ERROR 1418 是 binlog 安全校验错误,非权限问题;须显式声明 DETERMINISTIC/NO SQL/READS SQL DATA,或在 my.cnf 的 [mysqld] 段配置 log_bin_trust_function_creators = ON 并重启生效。

直接结论:ERROR 1418 不是权限错误,而是 MySQL 在开启 binlog 后对函数安全性的强制校验;必须显式声明函数行为(DETERMINISTIC / NO SQL / READS SQL DATA),或启用 log_bin_trust_function_creators 参数——但后者需注意权限与持久性。
为什么 SET GLOBAL log_bin_trust_function_creators = 1 失效?
常见现象是执行了 SET GLOBAL log_bin_trust_function_creators = 1,但创建函数仍报 1418。原因有三:
- 执行者缺少
SYSTEM_VARIABLES_ADMIN权限(MySQL 8.0+)或SUPER权限(旧版),普通用户即使有CREATE ROUTINE也不行 - 该语句只影响当前实例生命周期,MySQL 重启后恢复默认
OFF,不写进配置文件等于白设 - 连接已建立,而变量是全局级,新会话才生效;已有连接不会自动继承变更
my.cnf 中如何正确配置 log_bin_trust_function_creators?
必须在 [mysqld] 段下添加,且需重启 MySQL 才生效:
[mysqld] log_bin_trust_function_creators = ON
注意以下细节:
- 参数名是
log_bin_trust_function_creators,不是log-bin-trust-function-creators或其他变体 - 值可为
ON、1、TRUE,但推荐用ON保持可读性 - 若 MySQL 启用了主从复制,仅对可信账号(如 DBA 或专用部署账号)启用该参数,避免将不可信函数同步到从库引发数据不一致
函数定义中该加哪个特性关键字?
比起依赖配置项,更推荐在 CREATE FUNCTION 语句里显式声明行为,既安全又免配。可用的只有三个:
-
DETERMINISTIC:输入相同则输出必相同,比如ABS(x)、YEAR(NOW())—— 注意:NOW()本身非确定,但若函数逻辑不依赖它的时间部分(如只取年份且上下文固定),仍可声明为DETERMINISTIC,需自行担责 -
NO SQL:函数体内完全不含 SQL 语句,纯计算或调用内置函数(如CONCAT、IF) -
READS SQL DATA:只做SELECT,不修改任何数据;若函数内含INSERT/UPDATE/DELETE,则必须用MODIFIES SQL DATA—— 但该关键字在函数中不被接受,只能用于存储过程;函数不支持写操作声明,所以含写逻辑的函数无法绕过 1418,除非关 binlog 或开信任参数
生产环境最容易忽略的点是什么?
很多人修完函数创建问题,上线后调用时报 ERROR 1370 或静默失败,根源不在函数本身,而在 DEFINER 用户缺失或权限不足。执行 SHOW CREATE FUNCTION func_name; 后重点检查两处:
-
DEFINER=`user`@`host`:该用户是否真实存在?是否拥有函数内所有SELECT所涉库表的权限?跨库查询时,权限要覆盖所有目标库 -
SQL SECURITY DEFINER(默认):函数以DEFINER身份执行,调用者权限无关;若改为SQL SECURITY INVOKER,才需要验证调用者权限 - MySQL 8.0+ 中,若函数读取系统变量(如
@@sql_mode),DEFINER还必须有SYSTEM_VARIABLES_ADMIN权限


















