Documentation Home

17.5.1.21 复制和内存表

当复制源服务器关闭并重新启动时,其 MEMORY表变为空。为了将这种效果复制到副本,源MEMORY在启动后第一次使用给定表时,它会记录一个事件,通知副本必须通过将该表的 DELETEor (来自 MySQL 8.0.22) TRUNCATE 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

副本还将一个DELETE 或(来自 MySQL 8.0.22)TRUNCATE TABLE语句写入其自己的二进制日志,该日志将传递给任何下游副本,导致它们清空自己的 MEMORY表。

重新启动正在复制 MEMORY表的副本的安全方法是首先从源上的表中删除或删除所有行,MEMORY 然后等待这些更改已复制到副本。然后重新启动副本是安全的。

在某些情况下可能会应用替代的重启方法。当 时 ,如果您在再次启动副本之前设置 (从 MySQL 8.0.26 开始)或 (在 MySQL 8.0.26 之前) binlog_format=ROW,则可以防止副本停止 。这允许副本继续复制,但它的 表仍然与源上的不同。如果应用程序逻辑可以安全地丢失表的内容 (例如,如果 表用于缓存),这是可以接受的。 或 全局应用于所有表,因此它可能隐藏非表中的其他复制错误。 replica_exec_mode=IDEMPOTENTslave_exec_mode=IDEMPOTENTMEMORYMEMORYMEMORYreplica_exec_mode=IDEMPOTENTslave_exec_mode=IDEMPOTENTMEMORY

(刚刚描述的方法不适用于 NDB Cluster,其中replica_exec_modeor slave_exec_mode始终为 IDEMPOTENT,并且无法更改。)

表的大小MEMORY受系统变量的值限制, max_heap_table_size系统变量不被复制(参见 第 17.5.1.39 节,“复制和变量”)。中的更改 对使用更改或更改后创建或更新max_heap_table_size的表生效 ,或者对服务器重新启动后的所有 表生效。如果您在源上增加此变量的值而不在副本上这样做,则源上的表可能会变得比副本上的对应表大,导致插入在源上成功但在副本上失败已满MEMORYALTER TABLE ... ENGINE = MEMORYTRUNCATE TABLEMEMORY错误。这是一个已知问题(缺陷 #48666)。在这种情况下,您必须在副本和源上设置全局值 max_heap_table_size,然后重新启动复制。还建议您重新启动源和副本 MySQL 服务器,以确保新值对它们中的每一个都产生完整(全局)影响。

有关表 的更多信息, 请参阅第 16.3 节,“内存存储引擎” 。MEMORY