引言
通過
上一節的學習,我們知道在mysql一主一從叢集中,是依靠資料庫的Binlog(二進制日志)來進行主從同步的,主節點執行完一個DDL、DML語句後,會将此語句記錄到主庫的binlog中,然後由IO線程将日志傳輸到從庫,由SQL線程來replay binlog,進而實作主從同步。但是,這種機制是100%可靠的麼?會不會有例外情況?大家可以思考一下下面幾種情況,是否會造成主備不一緻:
(1)一張表上存在多個索引,在主庫上執行delete from tab1 limit 1語句,從庫上是否會删除了同一條記錄?我們知道如果表上有多個索引,在不同的節點上執行時有可能使用到不同的索引,最終引起的結果是可能會删除不同的記錄。
(2)主庫上執行insert into t1 values(now())語句,從庫在1分鐘後才執行此條記錄,從庫上插入的時間與主庫是一緻的麼?
binlog深入了解
在回答上面兩個問題之前,我們首先深入了解一下資料庫的binlog,到底binlog裡記錄了哪些資訊呢。
delete的binlog解析
首先,我們建立了一張測試表,表結構如下圖:

圖1:測試表tab1的表結構
接着,向表内插入4條記錄:
圖2:測試表tab1内的4條記錄
執行語句delete from tab1 limit 1,然後使用mysqlbinlog工具來解析一下binlog:
圖3:delete的binlog解析結果
我們可以看到,雖然我們執行時沒有where條件,但是在binlog裡自動加上了where條件@1=1 @2=’abc’,這樣當這條記錄傳到從機上時,便可以保證删除了同一條記錄。
insert的binlog解析
另外,我們再建立一張表,然後執行insert into tab2(1,now()),然後再用mysqlbinlog來看下binlog裡的内容:
圖4:insert的binlog解析結果
原來binlog在記錄sql語句的同時,多記錄了一條SET TIMESTAMP=1586956197的語句,用SET TIMESTAMP指令約定了接下來的now()函數的傳回時間。是以,不論這個binlog是1分鐘之後被備庫執行,還是3天後用來恢複這個庫的備份,這個insert語句插入的行,值都是固定的。也就是說,通過這條SET TIMESTAMP指令,MySQL就確定了主備資料的一緻性。
binlog小結
通過上面的分析,我們了解了binlog裡不光記錄了sql執行語句,同時,也記錄了一些上下文資訊。是以,我們在使用binlog做資料恢複時,不能隻執行裡面的sql語句,要連同上下文的資訊一起執行。正确用binlog來恢複資料的标準做法是,用mysqlbinlog工具解析出來,然後把解析結果整個發給MySQL執行。
總結
此文隻是給大家簡單介紹了一下mysql binlog的原理,實際上binlog還有許多本文未講到的東西,若感興趣可以檢視相關的資料進行學習。
本文用兩節的内容給大家介紹了mysql的主從實作原理、mysql如何保證主從一緻。
相關内容
雲資料庫高可用——Series1:MySQL主從複制原理背景作者:張西來
阿裡雲智能GTS-SRE團隊技術服務經理
曾就職于某國産資料庫廠商,有10多年資料庫技術支援工作經驗,精通多款資料庫産品,為國内多個大中銀行核心資料庫提供技術支援。目前就職于阿裡雲智能GTS-SRE團隊,負責雲資料庫的高效運維和管理工作。
我們是阿裡雲智能全球技術服務-SRE團隊,我們緻力成為一個以技術為基礎、面向服務、保障業務系統高可用的工程師團隊;提供專業、體系化的SRE服務,幫助廣大客戶更好地使用雲、基于雲建構更加穩定可靠的業務系統,提升業務穩定性。我們期望能夠分享更多幫助企業客戶上雲、用好雲,讓客戶雲上業務運作更加穩定可靠的技術,您可用釘釘掃描下方二維碼,加入阿裡雲SRE技術學院釘釘圈子,和更多雲上人交流關于雲平台的那些事。