mysql 组复制 不一致_使用MySQL组复制的限制和局限性
本節(jié)列出和解釋了組復(fù)制相關(guān)的要求和限制。
1.組復(fù)制的要求
要使用組復(fù)制,每個MySQL節(jié)點必須滿足以下條件:
1.1 基本要求
InnoDB存儲引擎:數(shù)據(jù)必須存儲在事務(wù)型的InnoDB存儲引擎中。事務(wù)以樂觀形式執(zhí)行,然后在提交前會檢測沖突問題。如果有沖突,為了維護組中一致性,有些事務(wù)必須回滾。這意味著需要事務(wù)型的存儲引擎。此外,InnoDB 存儲引擎提供了一些額外的功能,它們結(jié)合組復(fù)制時能更好地管理和處理沖突。
Primary Keys:每張需要被組復(fù)制的表都必須顯式定義一個主鍵。主鍵在判斷事務(wù)是否沖突扮演極其重要的角色:通過主鍵來準(zhǔn)確識別每個事務(wù)中修改了表中的哪些行。(實際上是將主機hash成寫集,然后由certifier來并發(fā)事務(wù)之間的檢測沖突性)
使用IPv4 地址:MySQL組復(fù)制使用的組通信引擎組件只支持 IPv4。因此,必須使用IPv4的網(wǎng)絡(luò)。
良好的網(wǎng)絡(luò)性能:組復(fù)制設(shè)計的初衷是部署在集群環(huán)境中,集群中的節(jié)點相互之間都非常近,因此除了網(wǎng)絡(luò)延遲,網(wǎng)絡(luò)帶寬也會影響組復(fù)制。
1.2 配置上的要求
組中的每個成員都必須配置以下選項:
必須開啟二進制日志:設(shè)置--log-bin[=log_file_name]。MySQL組復(fù)制會復(fù)制二進制日志的內(nèi)容,因此必須開啟二進制日志。
Slave Updates Logged:設(shè)置--log-slave-updates。節(jié)點需要記錄applier已應(yīng)用的日志。組中的每個節(jié)點都需要記錄它們所接收到并應(yīng)用的所有事務(wù),這是必須的,因為恢復(fù)過程是依賴于組中參與者的二進制日志來進行的。因此,組中每個成員都必須保留每個事務(wù)的副本,即使某事務(wù)不是在該節(jié)點上開始的。
Row Format的二進制日志:設(shè)置--binlog-format=row。組復(fù)制依賴于基于行格式的二進制日志,以便在組中傳播所發(fā)生的更改能保持一致性。而且,在探測組中不同節(jié)點間發(fā)生的并發(fā)事務(wù)是否沖突時,需要從行格式的日志中提取一些內(nèi)容來做比較。
開啟GTID復(fù)制:設(shè)置--gtid-mode=ON。組復(fù)制使用GTID(全局事務(wù)ID)來精確跟蹤每個節(jié)點上已經(jīng)提交了哪些事務(wù)。也因此可以推斷出某節(jié)點上要執(zhí)行的事務(wù)是否和已執(zhí)行的事務(wù)(每個節(jié)點上都有副本)沖突。換句話說,GTID是整個組復(fù)制判斷事務(wù)是否沖突的基礎(chǔ)。
Replication Information Repositories:設(shè)置--master-info-repository=TABLE和--relay-log-info-repository=TABLE。applier需要將 master 和 relay log 的元數(shù)據(jù)信息寫入到系統(tǒng)表 mysql.slave_master_info 和 mysql.slave_relay_log_info 中。這保證了組復(fù)制插件具有一致性恢復(fù)的能力和復(fù)制的元數(shù)據(jù)事務(wù)管理能力。
Transaction Write Set Extraction:設(shè)置--transaction-write-setextraction=XXHASH64,以便將行寫入到二進制日志中時,節(jié)點也收集寫集。寫集基于每行的主鍵,是唯一標(biāo)識被更改行的標(biāo)簽的簡化形式,該標(biāo)簽后續(xù)會用于探測事務(wù)沖突性。
Multithreaded Appliers:(某些舊版本沒有該要求)可以將組復(fù)制成員配置為多線程appliers,使得可以并行應(yīng)用事務(wù)。需要設(shè)置--slave-parallel-workers=N(N是applier線程數(shù)量)、--slavepreserve-commit-order=1以及--slave-parallel-type=LOGICAL_CLOCK。--slaveparallel-workers=N表示啟用多applier線程,組復(fù)制依賴于建立在所有參與節(jié)點都以相同順序接收和應(yīng)用、提交事務(wù)的一致性機制,因此還必須設(shè)置--slave-preserve-commit-order=1以保證并行事務(wù)的最終提交是和原事務(wù)所在順序位置一致的。最后,為了決定哪些事務(wù)可以并行執(zhí)行,relay log 必須包含由--slave-parallel-ype=LOGICAL_CLOCK生成的事務(wù)父信息(transaction parent information)。當(dāng)嘗試加入一個只設(shè)置了--slave-parallel-workers大于0,卻沒有設(shè)置其他兩項的新成員,將會報錯并阻止它的加入。
2.組復(fù)制的限制(局限性)
下面是使用組復(fù)制已知的限制:
Replication Event Checksums:由于對復(fù)制事件校驗的設(shè)計缺陷,目前組復(fù)制不能使用它們。因此,需要設(shè)置--binlog-checksum=NONE。
Gap Locks:在驗證階段中(certification process),不會考慮 Gap Locks,因此在 InnoDB 的外部無法獲取任何關(guān)于Gap 鎖的信息。
注意:
除非你的應(yīng)用程序或業(yè)務(wù)需求依賴于REPEATABLE READ(MySQL默認該隔離級別),否則建議在組復(fù)制中使用READ COMMITTED隔離級別。在READ COMMITTED隔離級別中,InnoDB基本上不會使用Gap Locks,這將使得InnoDB自帶的沖突探測能和組復(fù)制的沖突探測相互對齊從而保持一致。
Table Locks and Named Locks:驗證階段(certification process)中不考慮表鎖和命名鎖(見get_lock())。
不支持 SERIALIZABLE 隔離級別:在多主模型下,默認不支持該隔離級別。如果在多主模型下設(shè)置了該隔離級別,將拒絕提交事務(wù)。
不支持并發(fā)的 DDL 和 DML 操作:不支持在多主模型下不同節(jié)點上同時執(zhí)行DDL和DML修改同一對象。在某節(jié)點上對某對象執(zhí)行DDL語句時,如果在其他節(jié)點同時執(zhí)行DML修改該對象,將有一定風(fēng)險探測到?jīng)_突。(譯注:是 DDL+DML 的并發(fā),DDL+DDL 的并發(fā)也不允許。這是因為MySQL中沒有DDL事務(wù),不能保證DDL的原子性,當(dāng)DDL和DML同時操作某一個對象,可能DDL修改后,DML將因為對象結(jié)構(gòu)的改變而無法執(zhí)行,繼而回滾)
不支持級聯(lián)的外鍵約束:多主模型的組(所有節(jié)點都配置了group_replication_single_primary_mode=OFF)不支持多級外鍵依賴,特別是表上定義了級聯(lián)的外鍵約束(CASCADING foreign key constraints)。這是因為多主模型下執(zhí)行外鍵約束的級聯(lián)操作可能會出現(xiàn)未檢測到的沖突,從而導(dǎo)致組內(nèi)成員間數(shù)據(jù)不一致。因此,我們推薦在使用多主模型時,在每個節(jié)點上都設(shè)置group_replication_enforce_update_everywhere_checks=ON以避免出現(xiàn)未檢測到的沖突。在單主模型下沒有這種問題,因為沒有并發(fā)寫操作,從而不可能會出現(xiàn)未被探測到的沖突。
大事務(wù)可能會錯誤:如果一個事務(wù)非常大,導(dǎo)致GTID的內(nèi)容非常多,以至于無法在 5 秒內(nèi)通過網(wǎng)絡(luò)傳輸完成,這時組成員間的通信將失敗。要避免該問題,可以盡可能地限制事務(wù)的大小。例如,將LOAD DATA INFILE的文件切割為多個小塊。
多主模型可能出現(xiàn)死鎖:在多主模型下,SELECT ... FOR UPDATE語句可能會導(dǎo)致死鎖。這是因為組內(nèi)成員之間不會共享鎖資源(譯注:share nothing),因此這樣的語句可能達不到預(yù)期的結(jié)果。
總結(jié)
以上是生活随笔為你收集整理的mysql 组复制 不一致_使用MySQL组复制的限制和局限性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python地理可视化_【Python教
- 下一篇: linux cmake编译源码,linu