该错误表示DEFINER用户在当前MySQL实例中不存在,常见于跨环境导入、用户删除未清理对象、mysqldump未处理DEFINER及升级后认证插件变更等场景;需用SHOW CREATE或information_schema定位问题对象,修复可选重建(自动设当前用户)或ALTER VIEW重置DEFINER,预防应使用--skip-definer导出并统一约定CURRENT_USER。

这个错误意味着视图、存储过程或函数的 DEFINER 用户在当前 MySQL 实例中不存在,MySQL 拒绝执行它——不是权限问题,是用户账号根本查无此人。
为什么 DEFINER 会“消失”?
常见于以下场景:
- 从其他环境(如测试库、旧生产库)导入 SQL 时,
CREATE VIEW或CREATE PROCEDURE语句里写了类似DEFINER=`admin`@`192.168.%`,但目标库没这个用户 - DBA 删除了原 DEFINER 账号,但忘了清理依赖它的数据库对象
- 使用
mysqldump --routines --triggers导出后,在新实例上直接 source,而新实例未提前创建对应用户 - MySQL 升级或迁移后,
mysql.user表未同步,或认证插件变更导致旧账号不可见(如caching_sha2_passwordvsmysql_native_password)
快速定位是哪个对象触发报错
不要靠猜。先确认报错发生在哪条语句上,再查对应对象:
- 如果报错来自
SELECT * FROM my_view,运行:SHOW CREATE VIEW `my_view`;
查看DEFINER字段 - 如果是调用存储过程失败,运行:
SELECT ROUTINE_NAME, DEFINER FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = 'your_db';
- 通用排查(所有含 DEFINER 的对象):
SELECT CONCAT('VIEW: ', TABLE_NAME) AS obj, DEFINER FROM information_schema.VIEWS WHERE DEFINER NOT IN (SELECT CONCAT(User,'@',Host) FROM mysql.user) UNION ALL SELECT CONCAT('PROCEDURE: ', ROUTINE_NAME), DEFINER FROM information_schema.ROUTINES WHERE DEFINER NOT IN (SELECT CONCAT(User,'@',Host) FROM mysql.user);
修复方式:改 DEFINER 还是删对象?
取决于对象是否必要、是否可重写。优先选安全、低侵入的方式:
- 若对象可重建且你有
CREATE权限:
– 先DROP VIEW/PROCEDURE/FUNCTION
– 再用不带DEFINER的语句重建(MySQL 会自动设为当前用户)
– 或显式指定存在的用户,例如:CREATE DEFINER=`root`@`localhost` VIEW ... - 若不能删(如生产关键视图),必须修改 DEFINER:
– 直接更新mysql.proc(存储过程)或mysql.views(视图)表(MySQL 5.7+)
– 但注意:修改系统表前需FLUSH PRIVILEGES,且 8.0+ 已移除mysql.views,只能用ALTER VIEW ... SQL SECURITY DEFINER替代
– 更稳妥做法:CREATE OR REPLACE VIEW your_view AS SELECT ...; -- 会重置 DEFINER 为当前用户
- 临时绕过(仅调试):
– 启动时加参数--skip-grant-tables(不推荐线上用)
– 或设置sql_mode='NO_ENGINE_SUBSTITUTION'无效,此错误与 sql_mode 无关
预防下次再出问题
导出和部署环节最容易埋雷:
- 用
mysqldump时加--skip-definer参数,避免导出DEFINER子句 - 部署前检查目标库是否存在
SELECT CONCAT(User,'@',Host) FROM mysql.user;,对比导出文件里的所有DEFINER - 团队约定统一用
DEFINER=CURRENT_USER创建对象(需 MySQL 5.7.6+),这样迁移时自动适配执行者身份 - 注意:MySQL 8.0 默认关闭
log_bin_trust_function_creators,若涉及函数,还需额外授权或开启该变量
最常被忽略的一点:即使你用 root@localhost 登录,DEFINER 写的是 root@127.0.0.1,也会报错——MySQL 认为这是两个不同用户,host 匹配必须精确。


















