ERROR 1418 或 ERROR 1370 根源是函数 DEFINER 用户缺失、权限不足或 SQL SECURITY 设置不当;需先用 SHOW CREATE FUNCTION 查 DEFINER 和 SECURITY 类型,再验证用户存在性、权限完整性(含 SYSTEM_VARIABLES_ADMIN),优先修复 DEFINER 权限而非改 SECURITY 模式。

函数执行报错 ERROR 1418 或 ERROR 1370,基本就是 DEFINER 用户缺失、权限不全,或 SQL SECURITY 设置不当导致的——不是调用者缺权限,而是定义者身份在运行时被校验失败。
查函数当前 DEFINER 和 SECURITY 类型
先确认问题源头,别改错地方。执行:
SHOW CREATE FUNCTION function_name;
重点关注两处:DEFINER=`some_user`@`%` 和 SQL SECURITY DEFINER(默认值)。如果没显式写 SQL SECURITY,MySQL 就按 DEFINER 处理。
- 若
DEFINER用户不存在:用SELECT User, Host FROM mysql.user WHERE User = 'some_user';验证 - 若存在但权限不足:用
SHOW GRANTS FOR 'some_user'@'%';检查是否拥有函数内涉及的表/库/系统变量权限 - MySQL 8.0+ 中,若函数读取系统变量(如
@@version),还需SYSTEM_VARIABLES_ADMIN权限
授 EXECUTE 权限给调用者(仅适用于 SQL SECURITY INVOKER)
如果你明确希望函数以调用者身份执行(即检查当前连接用户的权限),就得把函数改成 SQL SECURITY INVOKER,并确保调用者有函数体里所有操作的权限。
- 重建函数时加声明:
CREATE FUNCTION ... SQL SECURITY INVOKER ... - 然后给调用用户授对应权限,例如函数里查
log_db.audit_log,就得执行:GRANT SELECT ON log_db.audit_log TO 'app_user'@'%'; - 注意:
GRANT EXECUTE ON FUNCTION db_name.func_name TO ...这条只控制“能否调用函数”,不解决函数内部 SQL 的权限问题
修复 DEFINER 用户权限(推荐用于生产环境)
大多数场景下,保持 SQL SECURITY DEFINER 更安全可控——只要确保 DEFINER 用户存在、密码有效、且拥有函数内全部操作所需的最小权限。
- 创建专用运维账号(如
'func_runner'@'%'),避免用root或应用账号当 DEFINER - 授予函数所需权限,例如函数含
INSERT INTO stats.t_daily和SELECT FROM config.settings,就执行:GRANT INSERT ON stats.t_daily TO 'func_runner'@'%';和GRANT SELECT ON config.settings TO 'func_runner'@'%'; - 若函数调用其他存储过程或函数,那些对象的
DEFINER也必须存在且权限完整(嵌套链路要通) - 不要用
CURRENT_USER作 DEFINER,它会随调用者变化,失去一致性
为什么 SET GLOBAL log_bin_trust_function_creators=1 不总管用
这个设置只绕过“函数是否确定性”的校验(比如含 NOW()、UUID() 会被认为非确定性),但它不解决权限问题。即使设了它,仍会报 ERROR 1370 (42000): execute command denied 或 ERROR 1418(后者在旧版中更常见)。
-
log_bin_trust_function_creators=1是为二进制日志服务的,和权限体系无关 - 真正卡住的是运行时权限检查:MySQL 在函数执行瞬间,会以
DEFINER身份去验证每一条 SQL 是否被允许 - 云数据库(如阿里云 RDS)通常禁用该变量修改,你只能老老实实配好 DEFINER 权限
最易被忽略的一点:函数里哪怕只有一行 SELECT @@sql_mode;,在 MySQL 8.0+ 下就必须给 DEFINER 用户 SYSTEM_VARIABLES_ADMIN 权限——不是所有文档都会提这茬,但漏了就必报错。


















