mysql 5.6 不支持同一表多个同类触发器,仅允许每个“时机+事件”组合(如 before insert)存在一个触发器;不支持 or 复合事件语法;主从复制中触发器行为依赖 binlog_format;且触发器内不能调用存储过程、建临时表或使用 return。

MySQL 5.6 不支持同一表多个同类触发器
这是最直接、最常踩的坑:5.6 及更早版本对每张表每个「时机 + 事件」组合(比如 BEFORE INSERT)只允许存在一个触发器。你不能建第二个 BEFORE INSERT,哪怕名字不同,也会报错 ERROR 1359 (HY000): Trigger already exists。
这不是配置问题,是内核硬限制——系统只为每个组合预留一个 slot。想绕开?只能把所有逻辑塞进一个触发器里,用 IF 分支判断不同条件,结果可读性差、调试难、修改易出错。
- 典型错误现象:
DROP TRIGGER t1; CREATE TRIGGER t2 BEFORE INSERT ON tbl ...仍失败 - 5.7+ 才引入
FOLLOWS/PRECEDES支持多触发器排序,5.6 完全没这语法 - 迁移脚本若含
FOLLOWS,在 5.6 上会直接报错ERROR 1064
MySQL 5.6 触发器不支持 OR 复合事件语法
INSERT OR UPDATE 这种写法在 5.6 中是非法的。官方语法只接受单一事件:INSERT、UPDATE 或 DELETE,三者不可并列。
如果你看到类似 CREATE TRIGGER t AFTER INSERT OR UPDATE ON tbl ... 的语句能执行成功,要么是客户端解析器做了兼容性处理(实际未生效),要么是用了非原生 MySQL 的兼容库(如金仓),但行为不可靠——它大概率只响应 INSERT,UPDATE 操作不会触发。
- 必须拆成两个独立触发器:
AFTER INSERT和AFTER UPDATE - 注意字段引用差异:
INSERT只有NEW,UPDATE同时有OLD和NEW - 跨版本脚本别用复合事件声明,否则在 5.6 上会静默失效或报错
主从复制下触发器行为高度依赖 binlog 格式
在 5.6 中,触发器是否在从库执行,完全由 binlog_format 决定,且无法统一控制:
-
STATEMENT模式:触发器在主库和从库都执行 → 要求从库也定义完全相同的触发器,否则主从数据不一致 -
ROW模式:触发器只在主库执行,变更后的行数据直接下发 → 从库无需定义触发器,但你也无法在从库做审计或二次校验
这意味着:部署前必须确认 binlog_format;如果用 STATEMENT,从库缺失触发器会导致数据漂移,且这种错误往往延迟暴露,排查成本高。
5.6 触发器内部能力受限且调试困难
除了外部限制,5.6 触发器本身功能也弱:
- 不能调用存储过程(
CALL语句被禁止) - 不能创建临时表、视图,也不能使用
RETURN - 没有
information_schema.TRIGGERS.CREATED字段(8.0 才加),查创建时间只能靠人工记录 - 错误日志不带触发器上下文,
SIGNAL报错只显示 SQLSTATE,定位具体哪一行出问题得靠反复注释测试
再加上触发器逻辑隐式执行、无断点、难单元测试,一旦出问题,基本只能靠 SELECT 插桩 + 重放 DML 来推演,效率极低。











