现象

公司云平台不少用户反馈创建存储过程,触发器失败。
普通用户(无SUPER,具备trigger,create routine权限)执行创建存储过程,函数,触发器操作均会报如下错误:

ERROR 1419 (HY000): You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)

存储过程,函数,触发器背景:

存储过程,函数,触发器作为拖垮数据库性能的三大组件,往往由于其内部复杂的SQL逻辑,计算公式,开发人员不规范的编码,组件数量过多而导致需要损耗额外的CPU,MEM,IO资源。从设计的规范角度考虑也不应该将这些复杂的逻辑放在数据层实现。所以绝大多数团队已禁用了这三组件。

在MySQL主从复制中,基于binlog_format=row的模式下,对使用存储过程,函数,触发器也有诸多限制,因为这三组件很可能导致主从数据不一致。可以参考:https://dev.mysql.com/doc/refman/5.7/en/stored-programs-logging.html

主从复制中会遭遇问题的语法汇总:

https://dev.mysql.com/doc/refman/5.7/en/replication-features.html


解决方法:

1.用具有SUPER权限的用户执行

2.设置log_bin_trust_function_creators=1

3.设计角度优化,尽量将存储过程,函数,触发器的实现逻辑移到业务层


通过方法1

创建存储过程,函数时,也必须指定DETERMINISTIC, NO SQL, or READS SQL DATA等参数,声明该存储函数不会对数据进行更改。如果不声明,则会报如下的错:

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_creatorsvariable)

创建触发器则不需要指定,因为触发器本身就是修改数据的。根据官方描述,在binlog_format=row模式下,触发器的主从复制不会出现问题

注:

  • DETERMINISTIC 确定的

  • NO SQL 没有SQl语句,当然也不会修改数据

  • READS SQL DATA 只是读取数据,当然也不会修改数据

样例:

错:

DELIMITER ;;create function func_test(id int) returns varchar(20)begindeclare a varchar(20);select account into a from user where userid=id;return a;end;;

对:

DELIMITER ;;create function func_test(id int) returns varchar(20)READS SQL DATAbegindeclare a varchar(20);select account into a from user where userid=id;return a;end;;

也就是说,只有不修改数据的存储过程和函数才允许被创建~~~


通过方法2

set global log_bin_trust_function_creators=1

必须同时设置主库和从库,并且修改my.cnf配置文件使其持久化。MySQL 开启了binlog模式下,此参数才有效,在binlog开启模式下,会对存储过程,函数的安全性检查,杜绝创建会对数据修改的存储过程和函数,从而造成binlog不安全,导致主从数据不一致。如果设置log_bin_trust_function_creators=1,则表示mysql会信任所有不安全的存储过程和函数。根据官方文档描述,仅在单实例下,可以开启该参数。在主从模式下,除非存储过程,函数的开发人员是具备充足的开发经验人员~~你是吗MySQL中存储过程,函数,触发器须知_javaMySQL中存储过程,函数,触发器须知_javaMySQL中存储过程,函数,触发器须知_java

If you do not want to require function creators to have the SUPER privilege (for example, if all users with the CREATE ROUTINE privilege on your system are experienced application developers), set the global log_bin_trust_function_creators system variable to 1.https://dev.mysql.com/doc/refman/5.7/en/stored-programs-logging.html

综上,各个公司云平台策略不一致,一般建议用户使用方法3,如果无法优化必须创建则使用方法1去创建存储过程,函数,触发器。如果不打算将SUPER权限暴露给用户,建议在平台运维端由运维人员手动创建。