背景:
线上通过mysql_upgrade 将MySQL 5.5.34 升级为 5.6.31 版本,发现了一些问题:
问题1:增加普通索引的时候,依然堵塞DML语句,理论上MySQL 5.6 支持在线DDL,增加普通索引不会阻塞DML。
原因:5.6.4之前的格式的时间列(TIME,DATETIME和TIMESTAMP列,不支持小数秒精度),升级成5.6后,执行ALTER TABLE会隐式升级,而升级此类列需要重建表,所以阻塞了DML。
解决方式:
- 等ALTER TABLE执行完,也就第一次需要重建表了,以后就不用了;
- 开启 set global avoid_temporal_upgrade=on; 它会使ALTER TABLE不重建临时列。不重建也就不会阻塞DML了,但是官方不推荐使用这个参数,以后会删除;
问题2:从库报错: Error 'You cannot 'ALTER' a log table if logging is enabled' on query. Default database: 'mysql'. Query: 'ALTER TABLE slow_log
原因:mysql_upgrade执行的所有语句都被二进制记录,然后被复制到slave,导致得错误。
解决方式:
1、停止复制线程,关闭慢查询日志,当前错误可以恢复。
STOP SLAVE; SET GLOBAL slow_query_log = "OFF"; START SLAVE; SET GLOBAL slow_query_log = "ON";
2、mysql_upgrade 升级时增加 --skip-write-binlog 可用于在升级过程中禁用二进制日志记录。注意从MySQL 5.6.7开始,默认情况下,mysql_upgrade的二进制日志记录处于禁用状态,所以升级到5.6.7以后版本不需要加--skip-write-binlog了。我这里是先升级到5.5.62版本再升级到5.6.31所以有这个错误。
升级建议:
大版本升级还是使用逻辑备份升级,mysqldump这种导入导出比较好,避免意外问题。问题就是太慢了。可以使用mydumper,但是会有表锁,建议在从库上执行。
具体操作步骤:
1、创建新库,逻辑备份导入
2、添加为从库,等待数据一致
3、在业务低峰期,将从库切换为新主库