根本原因是definer用户在从库不存在、无对应表权限或log_bin_trust_function_creators未启用;需用show create trigger确认definer,核查其存在性、跨库权限及该变量设置。

从库同步中断若由触发器权限不足引发,根本原因不是“没授权”,而是 DEFINER 用户在从库不存在、无对应表权限,或 log_bin_trust_function_creators 未启用——跳过错误或重开 SUPER 权限只会让问题更隐蔽。
查清触发器 DEFINER 是谁,别信 GUI 工具默认值
Navicat、DBeaver 等工具创建触发器时常用 DEFINER=CURRENT_USER(),但这个值固化的是创建时刻的认证账号(比如 'app'@'192.168.1.100'),不是你当前登录用的账号。迁移或重建后该用户大概率已消失。
- 执行
SHOW CREATE TRIGGER trigger_name;,紧盯输出中DEFINER=`xxx`@`yyy`这一行 - 立刻验证:运行
SELECT User, Host FROM mysql.user WHERE User = 'xxx';,注意大小写和Host必须完全匹配('xxx'@'localhost'≠'xxx'@'%') - 如果返回空,说明 DEFINER 账号在从库根本不存在——这是同步中断最常见原因
确认 DEFINER 是否有跨库、跨对象权限
触发器内若含 INSERT INTO log_db.audit_log 或 CALL proc_update_stat(),DEFINER 就必须对 log_db.audit_log 有 INSERT 权限、对 proc_update_stat 所属数据库有 EXECUTE 权限。GRANT ALL ON *.* 不解决问题,云数据库还可能直接拒绝。
- 查权限:运行
SHOW GRANTS FOR 'xxx'@'yyy';,逐条核对触发器 SQL 中涉及的库、表、过程名 - 跨库操作必须单独授权:比如触发器从
sales库 UPDATEreport库的表,则要执行GRANT UPDATE ON report.* TO 'xxx'@'yyy'; - MySQL 8.0+ 还需
SYSTEM_VARIABLES_ADMIN(如触发器里读取@@server_uuid)
检查并启用 log_bin_trust_function_creators
只要主库 log_bin=ON(5.7+ 默认开启),任何含 NOW()、UUID()、子查询或自定义函数的触发器,都要求该变量为 1,否则从库回放时直接报 ERROR 1419。SUPER 权限在 RDS/CDB 上不可用,这条路走不通。
- 查当前值:运行
SELECT @@log_bin_trust_function_creators;,返回 0 即未启用 - 临时生效(需 SYSTEM_VARIABLES_ADMIN):
SET GLOBAL log_bin_trust_function_creators = 1; - 持久化:在从库
my.cnf的[mysqld]段添加log_bin_trust_function_creators=1 - 注意:该设置只解决“是否允许执行非确定性逻辑”,不替代 DEFINER 本身的权限校验
修复必须重建触发器,禁止直改系统表
information_schema.TRIGGERS 是只读视图,不能 UPDATE;直接 INSERT 到 mysql.triggers 会破坏内部一致性,导致后续复制崩溃。唯一安全路径是导出 → 替换 DEFINER → 删除 → 重建。
- 导出:用
mysqldump -u root -p --triggers --no-create-info --no-data --skip-opt dbname > triggers.sql - 替换:将文件中所有
DEFINER=`old_user`@`%`改为存在的运维账号,如DEFINER=`admin`@`%` - 清理:在从库执行
DROP TRIGGER IF EXISTS trigger_name; - 重建:导入修改后的 SQL:
mysql -u root -p dbname - 关键点:新 DEFINER 必须已存在、有对应权限,且其调用的函数/过程也得存在并可执行
最容易被忽略的是:触发器里嵌套调用的存储过程,它的 DEFINER 也要同步验证——DEFINER 链断裂一层,整个触发链就停摆。别只盯着报错那一个触发器。











