MySQL relay_log_purge=0 時的風險

轉自: http://xiezhenye.com/2015/12/mysql-relay_log_purge0-%E6%97%B6%E7%9A%84%E9%A3%8E%E9%99%A9.htmlphp

 

有時候,咱們但願將 MySQL 的 relay log 多保留一段時間,好比用於高可用切換後的數據補齊,因而就會設置 relay_log_purge=0,禁止 SQL 線程在執行完一個 relay log 後自動將其刪除。可是在官方文檔關於這個設置有這麼一句話:html

Disabling purging of relay logs when using the --relay-log-recovery option risks data consistency and is therefore not crash-safe.

到底是什麼樣的風險呢?查找了一番後,基本上明白了緣由。mysql

首先,爲了讓從庫是 crash safe 的,必須設置 relay_log_recovery=1,這個選項的做用是,在 MySQL 崩潰或人工重啓後,因爲 IO 線程沒法保證記錄的從主庫讀取的 binlog 位置的正確性,所以,就無論 master_info 中記錄的位置,而是根據 relay_log_info 中記錄的已執行的 binlog 位置從主庫下載,並讓 SQL 線程也從這個位置開始執行。MySQL 啓動時,至關於執行了 flush logs ,會新開一個 relay log 文件,新的 relay log 會記錄在新的文件中。若是默認狀況 relay_log_purge=1 時,SQL 線程就會自動將以前的 relay log 所有刪除。而當 relay_log_purge=0 時,舊的 relay log 則會被保留。雖然這並不會影響從庫複製自己,但仍是會有地雷:sql

  1. 因爲崩潰或中止 MySQL 時,SQL 線程可能沒有執行徹底部的 relay log,最後一個 relay log 中的一部分數據會被從新下載到新的文件中。也就是說,這部分數據重複了兩次。
  2. 若是 SQL 跟得很緊,則可能在 IO 線程寫入 relay log ,但尚未將同步到磁盤時,就已經讀取執行了。這時,就會形成新的文件和舊的文件中少了一段數據。

若是咱們讀取 relay log 來獲取數據,必須注意這一點,不然就會形成數據不一致。而保留 relay log 的目的也在於此。所以,在處理 relay log 時必須格外當心,經過其中 binlog 頭信息來確保正確性。spa

關於如何配置 crash safe 的複製自己的配置,能夠參照:
http://blog.itpub.net/22664653/viewspace-1752588/
http://www.innomysql.net/article/34.html.net

參考資料:
http://blog.booking.com/better_crash_safe_replication_for_mysql.html
https://bugs.mysql.com/bug.php?id=73038
http://bugs.mysql.com/bug.php?id=74324線程

相關文章
相關標籤/搜索