事情起因:唯品會一個DBA找到我,說他們的slave掉電,再重啟服務器以后,同步復制就掛了,報1032和1062錯誤,首先排查了在從庫上沒有寫操作,之后詢問了他們的參
事情起因:唯品會一個DBA找到我,說他們的slave掉電,再重啟服務器以后,同步復制就掛了,報1032和1062錯誤,首先排查了在從庫上沒有寫操作,之后詢問了他們的參數。
這是他們的參數:
sync_master_info = 1 sync_relay_log_info = 1 relay_log_info_repository = FILE參數意思是:sql線程每次執行完了一個事務,就會記錄在master.info和relay.info文件里。即:
START TRANSACTION; -- Statement 1 -- ... -- Statement N COMMIT; -- Update replication info files由于在記錄relay.info的時候宕機,relay.info未更新,機器重啟恢復后會從之前的POS點再次執行,這樣就執行了兩條同樣的SQL,就會報1032和1062錯誤,同步就掛了。
于是我建議他們設置:
relay_log_info_repository = TABLE relay_log_recovery = 1 alter table mysql.slave_relay_log_info engine=innodb;參數意思是:把relay.info改成記錄在slave_relay_log_info表里,并改成innodb引擎,并開啟relay_log_recovery中繼日志自我修復功能。即:
START TRANSACTION; -- Statement 1 -- ... -- Statement N -- Update replication info COMMIT;這樣sql線程執行完事務后,立即會更新slave_relay_log_info表,如果在更新過程中宕機,事務會回滾,slave_relay_log_info表并不會記錄同步的點,下次重新同步復制時,從之前的POS點再次執行。
看似很完美了,但之后我在虛擬機上做了測試,發現了一個BUG:
即針對DDL語句,不會觸發刷盤操作,而DML語句不會有該問題,也就是說slave_relay_log_info表不會更新,必須手工執行stop slave;start slave;該表才會強制刷新。
試想一下,,你修改了表結構以后,突然宕機,slave_relay_log_info表沒刷進磁盤,下次重啟服務后,會再次執行一次修改表結構,此時同步就掛了,你只能手工去跳過這個錯誤。
我測試的版本是:5.6.22-71.0-log Percona Server (GPL), Release 71.0, Revision 726
參考:
本文出自 “賀春旸的技術專欄” 博客,請務必保留此出處
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com