本節討論使用 NDB 叢集進行複製時的已知問題。
來源與複本之間的連線中斷。 連線中斷可能發生在來源叢集 SQL 節點與複本叢集 SQL 節點之間,或來源 SQL 節點與來源叢集的資料節點之間。在後者的情況下,不僅可能因為實體連線中斷(例如,網路線斷裂)而發生,也可能因為資料節點事件緩衝區溢位而發生;如果 SQL 節點回應速度過慢,可能會被叢集捨棄(這可以在一定程度上透過調整 MaxBufferedEpochs
和 TimeBetweenEpochs
設定參數來控制)。如果發生這種情況,完全有可能在來源叢集中插入新資料,而沒有記錄在來源 SQL 節點的二進位日誌中。因此,為了保證高可用性,維護備份複製通道、監控主要通道,並在必要時故障轉移到輔助複製通道,以保持複本叢集與來源同步非常重要。NDB 叢集並非設計為自行執行此類監控;這需要外部應用程式。
來源 SQL 節點在連接或重新連接到來源叢集時會發出「間隙」事件。(間隙事件是一種「事件」,表示發生影響資料庫內容的事件,但不容易以一組變更表示。事件的例子包括伺服器故障、資料庫重新同步、某些軟體更新以及某些硬體變更。)當複本在複製日誌中遇到間隙時,會停止並顯示錯誤訊息。此訊息可在 SHOW REPLICA STATUS
的輸出中找到,表示 SQL 執行緒已因複製串流中註冊的事件而停止,並且需要手動介入。有關在這種情況下該怎麼做的更多資訊,請參閱第 25.7.8 節,「使用 NDB 叢集複製實作故障轉移」。
由於 NDB 叢集並非設計為自行監控複製狀態或提供故障轉移,如果複本伺服器或叢集需要高可用性,則必須設定多個複製線路、監控主要複製線路上的來源 mysqld,並準備在必要時故障轉移到輔助線路。這必須手動完成,或可能藉由協力廠商應用程式完成。有關實作此類設定的資訊,請參閱第 25.7.7 節,「使用兩個複製通道進行 NDB 叢集複製」和第 25.7.8 節,「使用 NDB 叢集複製實作故障轉移」。
如果您從獨立的 MySQL 伺服器複製到 NDB 叢集,通常一個通道就足夠了。
循環複製。 NDB 叢集複製支援循環複製,如下一個範例所示。複製設定涉及三個編號為 1、2 和 3 的 NDB 叢集,其中叢集 1 作為叢集 2 的複製來源,叢集 2 作為叢集 3 的來源,而叢集 3 作為叢集 1 的來源,從而完成循環。每個 NDB 叢集都有兩個 SQL 節點,其中 SQL 節點 A 和 B 屬於叢集 1,SQL 節點 C 和 D 屬於叢集 2,SQL 節點 E 和 F 屬於叢集 3。
只要滿足以下條件,就支援使用這些叢集進行循環複製
所有來源和複本叢集上的 SQL 節點都相同。
所有充當來源和複本的 SQL 節點都啟用了系統變數
log_replica_updates
。
下圖顯示了這種循環複製設定
在此情境中,叢集 1 中的 SQL 節點 A 複製到叢集 2 中的 SQL 節點 C;SQL 節點 C 複製到叢集 3 中的 SQL 節點 E;SQL 節點 E 複製到 SQL 節點 A。換句話說,複製線路(圖中彎曲的箭頭表示)直接連接所有用作來源和複本的 SQL 節點。
也可以設定並非所有來源 SQL 節點都是複本的循環複製,如下所示
在此情況下,每個叢集中使用不同的 SQL 節點作為來源和複本。但是,您不得啟動任何已啟用 log_replica_updates
系統變數的 SQL 節點。這種用於 NDB 叢集的循環複製方案(其中複製線路(同樣由圖中彎曲的箭頭表示)是不連續的)應該是可行的,但應該注意的是,尚未經過徹底測試,因此仍應視為實驗性。
NDB
儲存引擎使用冪等執行模式,這會抑制重複鍵和其他否則會破壞 NDB 叢集循環複製的錯誤。這相當於將系統變數 replica_exec_mode
的全域值設定為 IDEMPOTENT
,儘管在 NDB 叢集複製中這不是必要的,因為 NDB 叢集會自動設定此變數並忽略任何明確設定的嘗試。
NDB 叢集複製和主鍵。 在節點故障的情況下,由於在這種情況下可能會插入重複的列,因此複製沒有主鍵的 NDB
表格仍然可能發生錯誤。因此,強烈建議所有正在複製的 NDB
表格都有明確的主鍵。
NDB 叢集複製和唯一索引鍵。 在舊版本的 NDB 叢集中,更新 NDB
表格的唯一索引鍵欄位值的操作,在複製時可能會導致重複鍵錯誤。當在 NDB
表格之間進行複製時,會藉由延後唯一索引鍵檢查,直到所有表格列更新都完成後,來解決此問題。
目前僅 NDB
支援以這種方式延後條件約束。因此,當從 NDB
複製到不同的儲存引擎(例如 InnoDB
或 MyISAM
)時,仍然不支援更新唯一索引鍵。
使用 NDB
表格(例如 t
)來說明在不延後檢查唯一索引鍵更新的情況下進行複製時遇到的問題,在來源上建立和填入資料(並傳送到不支援延後唯一索引鍵更新的複本),如下所示
CREATE TABLE t (
p INT PRIMARY KEY,
c INT,
UNIQUE KEY u (c)
) ENGINE NDB;
INSERT INTO t
VALUES (1,1), (2,2), (3,3), (4,4), (5,5);
來源上的以下 UPDATE
陳述式在 t
上成功執行,因為受影響的列會按照 ORDER BY
選項決定的順序處理,該選項在整個表格上執行
UPDATE t SET c = c - 1 ORDER BY p;
相同的陳述在複本上會因重複鍵錯誤或其他約束違規而失敗,因為列更新的排序是針對單一分割區進行,而不是針對整個表格。
每個 NDB
表格在建立時都會依據鍵隱含地進行分割。更多資訊請參閱第 26.2.5 節「KEY 分割」。
不支援 GTID。使用全域交易 ID 的複製與 NDB
儲存引擎不相容,且不支援。啟用 GTID 很可能會導致 NDB Cluster 複寫失敗。
使用 --initial 重新啟動。使用 --initial
選項重新啟動叢集會導致 GCI 和 epoch 數字的序列從 0
重新開始。(這通常適用於 NDB Cluster,而不僅限於涉及叢集的複寫情境。)在這種情況下,應重新啟動參與複寫的 MySQL 伺服器。之後,您應使用 RESET BINARY LOGS AND GTIDS
和 RESET REPLICA
陳述式,分別清除無效的 ndb_binlog_index
和 ndb_apply_status
表格。
從 NDB 複寫到其他儲存引擎。 可以將來源上的 NDB
表格複寫到複本上使用不同儲存引擎的表格,並考量此處列出的限制。
不支援多來源和循環複寫(來源和複本上的表格都必須使用
NDB
儲存引擎才能運作)。在複本上使用不執行二進位記錄的儲存引擎處理表格時,需要特殊處理。
在複本上對表格使用非交易式儲存引擎也需要特殊處理。
來源 mysqld 必須使用
--ndb-log-update-as-write=0
或--ndb-log-update-as-write=OFF
啟動。
接下來的幾個段落將提供有關剛才描述的每個問題的其他資訊。
將 NDB 複寫到其他儲存引擎時,不支援多個來源。對於從 NDB
複寫到不同儲存引擎,兩個資料庫之間的關係必須是一對一的。這表示 NDB Cluster 和其他儲存引擎之間不支援雙向或循環複寫。
此外,在 NDB
和不同的儲存引擎之間複寫時,無法設定多個複寫通道。(NDB Cluster 資料庫可以同時複寫到多個 NDB Cluster 資料庫。)如果來源使用 NDB
表格,仍然可以讓多個 MySQL 伺服器維護所有變更的二進位記錄,但若複本要變更來源(容錯移轉),則必須在複本上明確定義新的來源-複本關係。
將 NDB 表格複寫到不執行二進位記錄的儲存引擎。如果您嘗試從 NDB Cluster 複寫到使用不處理本身二進位記錄的儲存引擎的複本,複寫程序會中止並顯示錯誤 無法進行二進位記錄...由於涉及多個引擎,且至少有一個引擎是自我記錄,因此陳述式無法以原子方式寫入(錯誤 1595)。您可以使用下列其中一種方式解決此問題:
關閉複本上的二進位記錄。可以透過設定
sql_log_bin = 0
來達成。變更 mysql.ndb_apply_status 表格使用的儲存引擎。使此表格使用不處理本身二進位記錄的引擎也可以消除衝突。可以透過在複本上發出類似
ALTER TABLE mysql.ndb_apply_status ENGINE=MyISAM
的陳述式來完成。在複本上使用NDB
以外的儲存引擎時,這樣做是安全的,因為您不需要擔心保持多個複本同步。篩除複本上 mysql.ndb_apply_status 表格的變更。可以透過使用
--replicate-ignore-table=mysql.ndb_apply_status
啟動複本來完成。如果您需要複寫忽略其他表格,您可能會想要改用適當的--replicate-wild-ignore-table
選項。
從一個 NDB Cluster 複寫到另一個 NDB Cluster 時,您不應停用 mysql.ndb_apply_status
的複寫或二進位記錄,或變更此表格使用的儲存引擎。有關詳細資訊,請參閱「在 NDB Cluster 之間複寫的複寫和二進位記錄篩選規則」。
從 NDB 複寫到非交易式儲存引擎。從 NDB
複寫到非交易式儲存引擎(例如 MyISAM
)時,複寫 INSERT ... ON DUPLICATE KEY UPDATE
陳述式時可能會遇到不必要的重複鍵錯誤。您可以使用 --ndb-log-update-as-write=0
來抑制這些錯誤,這會強制將更新記錄為寫入,而不是更新。
NDB 複寫和檔案系統加密 (TDE)。加密檔案系統的使用對 NDB 複寫沒有任何影響。支援所有下列情境:
將具有加密檔案系統的 NDB Cluster 複寫到其檔案系統未加密的 NDB Cluster。
將其檔案系統未加密的 NDB Cluster 複寫到其檔案系統已加密的 NDB Cluster。
將其檔案系統已加密的 NDB Cluster 複寫到使用未加密的
InnoDB
表格的獨立 MySQL 伺服器。將具有未加密檔案系統的 NDB Cluster 複寫到使用具有檔案系統加密的
InnoDB
表格的獨立 MySQL 伺服器。
在 NDB Cluster 之間複寫的複寫和二進位記錄篩選規則。如果您使用任何選項 --replicate-do-*
、--replicate-ignore-*
、--binlog-do-db
或 --binlog-ignore-db
來篩選正在複寫的資料庫或表格,您必須注意不要封鎖 mysql.ndb_apply_status
的複寫或二進位記錄,這是 NDB Cluster 之間正常複寫所必需的。特別是,您必須記住以下幾點:
使用
--replicate-do-db=
(且沒有其他db_name
--replicate-do-*
或--replicate-ignore-*
選項)表示僅複寫資料庫db_name
中的表格。在這種情況下,您也應使用--replicate-do-db=mysql
、--binlog-do-db=mysql
或--replicate-do-table=mysql.ndb_apply_status
,以確保在複本上填入mysql.ndb_apply_status
。使用
--binlog-do-db=
(且沒有其他db_name
--binlog-do-db
選項)表示僅將資料庫db_name
中表格的變更寫入二進位記錄。在這種情況下,您也應使用--replicate-do-db=mysql
、--binlog-do-db=mysql
或--replicate-do-table=mysql.ndb_apply_status
,以確保在複本上填入mysql.ndb_apply_status
。使用
--replicate-ignore-db=mysql
表示不會複寫mysql
資料庫中的任何表格。在這種情況下,您也應使用--replicate-do-table=mysql.ndb_apply_status
,以確保複寫mysql.ndb_apply_status
。使用
--binlog-ignore-db=mysql
表示不會將mysql
資料庫中表格的任何變更寫入二進位記錄。在這種情況下,您也應使用--replicate-do-table=mysql.ndb_apply_status
,以確保複寫mysql.ndb_apply_status
。
您也應該記住,每個複寫規則都需要以下項目:
其自身的
--replicate-do-*
或--replicate-ignore-*
選項,且無法在單一複寫篩選選項中表達多個規則。有關這些規則的資訊,請參閱第 19.1.6 節「複寫和二進位記錄選項和變數」。其本身的
--binlog-do-db
或--binlog-ignore-db
選項,而且單一二進制日誌篩選選項無法表達多個規則。關於這些規則的資訊,請參閱第 7.4.4 節,「二進制日誌」。
如果您正在將 NDB Cluster 複寫到使用 NDB
以外儲存引擎的複本,則先前給定的考量可能不適用,如本節其他地方所述。
NDB Cluster 複寫與 IPv6。 所有類型的 NDB Cluster 節點在 NDB 8.4 中都支援 IPv6;這包括管理節點、資料節點和 API 或 SQL 節點。
在 NDB 8.4 中,如果您不打算將 IPv6 位址用於任何 NDB Cluster 節點,則可以在 Linux 核心中停用 IPv6 支援。
屬性升級和降級。 NDB Cluster 複寫包含對屬性升級和降級的支援。後者的實作區分有損和無損類型轉換,並且它們在複本上的使用可以透過設定系統變數 replica_type_conversions
的全域值來控制。
有關 NDB Cluster 中屬性升級和降級的更多資訊,請參閱基於列的複寫:屬性升級和降級。
NDB
與 InnoDB
或 MyISAM
不同,不會將虛擬欄位的變更寫入二進制日誌;但是,這對 NDB Cluster 複寫或 NDB
與其他儲存引擎之間的複寫沒有不利影響。已儲存產生欄位的變更會被記錄。