文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


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

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 表的副本的安全方法是,首先从源服务器上的 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.39 节,“复制和变量”)。max_heap_table_size 的更改将对使用 ALTER TABLE ... ENGINE = MEMORYTRUNCATE TABLE 创建或更新的 MEMORY 表生效,或对服务器重启后所有 MEMORY 表生效。如果在源服务器上增加此变量的值,而不在副本服务器上增加,则源服务器上的表可能会比副本服务器上的表更大,从而导致在源服务器上成功插入但在副本服务器上失败,并出现 Table is full 错误。这是一个已知问题(Bug #48666)。在这种情况下,必须在副本服务器上以及源服务器上设置 max_heap_table_size 的全局值,然后重启复制。还建议重新启动源服务器和副本服务器,以确保新值在每个服务器上完全(全局)生效。

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