先來看下MYSQL異步復制的概念: 
  異步復制:MySQL本身支持單向的、異步的復制。異步復制意味著在把數據從一臺機器拷貝到另一臺機器時有一個延時 – 最重要的是這意味著當應用系統的事務提交已經確認時數據并不能在同一時刻拷貝/應用到從機。通常這個延時是由網絡帶寬、資源可用性和系統負載決定的。然而,使用正確的組件并且調優,復制能做到接近瞬時完成。 
  
   當主庫有更新的時候,主庫會把更新操作的SQL寫入二進制日志(Bin log),并維護一個二進制日志文件的索引,以便于日志文件輪回(Rotate)。在從庫啟動異步復制的時候,從庫會開啟兩個I/O線程,其中一個線程連接主庫,要求主庫把二進制日志的變化部分傳給從庫,并把傳回的日志寫入本地磁盤。另一個線程則負責讀取本地寫入的二進制日志,并在本地執行,以反映出這種變化。較老的版本在復制的時候只啟用一個I/O線程,實現這兩部分的功能。 




同步復制:同步復制可以定義為數據在同一時刻被提交到一臺或多臺機器,通常這是通過眾所周知的“兩階段提交”做到的。雖然這確實給你在多系統中保持一致性,但也由于增加了額外的消息交換而造成性能下降。 



使用MyISAM或者InnoDB存儲引擎的MySQL本身并不支持同步復制,然而有些技術,例如分布式復制塊設備(簡稱DRBD),可以在下層的文件系統提供同步復制,允許第二個MySQL服務器在主服務器丟失的情況下接管(使用第二服務器的復本)。要了解更多信息, 

  MYSQL 5。5開始,支持半自動復制。之前版本的MySQL Replication都是異步(asynchronous)的,主庫在執行完一些事務后,是不會管備庫的進度的。如果備庫不幸落后,而更不幸的是主庫此時又出現Crash(例如宕機),這時備庫中的數據就是不完整的。簡而言之,在主庫發生故障的時候,我們無法使用備庫來繼續提供數據一致的服務了。 

Semisynchronous Replication則一定程度上保證提交的事務已經傳給了至少一個備庫。 

   
Semi synchronous中,僅僅保證事務的已經傳遞到備庫上,但是并不確保已經在備庫上執行完成了。 

此外,還有一種情況會導致主備數據不一致。在某個session中,主庫上提交一個事務后,會等待事務傳遞給至少一個備庫,如果在這個等待過程中主庫Crash,那么也可能備庫和主庫不一致,這是很致命的。(在主庫恢復后,可以通過參數Rpl_semi_sync_master_no_tx觀察) 

     如果主備網絡故障或者備庫掛了,主庫在事務提交后等待10秒(rpl_semi_sync_master_timeout的默認值)后,就會繼續。這時,主庫就會變回原來的異步狀態。 

    MySQL在加載并開啟Semi-sync插件后,每一個事務需等待備庫接收日志后才返回給客戶端。如果做的是小事務,兩臺主機的延遲又較小,則Semi-sync可以實現在性能很小損失的情況下的零數據丟失。 

   主機Crash時的處理 

備庫Crash時,主庫會在某次等待超時后,關閉Semi-sync的特性,降級為普通的異步復制,這種情況比較簡單。 

主庫Crash后,那么可能存在一些事務已經在主庫Commit,但是還沒有傳給任何備庫,我們姑且稱這類事務為"墻頭事務"。"墻頭事務"都是沒有返回給客戶端的,所以發起事務的客戶端并不知道這個事務是否已經完成。 

這時,如果客戶端不做切換,只是等Crash的主庫恢復后,繼續在主庫進行操作,客戶端會發現前面的"墻頭事務"都已經完成,可以繼續進行后續的業務處理;另一種情況,如果客戶端Failover到備庫上,客戶端會發現前面的“墻頭事務”都沒有成功,則需要重新做這些事務,然后繼續進行后續的業務處理。 

   可以做多個備庫,任何一個備庫接收完成日志后,主庫就可以返回給客戶端了。 

網絡傳輸在并發線程較多時,一次可能傳輸很多日志,事務的平均延遲會降低。 

"墻頭事務"在墻頭上的時候,是可以被讀取的,但是這些事務在上面Failover的場景下,是被認為沒有完成的。 

     默認情況下MySQL的復制是異步的,Master上所有的更新操作寫入Binlog之后并不確保所有的更新都被復制到Slave之上。異步操作雖然效率高,但是在Master/Slave出現問題的時候,存在很高數據不同步的風險,甚至可能丟失數據。 
MySQL5.5引入半同步復制功能的目的是為了保證在master出問題的時候,至少有一臺Slave的數據是完整的。在超時的情況下也可以臨時轉入異步復制,保障業務的正常使用,直到一臺salve追趕上之后,繼續切換到半同步模式。 
Master: 
INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so’; 
SET GLOBAL rpl_semi_sync_master_enabled=1; 
SET GLOBAL rpl_semi_sync_master_timeout=1000; (1s, default 10s) 
Slave: 
INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so’; 
SET GLOBAL rpl_semi_sync_slave_enabled=1; 
復制心跳(用戶檢測復制是否中斷) 

MySQL5.5提供的新的配置master_heartbeat_period,能夠在復制停止工作和出現網絡中斷的時候幫助我們迅速發現問題。 

啟用方法: 

STOP SLAVE; 

CHANGE MASTER TO master_heartbeat_period= milliseconds; 

START SLAVE; 

Slave自動恢復同步 

在MySQL5.5版本之前,MySQL Slave實例在異常終止服務之后,可能導致復制中斷,并且relay binlog可能損壞,在MySQL再次啟動之后并不能正常恢復復制。在MySQL5.5中這一問題得到了解決,MySQL可以自行丟棄順壞的而未處理的數據,重新從master上獲取源數據,進而回復復制。 

跳過指定復制事件 

在多Master或環形復制的情況下,處于復制鏈條中間的服務器異常,可以通過 

CHANGE MASTER TO MASTER_HOST=xxx IGNORE_SERVER_IDS=y 

跳過出問題的MySQL實例。 

自動轉換字段類型 

MySQL5.1在基于語句的復制下,支持部分的字段轉換,但是行級的會報錯。MySQL5.5語句和行級復制都已支持。還可以通過 SLAVE_TYPE_CONVERSIONS 控制轉換的方向。