error 1418 或 1370 根源是 definer 用户缺失、权限不足(含 system_variables_admin)或 sql security 设置不当;须先用 show create function 查 definer 和 security 类型,再验证用户存在性及对所有涉及库表、系统变量的权限,优先修复 definer 权限而非改 security 模式。

函数调用报 ERROR 1418 或 ERROR 1370,基本不是调用者缺权限,而是 DEFINER 用户不存在、权限不全,或 SQL SECURITY 设置与实际环境冲突——直接改调用者权限没用,得先定位定义者身份。
查清函数的 DEFINER 和 SQL SECURITY 类型
执行 SHOW CREATE FUNCTION function_name;,重点看两处:DEFINER=`user`@`host` 和 SQL SECURITY DEFINER(默认值)。如果没写 SQL SECURITY,MySQL 就按 DEFINER 模式运行。
- 若返回中
DEFINER是'nobody'@'%'这类明显不存在的用户,问题根源就在这里 -
SQL SECURITY INVOKER表示函数以当前连接用户身份执行,此时才需要检查调用者权限 - 注意:MySQL 8.0+ 中,函数若读取系统变量(如
@@version),DEFINER还必须有SYSTEM_VARIABLES_ADMIN权限
验证 DEFINER 用户是否存在且权限完整
用 SELECT User, Host FROM mysql.user WHERE User = 'user'; 确认该用户是否真实存在。若不存在,要么重建用户,要么改函数定义者;若存在,再查权限:
- 执行
SHOW GRANTS FOR 'user'@'host';,确认其拥有函数体里所有表的SELECT/UPDATE等操作权限 - 特别注意:函数内若有跨库查询(如
SELECT * FROM other_db.table),DEFINER必须对other_db也有对应权限 - MySQL 8.0+ 必须包含
SYSTEM_VARIABLES_ADMIN(不是SUPER)才能访问大多数系统变量
修复 DEFINER 权限比改 SQL SECURITY 更安全
优先修 DEFINER 用户权限,而不是把函数改成 INVOKER——后者要求每个调用者都得被单独授权,运维成本高且易漏。
- 用高权限账号(如
root)执行:GRANT SELECT ON target_db.target_table TO 'definer_user'@'%'; - 若涉及系统变量:
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'definer_user'@'%'; - 不要用
GRANT ALL PRIVILEGES,最小化授予函数实际用到的权限 - 改完立即测试:
SELECT function_name();,别等应用报错才验证
Docker 或云数据库环境下容易忽略的点
在容器或 RDS 中,DEFINER 用户可能被限制创建,或 log_bin_trust_function_creators 默认关闭,导致函数根本无法创建或调用失败。
- Docker 启动时加参数:
-e MYSQL_ROOT_PASSWORD=xxx,进容器后手动建DEFINER用户并授必要权限 - 云数据库(如阿里云 RDS)通常禁用
SUPER,但允许设置log_bin_trust_function_creators=1(需控制台开关或工单申请) - 若函数含非确定性函数(如
NOW()、UUID()),MySQL 8.0+ 要求log_bin_trust_function_creators=1才能创建,否则报ERROR 1418
最常被跳过的动作是:查了 SHOW CREATE FUNCTION 却没验证 DEFINER 用户是否存在,或者验证了存在却没查它对函数内涉及的**所有库表和系统变量**是否真有权限——尤其是跨库引用和 @@ 变量,这两处一漏,函数就静默失败。











