MySQL报ERROR 1418是因开启binlog后未在CREATE FUNCTION中声明DETERMINISTIC、NO SQL或READS SQL DATA特性,触发复制安全校验;应修正函数定义而非依赖log_bin_trust_function_creators=1。

MySQL报ERROR 1418是因为开了binlog但没声明函数特性
只要log_bin=ON(主从、备份、审计等场景基本都开),MySQL就会强制校验每个CREATE FUNCTION语句是否显式声明了安全性行为。没声明就直接拒绝,报错信息里那句“This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA”就是核心提示——它不是权限不足,也不是语法错,而是复制安全机制在拦截。
临时设log_bin_trust_function_creators=1能绕过,但有硬性前提
执行SET GLOBAL log_bin_trust_function_creators = 1确实能让函数创建或mysqldump导入通过,但必须满足:
- 当前账号拥有
SUPER权限(普通root在MySQL 8.0+默认不带这个权限) - 该设置仅对当前实例生效,MySQL重启后自动变回
0 - 如果提示
ERROR 1227 (42501): Access denied; you need SUPER privilege,说明权限不够,别反复重试
真正该改的是函数定义本身,不是配置
在CREATE FUNCTION语句中补上DETERMINISTIC、NO SQL或READS SQL DATA三者之一,才是生产环境该走的路:
-
DETERMINISTIC:适用于纯计算类函数(如my_add(a,b)),但若函数内用了NOW()、RAND()或子查询结果不确定,标这个会引发主从数据不一致 -
READS SQL DATA:适用于只查表不改数据的函数(比如根据ID查姓名),这是最常见也最稳妥的选择 -
NO SQL:适用于完全不碰数据库的函数(比如只调CONCAT()、DATE_ADD()),实际使用较少
注意:MODIFIES SQL DATA和CONTAINS SQL在函数中不被允许,只能用于存储过程。
配置文件里加log_bin_trust_function_creators=1是危险操作
在my.cnf的[mysqld]段写死这个参数,看似一劳永逸,但等于永久关闭MySQL对函数安全性的校验。一旦有人误写了一个非确定性函数并上线,主库和从库执行结果可能不同,而你根本不会收到任何告警。这个开关只适合开发机或CI环境,绝不该出现在生产主库的配置里。
真正容易被忽略的点是:函数声明特性必须和实际行为严格一致——哪怕只是多写了一个SELECT NOW(),就不能标DETERMINISTIC;否则不是报错,而是埋下数据漂移的隐患。


















