报错1418是因binlog开启时mysql强制要求function显式声明deterministic、no sql或reads sql data属性,否则拒绝创建以保障主从一致;常见于工具执行、docker或mysql 8.0+默认启binlog场景。

直接说结论:报错1418不是权限问题,也不是语法写错了,而是 MySQL 在 binlog 开启时强制要求你为存储函数(FUNCTION)显式声明行为属性——否则它拒绝创建,以防主从数据不一致。
为什么 CREATE FUNCTION 会触发 ERROR 1418
只要你的 MySQL 实例开启了 binlog(即 log_bin=ON),而你又没在 CREATE FUNCTION 语句里写 DETERMINISTIC、NO SQL 或 READS SQL DATA 中的任意一个,就会立刻报这个错。这不是“可能出问题”,而是 MySQL 复制机制的硬性校验。
常见触发场景:
- 用 Navicat / DBeaver / SQLyog 等工具执行建函数脚本时弹窗报错
- Docker 启动的 MySQL 默认开启 binlog,本地开发一建函数就崩
- MySQL 8.0+ 新实例默认启用 binlog,新手照着教程复制
CREATE FUNCTION直接失败
三种解法,优先级从高到低
别急着开全局开关,先看函数本身能不能安全标注:
- 如果函数逻辑纯计算(比如
RETURN a * b + 1),不查表、不调系统函数,加DETERMINISTIC最稳妥 - 如果函数只做
SELECT查询(如统计某张表数量),加READS SQL DATA - 如果函数完全不碰数据库(比如字符串处理、日期格式化),加
NO SQL - 避免滥用
DETERMINISTIC:函数里用了NOW()、RAND()、UUID()或子查询,就不能标这个——MySQL 不校验真假,但主从可能不一致
示例(合法且安全):
CREATE FUNCTION calc_discount(price DECIMAL(10,2), rate TINYINT) RETURNS DECIMAL(10,2) DETERMINISTIC BEGIN RETURN price * (1 - rate / 100); END;
log_bin_trust_function_creators=1 怎么设才真正生效
这个变量是“绕过检查”的开关,但它有坑:
-
SET GLOBAL log_bin_trust_function_creators = 1只对后续新连接生效,当前会话已报错不会回滚 - 需要
SYSTEM_VARIABLES_ADMIN或SUPER权限,普通CREATE ROUTINE权限不够 - MySQL 重启后失效,必须写进配置文件才持久:在
my.cnf的[mysqld]段加一行log-bin-trust-function-creators=1(注意是短横线,不是下划线) - 生产环境慎用:一旦开启,任何用户都能创建未声明属性的函数,binlog 重放时可能产生不可预期结果
容易被忽略的关键点
很多人试了 DETERMINISTIC 还是报错,原因常是:
- 漏写了空格或换行,导致 MySQL 解析失败(比如
DETERMINISTICBEGIN连在一起) - 函数体里实际调用了非确定性函数(如
SYSDATE()),但你强行标了DETERMINISTIC—— MySQL 不拦,但从库执行结果会不同 - 用的是存储过程(
PROCEDURE)却套用函数(FUNCTION)的规则:过程不用标这些属性,但函数必须标 - MySQL 8.0.23+ 对
SQL SECURITY也有联动影响,如果函数里涉及视图或 DEFINER 权限,不配好也会间接触发 1418 类似行为











