閱讀140 返回首頁    go 微軟 go windows


一條更新操作引起的MySQL主從複製異常

作者介紹

康壯大連樓蘭科技股份數據庫運維組負責人,主要負責集團內部MySQL、MongoDB、Redis數據庫運維管理工作。曾在第三方數據庫運維公司任職技術部經理,負責政府行業的Oracle數據庫運維工作,具有Oracle OCP、OCM、MySQL OCP等相關認證、對數據庫架構設計、故障處理、優化有深入的理解。

 

一、環境描述 

 

生產環境異地機房主從數據庫,數據量過百G,數據庫版本社區版本5.6.25。

 

二、問題描述 

 

同事根據開發提供的SQL在Master節點執行了一個大表的的全表更新操作,導致從節點Slave IO線程中斷。

 

三、問題分析 

 

1)相關參數

 

my.cnf中有兩個參數設置:

expire_logs_days = 7        #binlog保留時間7天

max_binlog_size = 1G      #binlog大小

 

2)表大小,執行SQL

 

Table: v_clda   5.8G

Sql: update v_clda set uploadtime =now(); 主庫執行成功

 

3)主庫,大事物產生的binlog

 


\

 

4)異地從庫報錯

 


\


Slave 已經無法同步數據。

 

一個事物隻能寫入一個binlog日誌中,默認情況下,binlog日誌達到設定值後(max_binlog_size),會自動生成一個新的日誌文件,也會根據過期參數(expire_logs_days)設置自動刪除binlog日誌。如果生成了一個超大的binlog日誌,很可能是由於大事物引起的。

 

四、問題處理 

 

嚐試從啟slave線程,多次嚐試後失敗。

 

嚐試跳過事物,具體方法如下:

 

從節點執行(基於GTID)

 


\

 

從節點執行更新操作,同步數據

 


\

 

五、解決方案 

 

在執行大事物前關閉 set session sql_log_bin=0; (默認是開啟的),尤其是異地機房,網絡帶寬有限,而且VPN通道不是十分穩定的情況下。不允許它生成大量binlog日誌。

 

如果像本例中,已經執行了,而且生成了大量的binlog,最終導致複製異常,可以考慮使用跳過事物的方法來解決這個問題。

 

最笨的方法就是重新搭建主從,由於數據量比較大,還是異地不可取。

 

根本解決方法還是要拆分大事物,進行批量提交操作。賀春暘老師的MySQL管理之道一書中第四章4.4節有具體的解決方法。

 

參考改為用存儲過程,每刪除10000條事務就提交一次,循環操作直至刪除完畢。經過優化,行鎖的範圍變小了,性能也就變好了。相關代碼如下:

 


\

 

存儲過程上線後,觀察一段時間,同步複製時,Slave複製正常,問題解決。

原文發布時間為:2017-04-10

本文來自雲棲社區合作夥伴DBAplus

最後更新:2017-05-16 12:01:34

  上一篇:go  一個優秀的響應式網站能夠給你帶來什麼?
  下一篇:go  網易雲基於Kubernetes+Docker的容器服務研發實踐