文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  ...  /  複製與 MEMORY 資料表

19.5.1.21 複製與 MEMORY 資料表

當複製來源伺服器關閉並重新啟動時,其 MEMORY 資料表會變成空的。為了將此效果複製到複本,來源在啟動後第一次使用給定的 MEMORY 資料表時,會記錄一個事件,通知複本必須清空該資料表,方法是將該資料表的 DELETETRUNCATE TABLE 陳述式寫入二進制日誌。這個產生的事件可以透過二進制日誌中的註解來識別,並且如果伺服器上正在使用 GTID,則會分配一個 GTID。即使二進制日誌格式設定為 ROW,此陳述式也始終以陳述式格式記錄,並且即使伺服器上設定了 read_onlysuper_read_only 模式也會寫入。請注意,在來源重新啟動到第一次使用該資料表之間的間隔期間,複本的 MEMORY 資料表中仍然有過時的資料。為了避免在此間隔期間直接查詢複本可能會傳回過時資料的情況,您可以設定 init_file 系統變數,以指定一個檔案,其中包含在來源啟動時用來填入 MEMORY 資料表的陳述式。

當複本伺服器關閉並重新啟動時,其 MEMORY 資料表會變成空的。這會導致複本與來源失去同步,並可能導致其他失敗或導致複本停止。

  • 從來源接收的列格式更新和刪除可能會失敗,並顯示錯誤 Can't find record in 'memory_table'

  • 諸如 INSERT INTO ... SELECT FROM memory_table 等陳述式可能會在來源和複本上插入不同的列集合。

複本也會將 DELETETRUNCATE 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 = MEMORYTRUNCATE TABLE 在變更後建立或更新的 MEMORY 資料表生效,或對伺服器重新啟動後的所有 MEMORY 資料表生效。如果您在來源上增加此變數的值,而沒有在複本上執行此操作,則來源上的資料表可能會變得大於複本上的對應資料表,從而導致在來源上成功插入,但在複本上由於 Table is full 錯誤而失敗。這是一個已知問題(Bug #48666)。在這種情況下,您必須在複本和來源上設定 max_heap_table_size 的全域值,然後重新啟動複製。還建議您重新啟動來源和複本 MySQL 伺服器,以確保新值在每個伺服器上完全(全域)生效。

有關 MEMORY 資料表的詳細資訊,請參閱第 18.3 節,「MEMORY 儲存引擎」