本節討論使用 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);來源上 t 的以下 UPDATE 陳述式成功,因為受影響的資料列會按照 ORDER BY 選項所決定的順序處理,並對整個表格執行
UPDATE t SET c = c - 1 ORDER BY p;相同的陳述式會在複本上失敗並出現重複鍵錯誤或其他限制違規,因為資料列更新的排序是針對一個分割區一次執行,而不是針對整個表格執行。
建立時,每個 NDB 表格都會依鍵隱含分割。有關更多資訊,請參閱第 26.2.5 節「KEY 分割」。
不支援 GTID。使用全域交易 ID 的複製與 NDB 儲存引擎不相容,且不受支援。啟用 GTID 可能會導致 NDB 叢集複製失敗。
使用 --initial 選項重新啟動。 使用 --initial 選項重新啟動叢集會導致 GCI 和 epoch 數字序列從 0 重新開始。(這通常適用於 NDB 叢集,而不僅限於涉及叢集的複製情境。)在這種情況下,應重新啟動參與複製的 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 叢集和其他儲存引擎之間不支援雙向或循環複製。
此外,在 NDB 和不同儲存引擎之間複製時,無法設定多個複製通道。(NDB 叢集資料庫可以同時複製到多個 NDB 叢集資料庫。)如果來源使用 NDB 表格,仍然可以有多個 MySQL 伺服器維護所有變更的二進位記錄,但是若要讓複本變更來源(故障轉移),則必須在複本上明確定義新的來源-複本關係。
將 NDB 表格複製到不執行二進位記錄的儲存引擎。 如果您嘗試從 NDB 叢集複製到使用不自行處理二進位記錄的儲存引擎的複本,複製過程將中止並顯示錯誤訊息 無法進行二進位記錄...由於涉及多個引擎,且至少有一個引擎正在自我記錄,因此無法以原子方式寫入陳述式(錯誤 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 叢集複製到另一個 NDB 叢集時,您不應停用 mysql.ndb_apply_status 的複製或二進位記錄,或變更此表格使用的儲存引擎。如需詳細資訊,請參閱在 NDB 叢集之間複製時的複製和二進位記錄篩選規則。
從 NDB 複製到非交易式儲存引擎。 從 NDB 複製到非交易式儲存引擎(例如 MyISAM)時,複製 INSERT ... ON DUPLICATE KEY UPDATE 陳述式時,可能會遇到不必要的重複鍵錯誤。您可以使用 --ndb-log-update-as-write=0 來抑制這些錯誤,這會強制將更新記錄為寫入,而不是更新。
NDB 複製和檔案系統加密 (TDE)。 使用加密的檔案系統對 NDB 複製沒有任何影響。支援所有下列情境
將具有加密檔案系統的 NDB 叢集複製到檔案系統未加密的 NDB 叢集。
將檔案系統未加密的 NDB 叢集複製到檔案系統已加密的 NDB 叢集。
將檔案系統已加密的 NDB 叢集複製到使用未加密
InnoDB表格的獨立 MySQL 伺服器。將具有未加密檔案系統的 NDB 叢集複製到使用具有檔案系統加密的
InnoDB表格的獨立 MySQL 伺服器。
NDB 叢集之間複製的複製和二進位記錄篩選規則。 如果您使用任何選項 --replicate-do-*、--replicate-ignore-*、--binlog-do-db 或 --binlog-ignore-db 來篩選正在複製的資料庫或表格,您必須注意不要封鎖 mysql.ndb_apply_status 的複製或二進位記錄,這是 NDB 叢集之間正常運作所必需的。特別是,您必須記住以下事項
使用
--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 叢集複製到使用 NDB 以外的儲存引擎的複本,則先前給出的考量可能不適用,如本節其他地方所述。
NDB Cluster 複製與 IPv6。 在 NDB 9.0 中,所有類型的 NDB Cluster 節點都支援 IPv6;這包括管理節點、資料節點以及 API 或 SQL 節點。
在 NDB 9.0 中,如果您不打算為任何 NDB Cluster 節點使用 IPv6 定址,則可以在 Linux 核心中停用 IPv6 支援。
屬性升級與降級。 NDB Cluster 複製包含對屬性升級與降級的支援。後者的實作區分有損和無損類型轉換,它們在複本上的使用可以透過設定系統變數 replica_type_conversions 的全域值來控制。
關於 NDB Cluster 中屬性升級與降級的更多資訊,請參閱基於列的複製:屬性升級與降級。
與 InnoDB 或 MyISAM 不同,NDB 不會將虛擬欄位的變更寫入二進制日誌;然而,這對 NDB Cluster 複製或 NDB 與其他儲存引擎之間的複製沒有不利影響。儲存產生的欄位的變更會被記錄。