MySQL 5.6 對復制功能提供了新特性:slave 支持 crash-safe,可以解決之前版本中系統異常斷電可能導致的 SQL thread 信息不准確的問題。
原文:Enabling crash-safe slaves with MySQL 5.6
可以對從庫進行配置 crash-safe 功能是 MySQL 5.6 關於復制的一個重大改進。然而,我們注意到對如何正確開啟這個特性存在着一些困惑,那么讓我們一起來理清它要怎么做。
簡而言之
1.停止從庫 MySQL 服務
2.在配置文件 my.cnf 中添加 relay_log_info_repository = TABLE
和 relay_log_recovery = ON
3.重啟 MySQL 服務
詳情
如果要在從庫啟用 crash-safe 功能,你需要完全理解為什么要做上面所說的配置。首先,讓我們看看當從庫崩潰時,同步會斷開的原因。
在一個從節點上,同步涉及到 2 個線程:把主節點的二進制日志( binary log )復制到本地中繼日志( relay log )的 IO 線程,和執行中繼日志中的語句的 SQL 線程。每個線程當前的位置都存儲在一個文件里:IO 線程存在 master.info
文件,SQL 線程存在 relay-log.info
文件。
目前為止,還不錯。第一個問題是,這些文件不是每次寫入都同步到磁盤:如果發生崩潰,寫入到文件中的位置很可能是不准確的。MySQL 5.5 對這個進行了修復:你可以設置 set sync_master_info = 1
和 sync_relay_log_info = 1
來確保寫入兩個日志文件,且在每個事物完成之后同步到磁盤。同步到磁盤是有消耗的,但如果服務器有回寫緩存(write-back cache)策略,這些設置還是會起到積極作用,可以接受。
但是,等等,盡管設置了 set sync_master_info = 1
和 sync_relay_log_info = 1
,還是可能會出現問題。這是因為復制信息是在事務提交后才寫到日志文件的。因此,如果在事務提交之后,復制信息更新之前,發生了崩潰,當服務重啟的時候,復制信息是錯的,並且一個事務會被執行兩次。這個影響取決於這些事務:復制可能還可以正常運行,或者斷開,或者導致數據不一致。
MySQL 5.6 通過讓我們把復制信息存儲在表中,而不是之前的日志文件,來解決這個問題(當 relay_log_info_repository = TABLE
時,會創建表 mysql.slave_relay_log_info,當 master_info_repository = TABLE
時,會創建表 mysql.slave_master_info)。想法很簡單:我們可以把復制信息的更新包含在事務當中,確保它和數據同步/一致。
偽代碼,寫入到日志文件:
START TRANSACTION;
-- Statement 1
-- ...
-- Statement N
COMMIT;
-- Update replication info files
寫入到表:
START TRANSACTION;
-- Statement 1
-- ...
-- Statement N
-- Update replication info
COMMIT;
然而,這並沒有看起來那么簡單。對於 SQL 線程而言,因為實例會在一個事務提交的同時更新表 slave_relay_log_info,所以它可以很好的工作。但對於 IO 線程而言,表的更新與事務的執行並沒有關系,那么實例是如何知道什么時候去更新這個表呢?
答案是:它由 sync_master_info
控制。默認值是 10000,表示 IO 線程的位置,只會每提交 10000 個事務更新一次。這明顯不利於從節點開啟 crash-safe 功能。一個辦法是,設置 sync_master_info = 1
,但正如前面所說,它可能會影響性能(這就是為什么默認值不是 1)。
還有一個更加優雅的解決方法,那就是設置 relay_log_recovery = ON
,但它要求重啟 MySQL 服務。這個設置確保當 MySQL 服務啟動時,會從表 slave_relay_log_info
恢復出最新的 IO 線程的位置。因此,你甚至不需要為了從節點要開啟 crash-safe 功能而去把 IO 線程信息存儲到表里面。換句話說,沒有必要再去設置 master_info_repository = TABLE
。
最后再說一下,一旦設置了 relay_log_info_repository = TABLE
,因為這個表會在每個事物提交之后更新,所以 sync_relay_log_info
的設置是什么就無關緊要了。因此,你可以安全地把它從配置文件中刪除。
希望這篇文章可以讓你從這個這么棒的特性中有所收獲。