MySQL触发器本身不生成binlog事件,但其引发的每条DML操作(如INSERT/UPDATE/DELETE)均独立生成对应行事件组;ROW模式下,一条DML语句产生一个事件组,含影响行的前后镜像,数量取决于实际执行的DML语句条数及影响行数。

触发器本身不产生额外的 Binlog 记录,但触发器引发的 DML 操作会单独生成 Binlog 事件 —— 所以“几条”取决于触发器里实际执行了几条 INSERT/UPDATE/DELETE。
触发器执行不会被记录为独立 Binlog event
MySQL 的 Binlog 只记录 Server 层最终提交的 DML 和 DDL 操作,不记录触发器逻辑本身。哪怕你写了一个 AFTER INSERT 触发器,里面又插入了 5 行数据,Binlog 里也不会出现 “触发器被调用” 这类元信息。
真正会被记录的,是触发器内显式执行的每一条变更语句 —— 而且它们和原始语句一样,走完整的事务、日志写入流程。
- 原始语句(比如
INSERT INTO orders)生成一条 Binlog event(Write_rows或Query,取决于格式) - 触发器中执行的
INSERT INTO logs会再生成一条独立的Write_rowsevent - 如果触发器里还有
UPDATE stats SET count = count + 1,又会多一条Update_rowsevent
ROW 模式下,每条 DML 对应一个独立的行事件组
在 binlog_format = ROW 时,每个 DML 语句(无论是否由触发器发起)都会生成一组行事件(Write_rows / Update_rows / Delete_rows),包含该语句影响的所有行的前后镜像。
关键点:
- 不是“一个触发器 → 一条 Binlog”,而是“一个 DML 语句 → 至少一个 event group”
- 批量插入(如
INSERT ... SELECT)在触发器里执行,会按实际影响行数生成对应数量的行变更记录(不是按语句计数) -
binlog_row_image = MINIMAL可减少 UPDATE/DELETE 的字段冗余,但不改变 event 数量
容易踩的坑:主从复制时触发器行为不一致
这是最常被忽略的实战陷阱 —— 主库和从库的触发器默认不会同步执行,除非你显式配置 log_bin_trust_function_creators = 1 并确保从库也创建了相同触发器。
常见错误现象:
- 主库 insert → 触发器写 log 表 → Binlog 包含两条记录(主表 + log 表)
- 从库重放时,只执行原始 insert,触发器不自动触发 → log 表数据缺失
- 结果:主从数据逻辑不一致(log 表在主库有记录,从库没有)
解决方式只有两种:
- 禁用从库触发器(推荐),靠应用层或主库统一写 log;
- 手动在从库创建相同触发器,并设置
replicate_do_table等过滤规则,但需严格保证主从触发器逻辑完全一致。
验证方法:用 mysqlbinlog 工具看真实输出
别依赖猜测,直接查 Binlog 文件:
mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.000001 | grep -A 5 -B 5 "table_name"
你会看到类似这样的片段(简化):
-
# at 1234→ 原始 INSERT 到orders -
# at 2345→ 触发器 INSERT 到audit_log -
# at 3456→ 触发器 UPDATE 到summary
每个 # at 偏移量对应一个独立的 event,后面跟着具体的行变更细节。
复杂点在于:触发器链(A 触发 B,B 又触发 C)会让 Binlog 事件数呈线性增长,且难以追溯因果关系 —— 这时候必须靠 end_log_pos 和事务 ID 关联,而不是靠语义推断。


















