今天在创建存储函数时,意外的出现的报错,特此记录过程如下:
MySQL的有个参数log_bin_trust_function_creators
,官方文档对这个参数的介绍、解释如下所示:
一、log_bin_trust_function_creators功能介绍
当二进制日志启用
(binlog)后,这个变量就会启用。
它控制是否可以信任存储函数创建者
,不会创建写入二进制日志引起不安全事件的存储函数。如果设置为0(默认值
),用户不得创建或修改存储函数,除非它们具有除CREATE ROUTINE或ALTER ROUTINE特权之外的SUPER权限
。 设置为0还强制使用DETERMINISTIC特性或READS SQL DATA或NO SQL特性声明函数的限制。 如果变量设置为1,MySQL不会对创建存储函数实施这些限制。 此变量也适用于触发器的创建。
二、排查处理过程
2.1 当开启二进制日志后,如果变量
log_bin_trust_function_creators为OFF #那么创建或修改存储函数就会报
###报错信息如下:
“ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)”这样的错误,如下所示:
2.2 查看Mysql参数
mysql> show variables like 'log_bin'; #查看binlog是否开启
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set (0.00 sec)
mysql> show variables like '%log_bin_trust_function_creators%'; #查看选项是否开启
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | OFF |
+---------------------------------+-------+
1 row in set (0.00 sec)
"尝试创建函数,出现报错"
mysql>
mysql> DELIMITER //
mysql> CREATE FUNCTION GET_UPPER_NAME(emp_id INT)
-> RETURNS VARCHAR(12)
-> BEGIN
-> RETURN(SELECT UPPER(NAME) FROM TEST WHERE ID=emp_id);
-> END
-> //
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
mysql>
2.3 在调用存储函数时,也会遇到这个错误,如下测试所示:
mysql> DELIMITER ;
mysql> set global log_bin_trust_function_creators=1; #开启设置
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER //
mysql> CREATE FUNCTION GET_UPPER_NAME(emp_id INT)
-> RETURNS VARCHAR(12)
-> BEGIN
-> RETURN(SELECT UPPER(NAME) FROM TEST WHERE ID=emp_id);
-> END
-> //
Query OK, 0 rows affected (0.00 sec) #成功创建
mysql> SELECT ID,
-> GET_UPPER_NAME(ID)
-> FROM TEST;
-> //
+------+--------------------+
| ID | GET_UPPER_NAME(ID) |
+------+--------------------+
| 100 | KERRY |
| 101 | JIMMY |
+------+--------------------+
2 rows in set (0.00 sec)
mysql> DELIMITER ;
mysql> set global log_bin_trust_function_creators=0; #关闭参数
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT ID,
-> GET_UPPER_NAME(ID) #查询失败
-> FROM TEST;
ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
mysql>
三、报错分析
那么为什么MySQL有这样的限制
呢? 因为二进制日志的一个重要功能是用于主从复制
,而存储函数有可能导致主从的数据不一致
。所以当开启二进制日志后,参数log_bin_trust_function_creators就会生效
,限制存储函数的创建、修改、调用
。那么此时如何解决这个问题呢?官方文档介绍如下,具体可以参考23.7 Binary Logging of Stored Programs
3.1 解决方法一: 取消限制
1: 如果数据库没有
使用主从复制,那么就可以将参数log_bin_trust_function_creators设置为1.
mysql> set global log_bin_trust_function_creators=1;
这个动态设置的方式会在服务重启后失效,所以我们还必须在my.cnf中设置,加上log_bin_trust_function_creators=1,这样就会永久生效。
3.2 解决方法二: 指定函数类型
2:明确指明函数
的类型,如果我们开启了二进制日志, 那么我们就必须为我们的function
指定一个参数。其中下面几种参数类型里面,只有 DETERMINISTIC, NO SQL 和 READS SQL DATA 被支持。这样一来相当于明确的告知MySQL服务器这个函数不会修改数据。
1 DETERMINISTIC 不确定的
2 NO SQL 没有SQl语句,当然也不会修改数据
3 READS SQL DATA 只是读取数据,当然也不会修改数据
4 MODIFIES SQL DATA 要修改数据
5 CONTAINS SQL 包含了SQL语句
mysql> show variables like 'log_bin_trust_function_creators';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | OFF |
+---------------------------------+-------+
1 row in set (0.00 sec)
mysql> DROP FUNCTION GET_UPPER_NAME;
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER //
mysql> CREATE FUNCTION GET_UPPER_NAME(emp_id INT)
-> RETURNS VARCHAR(12)
-> READS SQL DATA #添加此行告诉mysql,我只读取不改变数据。
-> BEGIN
-> RETURN(SELECT UPPER(NAME) FROM TEST WHERE ID=emp_id);
-> END
-> //
Query OK, 0 rows affected (0.01 sec)
mysql> DELIMITER ;
mysql> SELECT ID,
-> GET_UPPER_NAME(ID)
-> FROM TEST;
+------+--------------------+
| ID | GET_UPPER_NAME(ID) |
+------+--------------------+
| 100 | KERRY |
| 101 | JIMMY |
+------+--------------------+
2 rows in set (0.00 sec)
至此解决掉MySQL-log_bin_trust_function_creators 报错。
更多精彩:Mysql相关文章
- QQ精品交流群
-
- 微信公众号
-