不停机修改线上 MySQL 主键字段 以及其带来的问题和总结思考
起因:
线上 user 数据库没有自增字段,数据量已经达到百万级。无论是给离线仓库还是数据分析同步数据,没有主键自增 id 都是杀手级的困难。所以在使用 create_time 痛苦了几次之后准备彻底来解决这个问题。
解决问题的思路:
当时理了两个思路,一个是直接找个夜生人静的夜晚,drop 掉目前的 primary key 。然后再 add 一个 id 字段做 primary key auto increament 。我觉得这个方法对于 100w 以下的数据表是一个不错的方法,首先简单,其次找个夜生人静的晚上也不会有非常长时间的锁表。当然最好使用 online ddl 进行操作就更好了。我们碰到的稍微现实一点问题是,目前线上表还会跟离线表进行同步。然后也想挑战一下不停机不锁表的切换。所以规划了一个思路是
1. 首先建一个变更 ddl 后的表,在这里表现为已经设置好自增 id 的情况。
2. 将线上数据导入该表。并且保持两张表同步。
- 方案1: 如果数据比较多 例如已经是1000w 插入了,而且插表频率高,那么建议使用类似于 maxwell 数据同步工具,读取 binlog 时时同步让两张表时刻保持一致。最后找一个表没那么热的时候,rename 表即可。 rename 操作可以在一个命令里面执行几乎是秒切,如果跟上线上没有延迟那么基本上不会有数据丢失,如果切换的时候表比较热,可能会有几条不一致可以手动修复即可。
- 方案2: 如果数据没有那么多 比如只是百万级别,而且也有表明显不热的时候比如说晚上 3 4 点的时候。那么你可以通过导入数据,然后根据 update_time 字段时时跟上线上表。然后最后再切换之前再执行一次 根据 update_time 的更新脚本,然后立即完成 rename 操作。这样的操作 在数据量不大表不热的时候甚至不会有数据的不一致。大家可以根据需求来选择具体的方案。
3. 找个夜深人静的时候 rename 表完成两张表的切换。
其实从流程上来看还是比较简单的,但是实际处理的时候还是遇到不少问题。
1. 我在线上进行两张表同步的时候发现 slave 明显跟不上 master,而且延迟的时间越来越大。后来查阅了一些资料发现是当 master 发生大量写入的时候, slave 是很有可能发生慢慢跟不上 master 的情况。引起这个情况有可能是 socket 网络通信上的跟不上,可能是 slave 机器的配置不行,更有可能是没有开启并行复制导致吞吐量跟不上。因为主库上可能是开启多进程在写,从库却是单进程在跟复制,慢慢落后是理所当然的,但是只要这种情况不长时间持续,可以发现离线库在主库完成大并发写入之后会慢慢恢复正常。
2. 切换方案跟太多别的业务交杂在一起,例如还去考虑同时兼容我们的离线分析库,把问题搞得十分复杂。下次在思考类似需求的解决方案的时候,一定要遵循最小优化原则。理论上来说离线分析库完全可以等切换完成之后全量重刷,由于已经有主键自增 id 了。刷新会变得比以前简单方便非常多,速度也会快很多。所以没有必要纠结同时兼容的问题。导致复制方案变得复杂最后导致出错。
3. 新键的表 ddl 一定不要随意改动上面的字段,理论上无论之前表字段有多不合理多恶心,如果没有在切换计划里面有比较全面的考量都不应该擅自删除字段。保持只增不减跟之前完全兼容。
最后这次切换虽然出了一些小岔子,但是总的来说比较顺利。目前已经正常跑了一周,应该稳定了。
Reference:
http://mysql.taobao.org/monthly/2016/04/08/ 常见的 MySQL slave 延迟问题
https://www.cnblogs.com/kevingrace/p/6065088.html MySQL binlog 总结
https://dev.mysql.com/doc/refman/5.6/en/rename-table.html 参考 MySQL 5.6 rename 文档
不停机修改线上 MySQL 主键字段 以及其带来的问题和总结思考的更多相关文章
- 线上Mysql数据库崩溃事故的原因和处理
前文提要 承接前文<一次线上Mysql数据库崩溃事故的记录>,在文章中讲到了一次线上数据库崩溃的事件记录,建议两篇文章结合在一起看,不至于摸不着头脑. 由于时间原因,其中只讲了当时的一些经 ...
- Spring+SpringMVC+MyBatis+easyUI整合进阶篇(八)线上Mysql数据库崩溃事故的原因和处理
前文提要 承接前文<一次线上Mysql数据库崩溃事故的记录>,在文章中讲到了一次线上数据库崩溃的事件记录,建议两篇文章结合在一起看,不至于摸不着头脑. 由于时间原因,其中只讲了当时的一些经 ...
- 记一次排查线上MySQL死锁过程,不能只会curd,还要知道加锁原理
昨晚我正在床上睡得着着的,突然来了一条短信. 啥,线上MySQL死锁了,我赶紧登录线上系统,查看业务日志. 能清楚看到是这条insert语句发生了死锁. MySQL如果检测到两个事务发生了死锁,会回滚 ...
- MySQL主键设计
[TOC] 在项目过程中遇到一个看似极为基础的问题,但是在深入思考后还是引出了不少问题,觉得有必要把这一学习过程进行记录. MySQL主键设计原则 MySQL主键应当是对用户没有意义的. MySQL主 ...
- mysql主键问题
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_22314145/article/details/80824660 MySQL主键 一. MyS ...
- 不停机替换线上代码? 你没听错,Arthas它能做到
写在前边 有没有这样一种感受,自己写的代码在开发.测试环境跑的稳得一笔,可一到线上就抽风,不是缺这个就是少那个反正就是一顿报错,线上调试代码又很麻烦,让人头疼得很.阿里巴巴出了一款名叫Arthas的工 ...
- MySQL主键设计盘点
目录 主键定义 主键设计和应用原则 主键生成策略 自增ID UUID 自建的id生成器 Twitter的snowflake算法 @ 最近在项目中用了UUID的方式生成主键,一开始只是想把这种UUID的 ...
- 原创 记录一次线上Mysql慢查询问题排查过程
背景 前段时间收到运维反馈,线上Mysql数据库凌晨时候出现慢查询的报警,并把原始sql发了过来: --去除了业务含义的sql update test_user set a=1 where id=1; ...
- MYSQL主键自动增加的配置及auto_increment注意事项
文章一 原文地址: http://ej38.com/showinfo/mysql-202971.html 文章二: 点击转入第二篇文章 在数据库应用,我们经常要用到唯一编号.在MySQL中可通过字 ...
随机推荐
- UVA11212-Editing a Book(迭代加深搜索)
Problem UVA11212-Editing a Book Accept:572 Submit:4428 Time Limit: 10000 mSec Problem Description ...
- fastText文本分类算法
1.概述 FastText 文本分类算法是有Facebook AI Research 提出的一种简单的模型.实验表明一般情况下,FastText 算法能获得和深度模型相同的精度,但是计算时间却要远远小 ...
- Idea自带工具解决冲突
1:产生冲突 2:解决冲突 解决冲突具体操作: 手动合并代码: 此时点击的是local的>:点击changes的X则合并效果为: 也可以两侧都点击>.结果为: 也可以都点击X,结果为: 最 ...
- 【css】max-height,min-height,height一起使用时,优先级问题
MDN说法: max-height 这个属性会阻止 height 属性的设置值变得比 max-height 更大. max-height 属性用来设置给定元素的最大高度. 如果height 属性设置的 ...
- Linux systemctl命令笔记
指令格式 systemctl [command] [unit] 常用指令 1.启动 $ systemctl start 2.停止 $ systemctl stop 3.重启 $ systemctl r ...
- Linux 创建静态库(.a)和动态库(.so)
0. 回顾一下 gcc 选项 ============================================== -E : 仅做预处理,例如去注释,宏展开,include 展开等 -S : ...
- 2018-2019-2 20175310实验一《Java开发环境的熟悉》实验报告
2018-2019-2 20175310实验一<Java开发环境的熟悉>实验报告 一.实验步骤及内容 (一).Java开发环境的熟悉-1 1.建立20175310exp1的目录 2.在20 ...
- 深入理解mongodb查询条件语句
阅读目录 1. 理解:"$lt"."$lte"."$gt" 和 "$gte" 2. 理解 '$ne' 3. 理解 &qu ...
- selenium:解决页面元素display:none的方法
在UI自动化测试中,有时候会遇到页面元素无法定位的问题,包括xpath等方法都无法定位,是因为前端元素被设置为不可见导致. 这篇博客,介绍下如何通过JavaScript修改页面元素属性来定位的方法.. ...
- Vue2.x源码学习笔记-Vue静态方法和静态属性整理
Vue静态方法和静态属性,其实直接在浏览器中可以查看到的,如下 圈起来的是其静态属性,但是有的属性对象中的属性的值又是函数.未圈起来的则是函数. 其实它来自如下各个目录下的js文件 // src/co ...