19.5.1.21 复制和MEMORY表
当复制源服务器关闭并重新启动时,它的MEMORY
表将变空。为了在复制中实现这个效果,源服务器在首次使用某个MEMORY
表后,会记录一个事件,通知复制服务器该表必须被清空,通过在二进制日志中写入DELETE
或TRUNCATE TABLE
语句。这个生成的事件可以通过二进制日志中的注释标识,并且如果服务器使用GTID,如果GTID被分配。语句总是以语句格式记录,即使二进制日志格式设置为ROW
,并且在服务器设置为只读或超级只读模式时也会写入。注意,在源服务器重新启动到首次使用该表之间,复制服务器仍然会有过时数据在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集群,因为replica_exec_mode
始终为IDEMPOTENT
,并且不能被更改。)
MEMORY
表的大小受max_heap_table_size
系统变量的限制,该变量不复制(见第19.5.1.39节,“Replication and Variables”)。将max_heap_table_size
的值更改将对使用ALTER TABLE ... ENGINE = MEMORY
或TRUNCATE TABLE
创建或更新的MEMORY
表或在服务器重启后对所有MEMORY
表生效。如果在源服务器上增加了max_heap_table_size
的值,但是在备用服务器上没有这样做,那么在源服务器上可以增长的表在备用服务器上可能会导致插入操作成功在源服务器上但是在备用服务器上失败,并出现Table is full错误。这是一个已知问题(Bug #48666)。在这种情况下,您需要在备用服务器上设置max_heap_table_size
的全局值,然后重新启动复制。还建议您重新启动源服务器和备用服务器,以确保新的值在每个服务器上生效。
查看第18.3节,“内存存储引擎”,了解更多关于内存
表的信息。