mysql存储过程修改后复制中断主因是主从mysql.proc表结构不一致或log_bin_trust_function_creators=0,需同步版本、执行mysql_upgrade并配置该参数。

修改存储过程后复制中断,先看错误码是不是 1410 或 1539
这类中断几乎都源于主库执行 ALTER PROCEDURE、DROP PROCEDURE 或 CREATE PROCEDURE 后,从库无法解析或权限不足。最典型的是 Last_SQL_Error 显示 ERROR 1410 (HY000): You are not allowed to create a user with GRANT(实际是权限校验误报)或 ERROR 1539 (HY000): Cannot load from mysql.proc. The table is probably corrupted。根本原因不是语法错,而是从库的 mysql.proc 表结构与主库不一致,或从库未启用 log_bin_trust_function_creators=1。
从库 missing mysql.proc 表或结构不匹配时不能硬跳过
如果 SHOW SLAVE STATUS\G 中 Last_SQL_Error 提到 mysql.proc、Table 'mysql.proc' doesn't exist 或字段数不符,说明从库的系统表没跟上主库升级(比如主库是 MySQL 8.0,从库还是 5.7,或中途跳过过 DDL)。此时用 SET GLOBAL sql_slave_skip_counter = 1 强行跳过只会让后续所有存储过程操作都失败。
- 确认版本:主从必须同大版本(5.7 ↔ 5.7,8.0 ↔ 8.0),小版本差异需补全
mysql_upgrade - 检查表结构:
DESC mysql.proc;对比主从字段数量和类型,常见缺失字段如character_set_client、collation_connection - 修复方式:在从库执行
mysql_upgrade -u root -p(需停复制),或手动导出主库mysql.proc的建表语句,在从库重建
log_bin_trust_function_creators=0 导致 CREATE/ALTER PROCEDURE 被拒绝
主库若未设 log_bin_trust_function_creators=1,任何含 DETERMINISTIC、READS SQL DATA 等特性的存储过程修改都会被主库记录为 unsafe event,并在从库回放时报错中断。错误日志里通常带 Unsafe statement written to the binary log。
- 主库临时修复:
SET GLOBAL log_bin_trust_function_creators = 1;(重启失效,需写入my.cnf) - 从库无需改此参数,但必须确保主库已开启,否则新创建的过程永远无法同步
- 长期方案:在主库
my.cnf加log_bin_trust_function_creators=1,并为存储过程显式声明DETERMINISTIC或NO SQL
GTID 模式下修改过程后复制卡住,别乱 reset master
GTID 环境中,CREATE PROCEDURE 会生成一个 GTID 事务。如果从库报 Could not execute command on worker: Attempted to execute replication event with GTID that was already executed,说明该 GTID 已存在于 Executed_Gtid_Set,但过程没生效——大概率是之前跳过事务时漏掉了依赖的系统表更新。
- 查卡点:
SELECT * FROM performance_schema.replication_applier_status_by_worker;找出LAST_ERROR_MESSAGE和对应 GTID - 注入空事务前先确认:
SELECT @@GLOBAL.gtid_executed;是否包含报错中的 GTID;若已存在,说明不是重复执行,而是过程未落地,应优先检查mysql.proc - 严禁在未确认情况下执行
RESET MASTER,这会清空所有 GTID,导致后续无法自动定位位点
真正麻烦的从来不是“怎么改过程”,而是“改完之后从库连 mysql.proc 都读不了”。很多团队在测试环境改完过程就上线,却忘了从库可能压根没跑过 mysql_upgrade,或者主库参数漏配——这些细节不会报语法错误,但会让复制在某条 ALTER PROCEDURE 后彻底静默失败。











