不会。ROW模式下从库SQL线程直接解析Table_map_event和Write_rows_event,调用存储引擎写入数据,完全绕过SQL解析器、优化器和触发器引擎,同名触发器不会被激活。

ROW模式下从库SQL线程根本不走触发器执行路径
MySQL从库在binlog_format = ROW时,SQL线程解析的是Table_map_event、Write_rows_event这类行级事件,直接调用存储引擎接口写入数据,完全绕过SQL解析器、优化器和触发器引擎。这不是“没启用”,而是架构层面跳过了整个触发器调用链。
常见误判是看到SHOW TRIGGERS里有定义,就以为会执行——但只要relay log里是ROW事件,从库连TRIGGER这个词都不会碰一下。
从库触发器只在STATEMENT模式或手动写入时才可能激活
只有两种现实场景会让从库触发器实际运行:
- 主库
binlog_format设为STATEMENT或MIXED,且某条带触发器的语句被降级记录为语句(比如触发器里用了UUID()、NOW()) - 运维人员在从库显式执行
SET sql_log_bin = 1后,再手动跑INSERT/UPDATE——但这属于违规写入,和复制无关
注意:read_only = ON不影响触发器是否被调用,只影响它内部写操作能否成功;如果触发器真被激活了,但read_only开着,就会立刻报ERROR 1290 (HY000)。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
为什么不能靠“在从库建同名触发器”来补漏
即使你手动在从库CREATE TRIGGER,也解决不了根本问题:
- 主库触发器修改的字段值(如
NEW.updated_at := NOW())在ROW日志里只存最终结果,从库拿到的是时间戳字符串,不是函数调用逻辑 - 触发器若更新其他表(如审计日志表),该变更不会进binlog,从库永远缺失那条记录
- DEFINER用户在从库不存在或缺
TRIGGER权限时,SHOW TRIGGERS能查到,但实际加载失败,静默跳过
更危险的是:主库触发一次,从库再触发一次,audit_log行数翻倍、唯一键冲突、字段覆盖错乱——这些问题往往不报错,只在比对数据时才暴露。
排查时别只看触发器是否存在,要看binlog内容
确认行为的唯一可靠方式是查binlog本身:
- 在主库用
mysqlbinlog --base64-output=DECODE-ROWS -v看对应事务,确认是否含Write_rows事件 - 在从库执行
SELECT @@binlog_format;,确保是'ROW'而非'STATEMENT'或'MIXED' - 检查
SHOW SLAVE STATUS\G里的Exec_Master_Log_Pos和Relay_Log_Pos是否持续前进,排除因触发器引发的隐式STATEMENT退化导致卡住
真正容易被忽略的点是:触发器里哪怕只调了一次USER()或ROW_COUNT(),都可能导致MySQL在ROW模式下自动切回STATEMENT记录整条语句——这时从库就真会二次触发,但你从配置里完全看不出异样。

















