Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  Replication and MEMORY Tables

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表中的所有行,然后等待这些更改复制到副本上。然后,可以安全地重新启动副本。

在某些情况下,可能适用替代的重新启动方法。当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表生效。如果您在源服务器上增加该变量的值,而不在副本服务器上这样做,那么源服务器上的表可能会增长得比副本服务器上的表大,从而导致插入操作在源服务器上成功,但在副本服务器上失败,出现“表已满”错误。这是一个已知的问题(Bug #48666)。在这种情况下,您必须在副本服务器上设置全局变量max_heap_table_size的值,然后重新启动复制。同时,我们建议您重新启动源服务器和副本服务器的MySQL服务器,以确保新值在每个服务器上生效。

请参阅第18.3节,“MEMORY存储引擎”,以获取更多关于MEMORY表的信息。