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节,“内存存储引擎”,了解更多关于内存表的信息。