當複製來源伺服器關閉並重新啟動時,其 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.40 節,「複製與變數」)。max_heap_table_size
的變更會對在變更後使用 ALTER TABLE ... ENGINE = MEMORY
或 TRUNCATE TABLE
建立或更新的 MEMORY
表格生效,或是對伺服器重新啟動後的所有 MEMORY
表格生效。如果您在來源上增加此變數的值,而未在複本上執行此操作,則來源上的表格可能會比複本上的對應表格大,導致在來源上成功插入,但在複本上因 表格已滿 錯誤而失敗。這是一個已知問題(錯誤 #48666)。在這種情況下,您必須在複本和來源上都設定 max_heap_table_size
的全域值,然後重新啟動複製。建議您同時重新啟動來源和複本 MySQL 伺服器,以確保新值在它們各自上完全(全域)生效。
請參閱第 18.3 節,「MEMORY 儲存引擎」,以取得有關 MEMORY
表格的更多資訊。