MySQL relay_log_purge=0 時的風險

http://ourmysql.com/archives/1453


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

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

   究竟是什麼樣的風險呢?查找了一番後,基本上明白了原因。

   首先,爲了讓從庫是 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 則會被保留。雖然這並不會影響從庫複製本身,但還是會有地雷:

  1. 由於崩潰或停止 MySQL 時,SQL 線程可能沒有執行完全部的 relay log,最後一個 relay log 中的一部分數據會被重新下載到新的文件中。也就是說,這部分數據重複了兩次。

  2. 如果 SQL 跟得很緊,則可能在 IO 線程寫入 relay log ,但還沒有將同步到磁盤時,就已經讀取執行了。這時,就會造成新的文件和舊的文件中少了一段數據。

   如果我們讀取 relay log 來獲取數據,必須注意這一點,否則就會造成數據不一致。而保留 relay log 的目的也在於此。因此,在處理 relay log 時必須格外小心,通過其中 binlog 頭信息來確保正確性。

   關於如何配置 crash safe 的複製本身的配置,可以參照:
http://blog.itpub.net/22664653/viewspace-1752588/
http://www.innomysql.net/article/34.html

   參考資料:
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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章