mysql从库触发器默认不执行,因主从复制仅同步binlog事件而非触发器逻辑;需手动创建且受read_only、definer权限及binlog_format限制,可靠替代方案为应用层双写或binlog监听。

MySQL 从库上触发器默认不执行,根本不存在 slave_run_triggers 这个配置项——它不是 MySQL 的合法系统变量,任何试图 SET 或查它都会报错 ERROR 1238 (HY000): Variable 'slave_run_triggers' is a read only variable 或直接提示未知变量。
SHOW VARIABLES LIKE '%trigger%' 查不到就对了
MySQL 官方文档和源码中从未定义过 slave_run_triggers。你在网上看到的所谓“开启该参数让从库执行触发器”,基本都源于对复制机制的误解或旧版错误教程的传播。实际行为由复制格式(binlog_format)和触发器部署方式共同决定,跟“开关参数”无关。
主库触发、从库不触发是设计使然,不是故障
- 主库执行
INSERT INTO orders触发AFTER INSERT,往orders_log插一行 → 这个“插日志”的动作不会写进 binlog - 从库只收到原始的
INSERT INTO orders事件,重放时不会再次触发自己的触发器(即使已创建) - 所以从库
orders_log表为空或不同步,不是因为“没开开关”,而是因为逻辑根本没被同步过去
真正要检查的三个硬性条件
如果你坚持要在从库也跑触发器逻辑,必须同时满足:
-
binlog_format = STATEMENT:只有这个模式下,从库重放 SQL 时才会“再次触发”——但会导致重复执行风险(主库触发一次 + 从库再触发一次),且禁用 ROW 后 UUID()/NOW() 等函数引发主从不一致 - 从库上已手动执行
CREATE TRIGGER,且DEFINER用户存在、有TRIGGER权限;否则SHOW TRIGGERS能看到但实际加载失败 - 从库未启用
read_only = ON:否则触发器内任何写操作(如 INSERT/UPDATE)会直接报ERROR 1290 (HY000)
别碰 STATEMENT 模式,优先考虑替代方案
把触发器逻辑提到应用层双写,是最可控的做法。如果必须保留在数据库侧,用 binlog 监听(如 Maxwell、Canal)解析变更后投递到下游服务,比依赖从库触发器可靠得多。ROW 模式下强行让从库触发,等于在复制链路上埋雷——时间一长,orders_log 和 orders 的行数对不上、字段值错位、甚至主键冲突,排查成本远高于初期重构。











