报错内容
2016-04-29 00:09:57 9242 [ERROR] Slave SQL: Error ‘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)‘ on query. Default database: ‘epsp_db‘. Query: ‘CREATE DEFINER=`unionpayb2b`@`%` FUNCTION `currval`(v_seq_name VARCHAR(50)) RETURNS int(11) BEGIN DECLARE val,val1 INTEGER; SET val = 0; SELECT current_val INTO val1 FROM tbl_sequence WHERE seq_name = v_seq_name; IF (val1 IS NULL)THEN INSERT INTO tbl_sequence VALUES(v_seq_name,0,1); ELSE SET val=val1; END IF; RETURN val; END‘, Error_code: 1418 2016-04-29 00:09:57 9242 [Warning] Slave: 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) Error_code: 1418 2016-04-29 00:09:57 9242 [Warning] Slave: Failed to CREATE FUNCTION currval Error_code: 1307 2016-04-29 00:09:57 9242 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log ‘mysql-bin.000002‘ position 326441 2016-04-29 00:10:01 9242 [Note] /data/mysql/base/bin/mysqld: Normal shutdown
错误分析1
根据错误信息得知由于创建的这个函数对数据的操作对于replication场景,存在不确定性,也就是说这个函数在主库和从库上执行可能产生不一样的结果。 所以该函数在从库应用时产生了错误,并导致从库sql apply中断,错误信息中也记录了中断的文件及对应的position点
错误分析2
根据错误信息给出的提示,可能需要设置log_bin_trust_function_creators这个变量来解决这个错误 通过查询官方文档,得知了该参数的含义: log_bin_trust_function_creators 这是一个安全参数,针对于主从复制时对于函数和触发器的处理,默认值为0,表示不允许对数据操作存在不确定性的函数和触发器的创建,因为这类语句会导致主从数据不一致的情况发生。 同时官方文档对这类语句产生不一致的场景进行了进一步说明: 通常二进制日志设置为statement或mixed格式时会出现这种情况,如果是row格式则不会,因为row格式不是记录的对这个函数的调用语句,而是记录的函数调用后对行的改变的记录。 同样对于触发器也是一样。所以在基于row格式的情况下不会发生这种不一致的情况。 mixed格式虽然会根据不同的情况动态的使用statement或row格式,但对于函数和触发器,mixed总是使用statement方式进行记录,所以基于mixed格式也会存在这种问题。 官方链接说明: https://dev.mysql.com/doc/refman/5.7/en/stored-programs-logging.html
解决办法
[master/slave]修改二进制日志格式为row格式 [master/slave]修改log_bin_trust_function_creators参数,将其设置为1 SET GLOBAL log_bin_trust_function_creators = 1; 可以在创建主从时直接使用row格式进行复制,不会出现该问题,如果不用基于row格式的复制,则提前启用该参数,避免主从复制时函数或触发器导致从库复制中断的问题,但由于该参数开启后,如果不是基于row格式的复制,很难保证当执行相关自定义的函数时,对数据的操作在主从上是一致的,存在不确定性,这也是为什么MySQL默认是禁止这类函数和触发器的原因,目的是为了保持主从数据的一致性。所以建议可能的情况下,还是采用基于row格式的复制,避免产生相关错误。
时间: 2024-12-12 23:47:03