文档首页
MySQL 9.0 参考手册
相关文档 下载此手册
PDF (美国信纸) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  复制和 MEMORY 表

19.5.1.22 复制和 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 表的副本的安全方法是,首先删除或删除源上所有 MEMORY 表中的所有行,并等待这些更改复制到副本。然后,可以安全地重新启动副本。

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

(上述方法不适用于 NDB Cluster,在 NDB Cluster 中,replica_exec_mode 始终为 IDEMPOTENT,并且无法更改。)

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

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