mysql开启binlog时要求函数必须显式声明数据访问行为,否则报错1418;合法声明仅deterministic、no sql、reads sql data三种;推荐优先使用deterministic,或配置log_bin_trust_function_creators=1临时绕过。

这个报错不是函数写错了,而是MySQL在二进制日志(log_bin=ON)开启时的强制安全校验——你没告诉它这个函数到底会不会影响数据一致性。
为什么CREATE FUNCTION会触发ERROR 1418
MySQL要求所有函数必须显式声明数据访问行为,否则拒绝创建。根本原因是:主从复制依赖binlog重放,如果函数行为不透明(比如内部调用NOW()或RAND()),从库执行结果可能和主库不一致。
- 报错信息里的
DETERMINISTIC、NO SQL、READS SQL DATA是仅被允许的三种声明(MODIFIES SQL DATA和CONTAINS SQL在函数中不被接受) - 哪怕函数只做加法(如
RETURN i1 + i2),也必须加声明,不能靠MySQL自动推断 - 该限制在 MySQL 5.0+ 全版本生效,8.0.30 同样适用
直接加DETERMINISTIC声明最稳妥
如果你确认函数输出完全由输入参数决定(无时间、随机、查询、变量等副作用),就在 CREATE FUNCTION 语句里补上 DETERMINISTIC。
DELIMITER $$ CREATE FUNCTION my_sum(i1 INT, i2 INT) RETURNS INT DETERMINISTIC BEGIN RETURN i1 + i2; END$$ DELIMITER ;
- 不要写成
NOT DETERMINISTIC—— 这是无效语法,MySQL只认DETERMINISTIC或不写(不写就触发报错) - 含子查询、表访问、
SELECT ... INTO的函数,必须用READS SQL DATA - 纯计算、字符串处理、数学运算类函数,
DETERMINISTIC是首选
临时绕过检查:set global log_bin_trust_function_creators=1
这条命令能立刻让MySQL跳过函数安全性检查,但只是会话级临时方案,重启失效,且存在复制风险。
- 执行前需有
SUPER权限(普通用户可能无权执行) - 命令是
SET GLOBAL log_bin_trust_function_creators = 1,注意中间无下划线 - 验证是否生效:
SHOW VARIABLES LIKE 'log_bin_trust_function_creators';返回ON或1 - 生产环境不建议长期依赖此方式,尤其当函数用于主从复制链路时
永久生效要改配置文件
想一劳永逸,就得修改 MySQL 配置文件,否则每次重启服务都要重设。
- 编辑
/etc/my.cnf(Linux)或my.ini(Windows),在[mysqld]段落下添加一行:log_bin_trust_function_creators=1 - 注意不是
log-bin-trust-function-creators(带短横线是旧版错误写法) - 改完必须重启 MySQL:
systemctl restart mysqld或service mysql restart - 该设置对所有新建函数生效,但不会修复已存在的未声明函数
真正要注意的是:声明必须和函数实际行为严格一致。标了 DETERMINISTIC 却用了 UUID() 或 (SELECT ...),后期调用时可能出错或导致主从数据不一致——这比建不成功更难排查。











