MySQL 5.7半同步複製after sync和after commit詳解

chenfeng發表於2017-06-19
如果你的生產庫開啟了半同步複製,那麼對資料的一致性會要求較高,但在MySQL5.5/5.6裡,會存在資料不一致的風險。有這麼一個場景,客戶端提交了一個事務,master把binlog傳送給slave,在傳送的期間,網路出現波動,此時Binlog Dump執行緒傳送就會卡住,要等待slave把binlog寫到本地的relay-log裡,然後給master一個反饋,等待的時間以rpl_semi_sync_master_timeout引數為準,預設為10秒。在這等待的10秒鐘裡,在其他會話裡,檢視剛才的事務是可以看見的,此時一旦master發生當機,由於binlog沒有傳送給slave,前端app切到slave檢視,就會發現剛才已提交的事務不見了。


為了解決這種問題,MySQL5.7 改善了半同步複製這個缺陷。透過rpl_semi_sync_master_wait_point這個引數加以控制,預設是AFTER_SYNC,官方推薦用這個,它的工作原理是:master把binlog傳送給slave,只有在slave把binlog寫到本地的relay-log裡,才提交到儲存引擎層,然後把請求返回給客戶端,客戶端才可以看見剛才提交的事務。如果slave未儲存到本地的relay-log裡,客戶端是看不見剛才的事務的,這樣就不會造成上述那個場景發生。另一個值是AFTER_COMMIT,這個值是採用老式的MySQL5.5/5.6半同步複製工作。


AFTER_SYNC (the default): The master writes each transaction to its binary log and the slave, and syncs the binary log to disk. The master waits for slave acknowledgment of transaction receipt after the sync. Upon receiving acknowledgment, the master commits the transaction to the storage engine and returns a result to the client, which then can proceed.
主庫把每一個事務寫到二進位制日誌並儲存磁碟上,且傳送給從庫。主庫在等待從庫寫到自己的relay-log裡確認資訊。在接到確認資訊後,主資料庫把事務寫到儲存引擎裡並把相應結果反饋給客戶端,客戶端將在那時進行處理。


AFTER_COMMIT: The master writes each transaction to its binary log and the slave, syncs the binary log, and commits the transaction to the storage engine. The master waits for slave acknowledgment of transaction receipt after the commit. Upon receiving acknowledgment, the master returns a result to the client, which then can proceed. 
主庫把每一個事務寫到二進位制日誌並儲存磁碟上,且傳送給從庫,並把事務寫到儲存引擎裡。主庫在等待從庫寫到自己的relay-log裡確認資訊。在接到確認資訊後,主庫把相應結果反饋給客戶端,客戶端將在那時進行處理。


The replication characteristics of these settings differ as follows:
這兩個引數不同之處在於:


With AFTER_SYNC, all clients see the committed transaction at the same time: After it has been acknowledged by the slave and committed to the storage engine on the master.。Thus, all clients see the same data on the master.
在設定為AFTER_SYNC引數,所有的客戶端可以同時看到提交的資料:在得到從庫寫到自己的relay-log裡的確認資訊後,並把事務寫到儲存引擎裡。這樣,所有的客戶端都可以在主庫上看到同樣的資料。


In the event of master failure, all transactions committed on the master have been replicated to the slave (saved to its relay log). A crash of the master and failover to the slave is lossless because the slave is up to date.
主庫報錯,所有已經寫到從庫的事務都已經儲存到了relay log裡。主庫的崩潰,HA切換到從庫,不會帶來任何損失,因為從庫的relay-log的資料是最新的。


With AFTER_COMMIT, the client issuing the transaction gets a return status only after the server commits to the storage engine and receives slave acknowledgment. After the commit and before slave acknowledgment, other clients can see the committed transaction before the committing client.
在設定為AFTER_COMMIT 引數,發起事務的客戶端僅在伺服器向儲存引擎寫入資料並接受從庫得到確認之後才返回狀態。在寫入資料後和得到從庫確認之前,其他的客戶端可以看到在這一事務。


If something goes wrong such that the slave does not process the transaction, then in the event of a master crash and failover to the slave, it is possible that such clients will see a loss of data relative to what they saw on the master. 
如果出現了某種錯誤,比如說從庫的sql_thread執行緒沒有執行,那麼主庫崩潰和故障轉移給從伺服器的前提下,有可能這個客戶端會丟失那些他們曾經在主庫上看到的資訊。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15498/viewspace-2140966/,如需轉載,請註明出處,否則將追究法律責任。

相關文章