假如你已經知道 binlog 是 mysql 歸檔日誌。那 mysql 是如何通過 binlog 來讓主備一致的呢?
首先,binlog 記錄了主庫執行的操作,比如某個時間點,備庫要求同步數據,那麼主庫就把上 一次同步之後,產生的 binlog 發給備庫,備庫按 binlog 的操作重新做一遍就和主庫一樣了。
不過這樣做還有個問題, binlog 到底記錄的是什麼操作呢? 是客戶端執行的 sql 語句,還是執行 SQL 所影響的具體行信息?
其實兩者兼有,原因如下:
假如只有 sql,是不行的,比如 'delete table_a where b > 0 and c < 100 limit 1' 因爲有 limit 1,因此具體刪除了哪一行,其實是有點隨機的,如果備庫刪除的和主庫不一致,那麼就無法保證主庫和備庫的數據一致了。解決方法就是將刪除了哪一行記錄在 binlog,備庫按行執行對應的刪除操作。
假如只有 sql 影響的具體行信息,也不行,比如 delete from table_a
,假如 table_a 有 10 萬行記錄,那 binlog 就要記錄 10 萬行記錄,這樣的話,數據量太大,導致性能下降。
因此 binlog 有三種格式:
- statement, 記錄的是 sql 語句。
- row,記錄的是受影響的行信息。
- mixed,上述兩者都有。
mixed 格式中,mysql 會自動判斷這條語句是否會生產主備不一致情況,如果是就記錄對應的行信息,如果不會產生不一致就記錄 sql 語句。
可以看出,這樣方式確實很妙,這樣的設計也許對我們設計系統有啓發。