必须运行SHOW CREATE TRIGGER trigger_name;确认真实DEFINER=xxx@yyy,而非GUI显示的CURRENT_USER();再查该用户是否存在、权限是否完备(含跨库及SYSTEM_VARIABLES_ADMIN)、log_bin_trust_function_creators是否启用,并验证TRIGGERS.STATUS为ENABLED。

查触发器 DEFINER 是谁,别信 GUI 工具显示的
触发器执行失败时,MySQL 不看你当前登录账号有没有权限,只认 DEFINER 字段里写的那个用户。Navicat、DBeaver 等工具创建触发器时自动生成的 DEFINER=CURRENT_USER(),实际取的是认证用户(比如 'app'@'192.168.1.%'),不是你连工具用的账号。
必须运行:
SHOW CREATE TRIGGER trigger_name;紧盯输出中
DEFINER=`xxx`@`yyy` 这一行。如果看到 DEFINER=CURRENT_USER 或为空,说明它已被固化为创建时刻的用户身份,迁移或重建后很可能已不存在。
验证 DEFINER 用户是否存在且有对应表权限
DEFINER 不是“名字对就行”,它必须是一个真实存在的账号,且对触发器内所有 SQL 涉及的库、表、列都有最小必要权限——包括读 NEW.col 和 OLD.col 所需的 SELECT 权限。
- 查用户是否存在:
SELECT User, Host FROM mysql.user WHERE User = 'xxx';
注意大小写和Host必须完全匹配:'admin'@'localhost'和'admin'@'%'是两个独立账号 - 查该用户实际权限:
SHOW GRANTS FOR 'xxx'@'yyy';
重点核对是否含INSERT ON log_db.audit_log、UPDATE ON mydb.orders等语句 - 若触发器跨库操作(如从
sales库UPDATE report库的表),DEFINER必须对两个库都单独授过权 - MySQL 8.0+ 还要确认是否授予了
SYSTEM_VARIABLES_ADMIN(尤其当触发器读取系统变量或调用函数时)
检查 log_bin_trust_function_creators 是否启用
只要 log_bin=ON(MySQL 5.7+ 默认开启),创建或执行含 NOW()、UUID()、子查询等非确定性操作的触发器,就必须让 MySQL 信任这个 DEFINER。硬加 SUPER 权限不仅高危,而且阿里云 RDS、腾讯云 CDB 等平台直接禁用。
- 临时生效:
SET GLOBAL log_bin_trust_function_creators = 1;
(需SYSTEM_VARIABLES_ADMIN权限) - 持久化:在
my.cnf的[mysqld]段加一行log_bin_trust_function_creators=1 - 该设置只影响“是否允许创建/执行非确定性函数”,不替代
DEFINER本身的权限校验
确认触发器状态是否为 ENABLED
触发器“没反应”大概率不是代码错,而是它压根没被调用——常见原因是状态为 DISABLED。MySQL 不会提示你触发器被禁用了,也不会出现在 SHOW TABLES 里。
执行:
SELECT * FROM information_schema.TRIGGERS WHERE TRIGGER_NAME = 'your_trigger_name';重点看
STATUS 字段:必须是 ENABLED 才算生效。若值为 DISABLED,运行:ALTER TRIGGER your_trigger_name ENABLE;(注意:MySQL 5.7 不支持该语法,只能
DROP 后重建)
最容易被忽略的是:错误日志里可能根本不报错,而只是静默跳过。务必确认 log_error_verbosity = 3(MySQL 8.0+),否则触发器内的警告会被忽略;同时检查 sql_mode 是否含 STRICT_TRANS_TABLES,否则空值插入可能被截断而非报错,导致触发器逻辑实际没跑。


















