Mysql的復制主要分為以下幾種:
1 異步復制:mysql默認的復制是異步復制,主庫在執行完客戶端提交的事務后立即將結果返回給客戶端,並不關心從庫是否已經接受並處理,
這樣,如果主庫crash掉了,此時主庫上已經提交的事務可能並沒有傳到從庫上,此時,如果強行將從庫提升為主,可能導致新主庫數據不完整。
后果:如果主服務器宕機時可能會導致數據丟失嚴重。
這里要說說一個參數:sync_binlog=1 它表示在事務提交之前,Mysql都需要先把binlog刷新到磁盤上,這樣的話,即使出現數據庫主機宕機,系統最多損失prepared狀態的事務,
如下是異步復制關系圖:
2 semi-sync replication(半同步復制)
異步復制中主庫和從庫的數據之間難免會存在一定的延遲,這樣會有出現一種情況:當在主庫上寫入一個事務並提交成功,而從庫尚未得到主庫的binlog日志(為什么沒有得到?),主庫由於各種原因宕機,導致主庫上該事務binlog丟失,此時從庫(這是會提升為主庫)就會損失這個事務,從而造成主從不一致(修復后的主庫會變成從庫),因此為了解決這個問題,從Mysql5.5開始,就開始引入半同步復制,半同步為了保證主庫上每一個binlog事務都能夠被可靠的復制到從庫上,主庫在每次事務成功提交后,並不及時反饋給前端應用用戶,而是等待至少一個從庫(rpl_semi_sync_master_wait_for_slave_count)也能接受到binlog事務成功寫入中繼日志,主庫才返回Commit操作給客戶端。
也就是說半同步復制保證事務成功提交后,至少有兩份日志記錄,一份在主庫的binlog日志上,另一份在至少一個從庫的中繼日志relay_log上,從而更進一步保證了數據的完整性。
在傳統的半同步復制中,主庫寫數據到binlog,且執行commit操作后,會一直等待從庫的ACK,即從庫寫入relay log 后,並將數據落盤,返回給主庫消息,通知主庫可以返回前端
應用操作成功。但是這樣會出現一個問題,就是實際上主庫已經將該事務Commit到了事務引擎層,應用已經可以看到數據發生了變化,只是等待返回而已,如果此時主庫宕機,
有可能從庫還沒能寫入relay log ,就會發生主從庫不一致的情況,
后果:1.至少有一個從庫收到binlog再返回 2.減少數據丟失風險 3.不能完全避免數據丟失 4.Mysql5.5版本開始支持 loss-less semi-sync replication(增強型半同步)
增強型半同步是對半同步做了微調,即主庫寫數據到binlog后,就開始等待從庫的應答,直到至少一個從庫寫入relay log 后,並將數據落盤,然后返回給主庫消息,
通過主庫可以執行commit操作,然后主庫開始提交到事務引擎層,應用此時可以看到數據發生了變化。
后果:1.二進制日志先寫遠程 2 可保證數據完全不丟失 3 mysql5.7版本開始支持
半同步復制模式下,假如傳送binlog日志到從庫時,從庫宕機或者網絡延時,導致binlog並沒有及時地傳送到從庫中,此時主庫上的事務會等待一段時間,時間長度由參數rpl_semi_sync_master_timeout設置的毫秒數決定,如果binlog在這段時間內都無法成功發送到從庫上,則mysql自動調整復制模式為異步模式,事務正常返回提交個客戶
半同步復制很大程度上取決於主從庫之間的網絡情況,往返時延RTT越小決定了從庫的實時性越好,通俗地說,主從庫之間的網絡越快,從庫越實時。
配置:
半同步復制搭建需要安裝插件:
加載插件 主: INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; 從: INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; 查看是否加載成功: show plugins; 啟動: 主: SET GLOBAL rpl_semi_sync_master_enabled = 1; 從: SET GLOBAL rpl_semi_sync_slave_enabled = 1; 重啟從庫上的IO線程 STOP SLAVE IO_THREAD; START SLAVE IO_THREAD; 查看是否在運行 主: show status like 'Rpl_semi_sync_master_status'; 從: show status like 'Rpl_semi_sync_slave_status';
組復制:之前上面說的不管是異步復制還是半同步復制,他們都不能完全解決數據丟失的問題,首先異步復制不用說,可能有數據丟失的問題,那么增強型半同步呢?其實增強型半同步只是保證了當主庫提交事務后,binlog日志可以傳到從庫並寫入relay log日志中,但是對於應用(重放)relay log的過程,從庫還是異步進行的,因此,從庫最后是否能應用這個事務還看apply過程是不是順利進行,所以就出現了組復制這種技術來進行的
Mysql組復制是基於傳統異步復制和半同步復制的缺陷——數據的一致性問題無法保證,MySQL官方在5.7.17版本正式推出組復制(MySQL Group Replication,簡稱MGR)
由若干個節點共同組成一個復制組,一個事務的提交,必須經過組內大多數節點(N / 2 + 1)決議並通過,才能得以提交。如上圖所示,由3個節點組成一個復制組,Consensus層為一致性協議層,在事務提交過程中,發生組間通訊,由2個節點決議(certify)通過這個事務,事務才能夠最終得以提交並響應。
引入組復制,主要是為了解決傳統異步復制和半同步復制可能產生數據不一致的問題。組復制依靠分布式一致性協議(Paxos協議的變體),實現了分布式下數據的最終一致性,提供了真正的數據高可用方案(是否真正高可用還有待商榷)。其提供的多寫方案,給我們實現多活方案帶來了希望。
一個復制組由若干個節點(數據庫實例)組成,組內各個節點維護各自的數據副本(Share Nothing),通過一致性協議實現原子消息和全局有序消息,來實現組內實例數據的一致。
MGR的解決方案目前的一些局限性
1.僅支持InnoDB表,並且每張表一定要有一個主鍵,用於做write set的沖突檢測;
2.必須打開GTID特性,二進制日志格式必須設置為ROW,用於選主與write set
3.COMMIT可能會導致失敗,類似於快照事務隔離級別的失敗場景
4.目前一個MGR集群最多支持9個節點
5.不支持外鍵於save point特性,無法做全局間的約束檢測與部分部分回滾
6.二進制日志不支持binlog event checksum
MGR方案對數據庫的一些要求
1 innodb引擎
在MySQL Group Replication中,事務以樂觀形式執行,但是在提交時檢查沖突,如果存在沖突,則會在某些實例上回滾事務,保持各個實例的數據一致性,那么,這就需要使用到 事務存儲引擎,同事Innodb提供一些額外的功能,可以更好的管理和處理沖突,所以建議業務使用表格使用inndb存儲引擎,類似於系統表格mysql.user使用MyISAM引擎的表格,因為極少修改及添加,極少出現沖突情況。
2 主鍵
每個需要復制的表格都必須定義一個顯式主鍵,注意跟隱式主鍵區分(使用Innodb引擎的表格,如果沒有指定主鍵,默認選擇第一個非空的唯一索引作為主鍵,如果沒有,則自動創建一個6個字節的rowid隱式主鍵)。這個主鍵能在沖突發生時啟動極其重要的作用,同時,能夠有效提高relay log的執行效率。
3 隔離級別
官網建議使用READ COMMITTED級別,除非應用程序依賴於REPLEATABLE READ,RC模式下沒有GAP LOCK,比較好支持Innodb本身的沖突檢測機制何組復制的內部分布式檢測機制一起協同工作。不支持SERIALIZABLE隔離級別。
4 外鍵
不建議使用級聯外鍵,如果舊庫本身有外鍵,業務上無法去除並且使用的是多主模式,那么,請配置 group_replication_enforce_update_everywhere_check ,強制檢查每個組成員的級聯檢查,避免多主模式下執行級聯操作造成的檢測不到的沖突
參考文章:https://blog.csdn.net/HD243608836/article/details/110120638