RC隔离级别强制要求binlog_format=ROW,因MVCC依赖每行最新已提交版本,与STATEMENT日志重放逻辑冲突;RR级别理论上兼容STATEMENT但需规避非确定性函数;MIXED在RC下实际等价于ROW。

这不是函数写错了,是 MySQL 在开启 binlog 后强制校验函数声明
只要你的 MySQL 实例启用了 log_bin(比如主从复制、PITR 备份场景),创建自定义函数时就必须在 CREATE FUNCTION 语句里明确标注行为类型——否则直接报 ERROR 1418 (HY000),根本不会进语法解析阶段。
为什么必须加 DETERMINISTIC / NO SQL / READS SQL DATA
MySQL 要保证主从一致性:如果一个函数在主库返回 100,在从库因 NOW() 或子查询执行时机不同返回 99,binlog 回放就不可靠。所以它只接受三种可安全复制的函数类型:
-
DETERMINISTIC:输出仅由输入参数决定(如ABS(x)),禁止RAND()、UUID()、未限定的子查询 -
NO SQL:函数体内完全不出现任何 SQL 语句(纯字符串/数学运算) -
READS SQL DATA:只允许SELECT,不能INSERT/UPDATE/DELETE
注意:MODIFIES SQL DATA 和 CONTAINS SQL 在函数中不被接受——它们只适用于存储过程或触发器。
set global log_bin_trust_function_creators = 1 为什么无效
这条命令看似简单,但实际生效需要同时满足三个条件,缺一不可:
- 执行账号必须拥有
SYSTEM_VARIABLES_ADMIN权限(SUPER权限在 8.0+ 已被弃用) - 设置后只影响后续新建连接,当前会话不受影响
- MySQL 重启后自动恢复为
0,不是持久化配置
常见误判:执行 SET GLOBAL 返回 Query OK,但立刻查 SELECT @@global.log_bin_trust_function_creators 发现仍是 0——说明权限不足,MySQL 静默忽略该操作。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
my.cnf 配置了 log_bin_trust_function_creators 却不生效
配置文件写法错误是最隐蔽的原因:
- 必须放在
[mysqld]段下,不能写在[client]或其他段 - 变量名必须严格为
log_bin_trust_function_creators(不能带下划线变体、不能拼错) - 值只能是
1或0,不能加引号,不能写成ON/TRUE - Docker 环境要确认挂载路径(如
/etc/mysql/conf.d/custom.cnf),云数据库(RDS/Aurora)需通过控制台参数组修改
验证是否加载成功:启动后执行 SELECT @@GLOBAL.config_file(8.0.25+ 支持),再查 SHOW VARIABLES LIKE 'log_bin_trust_function_creators'。
函数创建失败但 SHOW CREATE FUNCTION 报错或查不到
这是典型因果倒置:报 ERROR 1418 是创建被拒,不代表函数“已存在但隐藏”。更可能是以下两种情况之一:
- 从 5.7 升级到 8.0 时,
mysql.proc表未迁移,函数元数据已丢失,此时改任何配置都无效 -
CREATE FUNCTION语句里写了DEFINER=`xxx`@`%`,但当前用户无权模拟该 definer,导致创建静默失败
先确认函数是否存在:SELECT ROUTINE_NAME FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA = 'your_db' AND ROUTINE_TYPE = 'FUNCTION'。空结果就说明没创建成功,别在配置上反复折腾。
真正麻烦的是那些依赖 NOW() 或 SELECT ... INTO 的函数——它们看起来只读,但 MySQL 不认为 NOW() 是确定性的(除非你手动加 DETERMINISTIC 并承担风险),而 SELECT ... INTO 属于 READS SQL DATA,漏写就会卡死在第一步。

















