使用 BinLog 進行數據庫複製
我正在使用mysql-binlog-connector監聽任何 binlog 事件,然後在從數據庫上執行複制。我的問題是,二進制日誌在執行之後和送出之前立即註冊事件,所以如果有任何回滾,事件仍然會從二進制日誌條目中提取並複製到從屬設備上。有沒有辦法解決這個問題?
從binlog 手冊中,我得到的印像是該機制的工作方式略有不同:
在未送出的事務中,所有更改事務表(如 InnoDB 表)的更新(UPDATE、DELETE 或 INSERT)都會被記憶體,直到伺服器接收到 COMMIT 語句。此時,mysqld 在執行 COMMIT 之前將整個事務寫入二進制日誌。
換句話說,在實際發出 COMMIT 之前,該事務中的任何內容都不會寫入二進制日誌,或者,事務進入二進制日誌這一事實意味著沒有發出 ROLLBACK!
一旦發出 COMMIT:首先將完整的事務寫入二進制日誌,然後執行 COMMIT,最後,只有在 COMMIT 成功完成後,COMMIT 才會記錄在二進制日誌中。
然後,該手冊繼續介紹了一些邊緣情況及其緩解措施 (
sync_binlog=1
&--innodb_support_xa
),這可能會減輕您的擔憂:從 MySQL 5.7.7 開始,二進制日誌預設在每次寫入時同步到磁碟 (
sync_binlog=1
)。在 MySQL 5.7.7 之前,它不是 (sync_binlog=0
)。因此,在 MySQL 5.7.7 之前,如果作業系統或機器(不僅是 MySQL 伺服器)崩潰,則二進制日誌的最後一條語句有可能失去。為防止這種情況發生,請sync_binlog
在每 N 個送出組之後使用系統變數將二進制日誌同步到磁碟。請參見第 5.1.4 節,“伺服器系統變數”。sync_binlog 最安全的值是 1,但這也是最慢的。即使將 sync_binlog 設置為 1,在崩潰的情況下,表格內容和二進制日誌內容之間仍然存在不一致的可能性。例如,如果您使用 InnoDB 表,並且 MySQL 伺服器處理 COMMIT 語句,它會按順序將許多準備好的事務寫入二進制日誌,同步二進制日誌,然後將該事務送出到 InnoDB。如果伺服器在這兩個操作之間崩潰,事務會在重啟時被 InnoDB 回滾,但仍然存在於二進制日誌中。假設
--innodb_support_xa
設置為1