使用MySQL組複製的限制和侷限性

本節列出和解釋了組複製相關的要求和限制。html

1.組複製的要求

要使用組複製,每一個MySQL節點必須知足如下條件:mysql

1.1 基本要求

  1. InnoDB存儲引擎:數據必須存儲在事務型的InnoDB存儲引擎中。事務以樂觀形式執行,而後在提交前會檢測衝突問題。若是有衝突,爲了維護組中一致性,有些事務必須回滾。這意味着須要事務型的存儲引擎。此外,InnoDB 存儲引擎提供了一些額外的功能,它們結合組複製時能更好地管理和處理衝突。
  2. Primary Keys:每張須要被組複製的表都必須顯式定義一個主鍵。主鍵在判斷事務是否衝突扮演極其重要的角色:經過主鍵來準確識別每一個事務中修改了表中的哪些行。(其實是將主機hash成寫集,而後由certifier來併發事務之間的檢測衝突性)
  3. 使用IPv4 地址:MySQL組複製使用的組通訊引擎組件只支持 IPv4。所以,必須使用IPv4的網絡。
  4. 良好的網絡性能:組複製設計的初衷是部署在集羣環境中,集羣中的節點相互之間都很是近,所以除了網絡延遲,網絡帶寬也會影響組複製。

1.2 配置上的要求

組中的每一個成員都必須配置如下選項:sql

  1. 必須開啓二進制日誌:設置--log-bin[=log_file_name]。MySQL組複製會複製二進制日誌的內容,所以必須開啓二進制日誌。
  2. Slave Updates Logged:設置--log-slave-updates。節點須要記錄applier已應用的日誌。組中的每一個節點都須要記錄它們所接收到並應用的全部事務,這是必須的,由於恢復過程是依賴於組中參與者的二進制日誌來進行的。所以,組中每一個成員都必須保留每一個事務的副本,即便某事務不是在該節點上開始的。
  3. Row Format的二進制日誌:設置--binlog-format=row。組複製依賴於基於行格式的二進制日誌,以便在組中傳播所發生的更改能保持一致性。並且,在探測組中不一樣節點間發生的併發事務是否衝突時,須要從行格式的日誌中提取一些內容來作比較。
  4. 開啓GTID複製:設置--gtid-mode=ON。組複製使用GTID(全局事務ID)來精確跟蹤每一個節點上已經提交了哪些事務。也所以能夠推斷出某節點上要執行的事務是否和已執行的事務(每一個節點上都有副本)衝突。換句話說,GTID是整個組複製判斷事務是否衝突的基礎。
  5. Replication Information Repositories:設置--master-info-repository=TABLE--relay-log-info-repository=TABLE。applier須要將 master 和 relay log 的元數據信息寫入到系統表 mysql.slave_master_infomysql.slave_relay_log_info 中。這保證了組複製插件具備一致性恢復的能力和複製的元數據事務管理能力。
  6. Transaction Write Set Extraction:設置--transaction-write-setextraction=XXHASH64,以便將行寫入到二進制日誌中時,節點也收集寫集。寫集基於每行的主鍵,是惟一標識被更改行的標籤的簡化形式,該標籤後續會用於探測事務衝突性。
  7. Multithreaded Appliers:(某些舊版本沒有該要求)能夠將組複製成員配置爲多線程appliers,使得能夠並行應用事務。須要設置--slave-parallel-workers=N(N是applier線程數量)、--slavepreserve-commit-order=1以及--slave-parallel-type=LOGICAL_CLOCK--slaveparallel-workers=N表示啓用多applier線程,組複製依賴於創建在全部參與節點都以相同順序接收和應用、提交事務的一致性機制,所以還必須設置--slave-preserve-commit-order=1以保證並行事務的最終提交是和原事務所在順序位置一致的。最後,爲了決定哪些事務能夠並行執行,relay log 必須包含由--slave-parallel-ype=LOGICAL_CLOCK生成的事務父信息(transaction parent information)。當嘗試加入一個只設置了--slave-parallel-workers大於0,卻沒有設置其餘兩項的新成員,將會報錯並阻止它的加入。

2.組複製的限制(侷限性)

下面是使用組複製已知的限制:網絡

  1. Replication Event Checksums:因爲對複製事件校驗的設計缺陷,目前組複製不能使用它們。所以,須要設置--binlog-checksum=NONE
  2. Gap Locks:在驗證階段中(certification process),不會考慮 Gap Locks,所以在 InnoDB 的外部沒法獲取任何關於Gap 鎖的信息。多線程

    注意:併發

    除非你的應用程序或業務需求依賴於REPEATABLE READ(MySQL默認該隔離級別),不然建議在組複製中使用READ COMMITTED隔離級別。在READ COMMITTED隔離級別中,InnoDB基本上不會使用Gap Locks,這將使得InnoDB自帶的衝突探測能和組複製的衝突探測相互對齊從而保持一致。app

  3. Table Locks and Named Locks:驗證階段(certification process)中不考慮表鎖和命名鎖(見get_lock())。
  4. 不支持 SERIALIZABLE 隔離級別:在多主模型下,默認不支持該隔離級別。若是在多主模型下設置了該隔離級別,將拒絕提交事務。
  5. 不支持併發的 DDL 和 DML 操做:不支持在多主模型下不一樣節點上同時執行DDL和DML修改同一對象。在某節點上對某對象執行DDL語句時,若是在其餘節點同時執行DML修改該對象,將有必定風險探測到衝突。(譯註:是 DDL+DML 的併發,DDL+DDL 的併發也不容許。這是由於MySQL中沒有DDL事務,不能保證DDL的原子性,當DDL和DML同時操做某一個對象,可能DDL修改後,DML將由於對象結構的改變而沒法執行,繼而回滾)
  6. 不支持級聯的外鍵約束:多主模型的組(全部節點都配置了group_replication_single_primary_mode=OFF)不支持多級外鍵依賴,特別是表上定義了級聯的外鍵約束(CASCADING foreign key constraints)。這是由於多主模型下執行外鍵約束的級聯操做可能會出現未檢測到的衝突,從而致使組內成員間數據不一致。所以,咱們推薦在使用多主模型時,在每一個節點上都設置group_replication_enforce_update_everywhere_checks=ON以免出現未檢測到的衝突。在單主模型下沒有這種問題,由於沒有併發寫操做,從而不可能會出現未被探測到的衝突。
  7. 大事務可能會錯誤:若是一個事務很是大,致使GTID的內容很是多,以致於沒法在 5 秒內經過網絡傳輸完成,這時組成員間的通訊將失敗。要避免該問題,能夠儘量地限制事務的大小。例如,將LOAD DATA INFILE的文件切割爲多個小塊。
  8. 多主模型可能出現死鎖:在多主模型下,SELECT ... FOR UPDATE語句可能會致使死鎖。這是由於組內成員之間不會共享鎖資源(譯註:share nothing),所以這樣的語句可能達不到預期的結果。性能

相關文章
相關標籤/搜索