若是你的生產線開啓了半同步複製,那麼對數據的一致性會要求較高,但在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查看,就會發現剛纔已提交的事務不見了。前端
例如,在雙十一期間,搶購產品,出現了上面這種狀況,用戶下了一個訂單,因爲網絡波動,發送binlog給slave卡住了(10秒),那個用戶又刷新了一下瀏覽器,看見了剛纔下的訂單,此時master宕機,經過高可用failover到了slave上(slave未接收到那個binlog),他發現我剛纔下的訂單沒了,他確定大罵,老子錢花了,訂單不見了,直接投訴。sql
爲了解決這種問題,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半同步複製工做。數據庫
另外:在MySQL5.7 半同步複製能夠經過rpl_semi_sync_master_wait_slave_count參數指定有幾臺slave接收到了binlog才成功返回客戶端請求,默認是一臺,但不能指定是具體哪臺。
瀏覽器
參考:服務器
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線程沒有執行,那麼主庫崩潰和故障轉移給從服務器的前提下,有可能這個客戶端會丟失那些他們曾經在主庫上看到的信息。
網絡