本文为您介绍在对只读实例执行某些预期外的操作时,不生成 binlog 的实践说明。
背景
腾讯云数据库技术团队在现网生产环境中观察到,部分预期外的操作在只读实例(RO)上异常地产生了 GTID。这种场景通常见于当 RO 有用户访问流量,且用户对 RO 执行 FLUSH TABLE 操作时。对于这种场景,在执行操作后会生成 binlog,推进 GTID 的产生,这将引起一系列 binlog 不一致,影响复制订阅等问题。
除了 FLUSH TABLE 操作,类似的还包括 REPAIR TABLES、ANALYZE TABLES 以及 OPTIMIZE TABLES。这些本应在主库执行或非事务性的维护指令,在 RO 实例上运行时错误地参与了 GTID 生成逻辑,引发下游订阅异常。
影响分析
对于上述背景中的操作,在执行后可能会引起一系列 binlog 不一致,影响复制订阅等问题。当 RO 上有订阅时,则在后续变配迁移切换后,上述背景中产生的 GTID 会丢失,对于下游使用 Flink 等第三方工具的用户会校验失败,进而报错,迫使业务面临停摆风险。

解决方案分析
方案1
云数据库 MySQL 提供对应语法,以便在执行 FLUSH TABLE 时不写 binlog,具体方法是加 NO_WRITE_TO_BINLOG 关键字。
示例:
flush NO_WRITE_TO_BINLOG table;
分析1
对于这种方案,存在一个不便捷的因素,即每次执行都需要加关键字,有时可能会遗忘。因此,此方案不具备易用性。
方案2
腾讯云数据库技术团队进行了内核的优化,将 FLUSH TABLE 默认行为置为 NO_WRITE_TO_BINLOG 状态,在备机(read_only = on)和 RO 上执行 FLUSH TABLE 操作不生成 binlog。
分析2
本次优化要考虑的主要方向是避免主从 binlog 不一致的问题,在主实例上执行 FLUSH TABLE,要正常生成 binlog,因此将 FLUSH TABLE 默认行为置为 NO_WRITE_TO_BINLOG 状态对主实例无任何影响;另一个方面是备机复制线程也要不受影响,即在主实例上执行的 FLUSH TABLE 语句同步到备机后,复制线程正常回放生成 binlog。
方案2使用说明

方案2支持版本
MySQL 5.7 20250510
MySQL 8.0 20250430
方案2不记录 binlog 的语法说明
升级至目标内核小版本后,在备机(read_only = on)和 RO 上,不记录 binlog 的语法参考如下:
REPAIR TABLE
OPTIMIZE TABLE
ANALYZE TABLE
FLUSH BINARY LOGS
FLUSH DES_KEY_FILE
FLUSH ENGINE LOGS
FLUSH ERROR LOGS
FLUSH GENERAL LOGS
FLUSH HOSTS
FLUSH LOGS
FLUSH PRIVILEGES
FLUSH OPTIMIZER_COSTS
FLUSH QUERY CACHE
FLUSH RELAY LOGS
FLUSH SLOW LOGS
FLUSH STATUS
FLUSH USER_RESOURCES
FLUSH TABLE
FLUSH TABLES