当复制源服务器关闭并重新启动时,其
MEMORY
表变为空。为了将这种效果复制到副本,源MEMORY
在启动后第一次使用给定表时,它会记录一个事件,通知副本必须通过将该表的
DELETE
or (来自 MySQL 8.0.22)
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
或(来自 MySQL 8.0.22)TRUNCATE
TABLE
语句写入其自己的二进制日志,该日志将传递给任何下游副本,导致它们清空自己的
MEMORY
表。
重新启动正在复制
MEMORY
表的副本的安全方法是首先从源上的表中删除或删除所有行,MEMORY
然后等待这些更改已复制到副本。然后重新启动副本是安全的。
在某些情况下可能会应用替代的重启方法。当 时
,如果您在再次启动副本之前设置
(从 MySQL 8.0.26 开始)或
(在 MySQL 8.0.26 之前) binlog_format=ROW
,则可以防止副本停止
。这允许副本继续复制,但它的
表仍然与源上的不同。如果应用程序逻辑可以安全地丢失表的内容
(例如,如果
表用于缓存),这是可以接受的。
或
全局应用于所有表,因此它可能隐藏非表中的其他复制错误。
replica_exec_mode=IDEMPOTENT
slave_exec_mode=IDEMPOTENT
MEMORY
MEMORY
MEMORY
replica_exec_mode=IDEMPOTENT
slave_exec_mode=IDEMPOTENT
MEMORY
(刚刚描述的方法不适用于 NDB Cluster,其中replica_exec_mode
or
slave_exec_mode
始终为
IDEMPOTENT
,并且无法更改。)
表的大小MEMORY
受系统变量的值限制,
max_heap_table_size
系统变量不被复制(参见
第 17.5.1.39 节,“复制和变量”)。中的更改
对使用更改或更改后创建或更新max_heap_table_size
的表生效
,或者对服务器重新启动后的所有
表生效。如果您在源上增加此变量的值而不在副本上这样做,则源上的表可能会变得比副本上的对应表大,导致插入在源上成功但在副本上失败表已满MEMORY
ALTER TABLE
... ENGINE = MEMORY
TRUNCATE
TABLE
MEMORY
错误。这是一个已知问题(缺陷 #48666)。在这种情况下,您必须在副本和源上设置全局值
max_heap_table_size
,然后重新启动复制。还建议您重新启动源和副本 MySQL 服务器,以确保新值对它们中的每一个都产生完整(全局)影响。
有关表
的更多信息,
请参阅第 16.3 节,“内存存储引擎” 。MEMORY