當複製來源伺服器關閉並重新啟動時,其 MEMORY
資料表會變成空的。為了將此效果複製到複本,來源在啟動後第一次使用給定的 MEMORY
資料表時,會記錄一個事件,通知複本必須清空該資料表,方法是將該資料表的 DELETE
或 TRUNCATE TABLE
陳述式寫入二進制日誌。這個產生的事件可以透過二進制日誌中的註解來識別,並且如果伺服器上正在使用 GTID,則會分配一個 GTID。即使二進制日誌格式設定為 ROW
,此陳述式也始終以陳述式格式記錄,並且即使伺服器上設定了 read_only
或 super_read_only
模式也會寫入。請注意,在來源重新啟動到第一次使用該資料表之間的間隔期間,複本的 MEMORY
資料表中仍然有過時的資料。為了避免在此間隔期間直接查詢複本可能會傳回過時資料的情況,您可以設定 init_file
系統變數,以指定一個檔案,其中包含在來源啟動時用來填入 MEMORY
資料表的陳述式。
當複本伺服器關閉並重新啟動時,其 MEMORY
資料表會變成空的。這會導致複本與來源失去同步,並可能導致其他失敗或導致複本停止。
從來源接收的列格式更新和刪除可能會失敗,並顯示錯誤
Can't find record in '
。memory_table
'諸如
INSERT INTO ... SELECT FROM
等陳述式可能會在來源和複本上插入不同的列集合。memory_table
複本也會將 DELETE
或 TRUNCATE TABLE
陳述式寫入其自己的二進制日誌,該日誌會傳遞給任何下游複本,導致它們清空自己的 MEMORY
資料表。
重新啟動正在複製 MEMORY
資料表的複本的安全方法是,首先從來源的 MEMORY
資料表中刪除所有列,並等待這些變更複製到複本。然後重新啟動複本才是安全的。
在某些情況下,可以採用替代的重新啟動方法。當 binlog_format=ROW
時,如果您在再次啟動複本之前設定 replica_exec_mode=IDEMPOTENT
,則可以防止複本停止。這允許複本繼續複製,但其 MEMORY
資料表仍然與來源上的不同。如果應用程式邏輯允許安全地丟失 MEMORY
資料表的內容(例如,如果 MEMORY
資料表用於快取),則這是可以接受的。replica_exec_mode=IDEMPOTENT
全域適用於所有資料表,因此可能會隱藏非 MEMORY
資料表中的其他複製錯誤。
(剛才描述的方法不適用於 NDB Cluster,其中 replica_exec_mode
始終為 IDEMPOTENT
,且無法變更。)
MEMORY
資料表的大小受 max_heap_table_size
系統變數的值限制,該變數不會被複製(請參閱 第 19.5.1.39 節,「複製和變數」)。max_heap_table_size
的變更會對使用 ALTER TABLE ... ENGINE = MEMORY
或 TRUNCATE TABLE
在變更後建立或更新的 MEMORY
資料表生效,或對伺服器重新啟動後的所有 MEMORY
資料表生效。如果您在來源上增加此變數的值,而沒有在複本上執行此操作,則來源上的資料表可能會變得大於複本上的對應資料表,從而導致在來源上成功插入,但在複本上由於 Table is full 錯誤而失敗。這是一個已知問題(Bug #48666)。在這種情況下,您必須在複本和來源上設定 max_heap_table_size
的全域值,然後重新啟動複製。還建議您重新啟動來源和複本 MySQL 伺服器,以確保新值在每個伺服器上完全(全域)生效。
有關 MEMORY
資料表的詳細資訊,請參閱第 18.3 節,「MEMORY 儲存引擎」。