MySQL 5.7升级到8.0后DEFINER报错,主因是8.0强化definer权限校验且废弃mysql.proc表;需用8.0 mysqldump导出、修改DEFINER为CURRENT_USER、显式加--routines参数,并注意字符集与排序规则兼容性。

MySQL 5.7 升级到 8.0 后 DEFINER 报错怎么办
升级后执行 SHOW CREATE PROCEDURE 或调用过程直接报 Access denied; you need (at least one of) the SUPER privilege(s),本质是 8.0 默认启用了 sql_require_primary_key 和更严格的 definer 权限校验。
- 导出前先用低权限账号登录,执行
SET sql_log_bin = 0;再修改所有过程的DEFINER为当前用户(如DEFINER=CURRENT_USER) - 避免用
root@localhost这类高权限账户作为DEFINER,否则导入时会强制校验该用户是否存在且有对应权限 - 如果必须保留原
DEFINER,得在目标库提前创建同名用户并赋权:CREATE USER 'old_user'@'localhost'; GRANT EXECUTE ON *.* TO 'old_user'@'localhost';
mysqldump 导出存储过程时漏掉 ROUTINES 参数导致导入失败
mysqldump 默认不导出存储过程和函数,只导表结构和数据。没加 --routines 就直接导入,CALL proc_name() 会报 PROCEDURE not exists。
- 导出命令必须显式带上
--routines --no-create-info(后者可选,避免重复建表) - 若过程里用了
PREVIEWS或JSON_TABLE等 8.0 新语法,5.7 导出的CREATE PROCEDURE语句在 8.0 导入可能报错,需人工检查替换 - 注意
--skip-triggers和--routines是独立开关,别误以为开了前者就自动包含后者
8.0 的 mysql.proc 表废弃,但 dump 文件里还引用它
5.7 的 mysqldump 生成的 routine dump 会包含类似 INSERT INTO mysql.proc ... 的语句,而 8.0 已移除该表,导入直接失败,错误信息是 Table 'mysql.proc' doesn't exist。
- 不要用 5.7 的
mysqldump直接往 8.0 导;务必用目标版本的客户端工具导出:即 8.0 升级后,用 8.0 的mysqldump连 5.7 实例(支持跨版本导出) - 或者改用
SELECT body FROM mysql.proc WHERE db='xxx' AND name='yyy'\G手动提取逻辑,重写为标准CREATE PROCEDURE语句 - 8.0 中过程元数据存在
information_schema.routines,但它是只读视图,不能用于恢复
字符集与排序规则不一致引发过程内部字符串比较异常
比如过程里写 IF @a = '测试' THEN,在 5.7 是 utf8mb4_general_ci,8.0 默认是 utf8mb4_0900_as_cs(大小写敏感),导致条件恒为 false。
- 导出前确认源库过程定义里的字符集声明,例如
CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs是否被硬编码 - 导入前在目标库执行
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;可临时缓解,但治标不治本 - 真正安全的做法是在过程体中显式指定 collation:
IF @a COLLATE utf8mb4_unicode_ci = '测试' THEN
过程迁移不是“dump + source”就能完事的事——DEFINER、元数据表路径、字符序行为、甚至空格和注释解析,在两个版本间都有静默差异。最容易被跳过的,是用错版本的 mysqldump 客户端。


















