背景
业务需求需要在数据库表新赠一个字段,执行DDL且在不停服的情况下。
实际操作
第一次提交SQL
alter table
tibtc23
add
`red_flag` varchar(2) DEFAULT '0' COMMENT '红冲状态(1-已红冲,0-未红冲)';
- 预测有效行数有700多万,DBA刚开始执行的时候,说还有用户使用会产生原数据锁,最后会引起锁表,于是推迟到11.多。
第二次提交
-
第二次执行的时候已经11.多,用户量很少(偏Tob),但是DBA执行中,反馈是我们有业务的SQL有问题,然后看了具体SQL后,才知道原来是有几个定时任务定时在数据库查询的语句(比较频繁的查询)。导致执行过程中执行失败
-
于是再次确定了mysql的version,想到了online DDL的几个语法。直接声明让他们在执行的过程中不进行锁表(此处的新增列必须不是自增的,不然语法会erro)。(官方地址:https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html)
alter table
tibtc23
add
`red_flag` varchar(2) DEFAULT '0' COMMENT '******', ALGORITHM=INPLACE, LOCK=NONE;
- 再次提交SQL之后 通过show processlist查看了sql进程以及描述,虽然有sleep但是是没有metadatalock的描述的。最后顺利执行完成。这也算是一次线上测试(毕竟是官方给的,还是很靠谱的)。但是DBA说是会在特殊情况下才有可能缓解缩表的情况。(后续再测试测试)
总结
在新增列的时候,数据量大的时候,使用ALGORITHM=INPLACE, LOCK=NONE语法。
大家可以再深入理解一下 onlineDDL
官方文档: https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html