ERROR 1419或触发器执行拒绝,主因是DEFINER用户不存在、无对应表权限,或log_bin_trust_function_creators未启用;需通过SHOW CREATE TRIGGER确认DEFINER,核查用户存在性、跨库权限及该变量设置。

触发器执行时报 ERROR 1419 或 Access denied for trigger execution,基本可以断定是 DEFINER 用户不存在、无对应表权限,或当前环境未启用 log_bin_trust_function_creators。
查触发器定义和实际 DEFINER 是谁
先确认触发器里写的 DEFINER 到底是谁,而不是猜:
- 运行
SHOW CREATE TRIGGER trigger_name;,看输出中DEFINER=`xxx`@`yyy`字段 - 注意:Navicat 等 GUI 工具自动生成的
DEFINER = CURRENT_USER()往往取的是认证用户(比如'app'@'192.168.1.%'),不是你登录 Navicat 用的账号 - 如果输出里是
DEFINER=CURRENT_USER或空着,MySQL 实际会设为创建时的CURRENT_USER(),仍需验证该用户是否存在且有权
验证 DEFINER 用户是否存在且有操作权限
DEFINER 不是“名字对就行”,它必须是一个真实存在的 MySQL 账号,且对该触发器内所有 SQL 涉及的库表拥有完整权限:
- 查用户是否存在:
SELECT User, Host FROM mysql.user WHERE User = 'xxx';(注意大小写和Host是否匹配) - 查该用户的权限:
SHOW GRANTS FOR 'xxx'@'yyy';,重点核对是否含INSERT ON log_db.audit_log、UPDATE ON mydb.orders这类语句 - 如果触发器里写了跨库操作(比如从
sales库 UPDATEreport库的表),DEFINER必须对两个库都授过权 - 别用
GRANT ALL ON *.*代替——它在 MySQL 8.0+ 虽含TRIGGER,但违反最小权限原则,云数据库(如阿里云 RDS)通常禁用
log_bin_trust_function_creators 未开导致 ERROR 1419
只要开启了 binlog(log_bin=ON,MySQL 5.7+ 默认开启),创建或执行含非确定性函数(如 NOW()、UUID()、子查询)的触发器,就必须让 MySQL 信任这个 DEFINER:
- 临时生效:
SET GLOBAL log_bin_trust_function_creators = 1;(需要SYSTEM_VARIABLES_ADMIN权限,MySQL 8.0+;旧版需SUPER) - 持久化:在
my.cnf的[mysqld]段加一行:log_bin_trust_function_creators=1 - 云数据库(RDS/CDB)通常禁用
SUPER,这是唯一可行路径;硬加SUPER权限不仅无效,还可能被平台自动回收 - 该设置只影响触发器/函数创建和执行的信任判定,不改变
DEFINER本身的权限校验逻辑
为什么 CREATE TRIGGER 成功但 INSERT 时才报错
因为触发器创建和触发是两套权限检查:
- 创建时只校验你当前用户是否有
TRIGGER权限(GRANT TRIGGER ON db_name.* TO 'user'@'host';) - 触发时(比如应用执行
INSERT)检查的是DEFINER用户——它必须存在、能连上、且对触发器内每条 SQL 所操作的库表都有对应权限 - 常见错觉:“我用 root 创建的,怎么会没权?”——root 是创建者,
DEFINER可能是'app'@'%',而这个账号压根没建,或只被授了SELECT没给INSERT - 生产环境最稳做法:删掉
DEFINER行,让 MySQL 自动设为创建者;或显式设成一个专用账号(如'trig_admin'@'localhost'),再单独授所需权限
真正卡住人的地方,往往不是缺某条 GRANT 命令,而是 DEFINER 用户的 Host 匹配失败、跨库权限漏授、或者 log_bin_trust_function_creators 在配置文件里写了却忘了重启 mysqld —— 这些细节不逐项敲命令验证,光看报错信息根本绕不出来。


















