作者:莫善
某互联网公司高级 DBA。
本文来源:原创投稿
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
DBA【MySQL DBA】,其他 DBA 不在本文讨论范围。
DDL【ALTER TABLE】,其他操作不在本文讨论范围。
OMM【Only Modifies Metadata】。
NOMM【Not Only Modifies Metadata】。
嘟!嘟!嘟! 你好,我今晚要上线新功能,有个改表帮我处理一下呗。 你好,我有个亿级(十亿)表,需要加个字段/索引帮我处理一下呗。 你好,我刚加了一个字段,小表半小时还没加完,而且现在好像写不了数据。
DBA 们应该经常会接到这种需求吧。
DDL 操作可能是 DBA 最头疼的一项工作之一,也是最日常的一项工作了。动不动就要加个字段,扩个长度。如果不幸前期设计不合理的系统,那后期维护起来就真的是叫爹骂娘的问候。如果又不幸是接盘跑了八百年的业务表需要上线新功能加一两字段或者扩个长度啥的,简直酸爽到飞。
MySQL 5.6 开始支持 OnlineDDL,美美地敲了回车,等半天还是没反应,撸了一把又一把,业务催了一遍又一遍,猥琐发育都二胎了,就是没结束,在三胎之后终于跑完了,然后你就躺下刷了会手机,想找点安慰告别努力工作的一天,结果发现又是绿油油的一天,怒扔手机睡觉去了,不曾想刚酝酿了一会睡意,麻烦又来了。
业务疯狂地打电话,很不情愿地接通了。业务反馈很多订单返回的数据都有问题。机智的你猜到了肯定是改表导致了延迟,业务还是一顿吐槽,吧啦吧啦说一大堆,还得起来把读流量切到主库,有没有很酸爽。
为啥会这样呢,我们就来掰扯掰扯这个问题。
MySQL 的 DDL 操作主要有两种方式 copy 和 inplace。copy 表需要全程锁表,对业务影响极大,inplace 不阻塞 dml 操作。但是 MySQL 5.6 推出 OnlineDDL 以前,基本干啥 copy,干啥啥不行,干啥啥锁表。5.6 版本推出 OnlineDDL,DBA 们简直爱的不要不要了。但是 inplace?就真的很爱了吗。别忘了,inplace 分为 rebuild 和 no-rebuild,这就能解释了为啥很多操作还是很慢了。原因就是:【NOMM】。
既然 OnlineDDL 还是有那么多问题,那我们该咋整呢?这还只是一个 DDL 操作,如果很多呢,几十上百个 DDL 需求,是不是要疯,枸杞红枣肾宝片是不是得搞起来了。但是别慌,还有后招。生活是很美好的,比如骑上小电驴就可以送外卖了。
废话时间结束,现在言归正传,来聊聊改表工单系统-后台逻辑是怎么实现的。
为什么 DBA 那么排斥 DDL 操作?
1)对生产环境的敬畏心,能不做就不做,多做多错。只要是对线上环境操作,就是有风险的,一定要有这个意识,任何认为简单的操作都可能隐藏着不可预知的风险,线上环境无小事,一出事就是大事。所以能避免人为操作,就尽量避免人为操作。(是自动化不香吗,还是工作不饱和要体现工作量)
2)大表 DDL 操作成本高,白天容易影响业务,产生延迟等等。一般都是凌晨搞,熬夜太伤肾。还有就是,大多数 DDL 开销成本极大,简单来说就是【NOMM】开销成本都不小,那么就会带来一些问题,比如上面提到的延迟,还有就是 mdl 锁问题,还有磁盘 io 争抢,磁盘空间爆满等等,所以是有诸多风险的。是否是【OMM】请参照下表:
Operation | 5.6 | 5.7 | 8.0 |
---|---|---|---|
Dropping an index | YES | YES | YES |
Renaming an index | NULL | YES | YES |
Changing the index type | YES | YES | YES |
Renaming a column | YES | YES | YES |
Setting a column default value | YES | YES | YES |
Extending VARCHAR column size | NO | YES | YES |
Dropping the column default value | YES | YES | YES |
Modifying the definition of an ENUM or SET column | YES | YES | YES |
Adding a VIRTUAL column | NULL | YES | YES |
Dropping a VIRTUAL column | NULL | YES | YES |
Adding a foreign key constraint | YES | YES | YES |
Dropping a foreign key constraint | YES | YES | YES |
Setting persistent table statistics | YES | YES | YES |
Renaming a table | YES | YES | YES |
注:8.0 支持快速加列(instant 算法),但是有很多限制。常见的就是(1)不能使用 after、first 等位置属性,只能添加在表的最后一列。(2)不能是开启压缩的表。(3)不能是有全文索引的表。
3)重复性工作,大部分就是一个回车的事,然后就是盯监控,关注告警等一小时甚至更久,问题是每天还重复干很多。(dba 是干大事的,想想当时是不是按照内核开发要求招你来的)。
当然,在日常工作中,DBA 处理 DDL 操作,一般都是使用 gh-ost 或者 pt-osc 来进行操作,但是这两款工具就没问题了吗?下面我列几个问题:
综上,会发现,DDL 真的很烦人,实际工作中遇到的痛点估计比上述的更多。(在此也建议业务,前期一定要做好数据库设计,有条件的一定要让 dba 参与设计,没有条件的一定要创建条件)
先上一个流程图:
提示:原图链接 https://gitee.com/mo-shan/myonlineddl/blob/master/img/myonlineddl.png
主要做如下几点介绍:
当然要实现上述功能,最大的难度就是如何对业务的 DDL 操作进行解析。只有实现了 SQL 解析,才能消除上痛点实现功能。大家也可以想想怎么实现 SQL 解析这个功能。
下面列几个我在实现的时候遇到问题,供大家思考一下:
以上几点,大家可以想想怎么实现,可能用脑子一过觉得难度好像不大,但是真正落实到代码,应该还是有些难度的。毕竟 ALTER TABLE 语法千变万化,组合十分复杂,关于我是如何实现的,有兴趣的小伙伴可以看一下 git,欢迎吐槽改进。(安装部署及测试都有)
git:https://gitee.com/mo-shan/myonlineddl 需要了解测试流程,可以直接阅读【README.md】测试部分
日拱一卒,终有一日成车。就是干!
文章推荐: