先來看下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 控制轉換的方向。