必须设为ROW,因STATEMENT仅记录SQL文本而不记录实际变更行,导致NOW()、UUID()等非确定函数及触发器、自增列等在从库重放时结果不同;MIXED存在隐式降级至STATEMENT的盲区;ROW+FULL才是保障主从一致的可靠组合。

必须设为 ROW,其他选项在主从一致性场景下都不够可靠。
为什么 STATEMENT 会导致主从数据不一致
它只记录原始 SQL 文本,不记录实际影响的行。比如 INSERT INTO users VALUES (1, UUID(), 'alice') 在主库生成一个 UUID,在从库回放时又生成另一个 UUID,两边值必然不同。类似问题还出现在:NOW()、RAND()、CURRENT_USER()、触发器、自增列插入、存储函数调用等场景。这些语句在从库重放时行为不可控,无法还原主库真实状态。
MIXED 模式下哪些操作仍会悄悄退回到 STATEMENT
MySQL 的自动降级逻辑不透明,以下情况即使设了 MIXED,也仍以 STATEMENT 记录:
-
UUID()、RAND()、USER()、CURRENT_USER()等非确定性函数参与的写操作 -
LOAD DATA INFILE或INSERT ... SELECT目标表含自增列 - 调用未显式声明
DETERMINISTIC的存储函数或触发器 -
CREATE TABLE ... SELECT且源表存在未提交事务
这些操作在 binlog 中只有语句文本,没有行级镜像,恢复或同步时无法保证结果一致。
解析 MySQL 8.0 的 DDL 脚本,并将表结构导出为 Excel 格式。适用于用户需将 MySQL 的 `CREATE TABLE` 语句转换为结构化的 Excel 文件场景,导出内容包含字段名、数据类型、长度及精度等信息。支持多张表的批量处理,每张表对应 Excel 中的一个独立工作表。适用于数据库文档编写、数据字典生成及模式分析等任务。
配置 binlog_format = ROW 的关键实操动作
临时设置(如 SET GLOBAL binlog_format = 'ROW')对已有活跃事务无效,且重启后失效。生产环境必须永久配置:
- 编辑
/etc/my.cnf或/etc/mysql/my.cnf,在[mysqld]段下添加:binlog_format = ROW - 确认已启用
log_bin,并设置唯一server-id(主从环境下不能重复) - 重启前检查从库是否正在拉取当前 binlog(避免
RESET MASTER中断复制) - 重启后执行
SHOW VARIABLES LIKE 'binlog_format';验证返回值为ROW - 立即执行
FLUSH LOGS;,确保后续所有变更都进入新 binlog 文件并按ROW格式记录
ROW 模式下还需注意的两个隐性依赖
ROW 能保障行级可追溯,但前提是:
-
binlog_row_image必须为FULL(默认值),否则MINIMAL或NOBLOB会丢字段,导致反向构造失败 - 主库和从库的 MySQL 版本需兼容,尤其涉及 JSON、虚拟列、Generated Column 等特性时,低版本从库可能无法正确解析高版本主库的
ROW事件
最易被忽略的是:哪怕 binlog_format 设对了,如果没做 FLUSH LOGS,旧 binlog 文件里仍可能是 STATEMENT 或 MIXED 写入的内容——这部分日志一旦被从库拉取,就再也无法挽回一致性。










