背景:
線上通過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、在業務低峰期,將從庫切換為新主庫