Mysql 主从服务器遭遇Error_code: 1418

在MySQL的主从复制过程中遇到Error_code:1418错误,原因是存储过程或函数在从服务器执行时可能造成数据不一致。解决方法是设置全局变量log_bin_trust_function_creators为1,或者在配置文件中添加该参数,允许不安全的存储函数创建。这将允许从服务器正确执行包含不确定子程序的事务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        上周在MHA架构中,测试通过存储过程构建大量的数据,在主服务器执行存储过程后,从服务器的日志和slave状态中看到异常错误,日志文件抛出Error_code: 1418代码,记录下解决办法。

错误日志:

2021-08-16T01:25:52.924913Z 32 [Note] Slave SQL thread for channel '' initialized, starting replication in log 'mysql-bin.000011' at position 12828, relay log './rac2-relay-bin.000022' position: 13001
2021-08-16T01:25:52.925756Z 33 [ERROR] Slave SQL for channel '': Worker 1 failed executing transaction '5ed107db-f4f8-11eb-8c05-0050568f8774:152' at master log mysql-bin.000011, end_log_pos 13393; 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: 'db'. Query: 'CREATE DEFINER=`root`@`localhost` FUNCTION `randstring`(n int) RETURNS varchar(255) CHARSET latin1
begin
declare all_str varchar(100) default 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ;
declare return_str varchar(255) default '' ;
declare i int default 0 ;
while i<n
do
set return_str = concat( return_str, substring(all_str, floor(1+rand()*52) ,1) ) ;
set i=i+1 ;
end while ;
return return_str ;

end', Error_code: 1418
2021-08-16T01:25:52.925828Z 32 [Warning] Slave SQL for channel '': ... The slave coordinator and worker threads are stopped, possibly leaving data in inconsistent state. A restart should restore consistency automatically, although using non-transactional storage for data or info tables or DDL queries could lead to problems. In such cases you have to examine your data (see documentation for details). Error_code: 1756
2021-08-16T01:25:52.925923Z 32 [Note] Slave SQL thread for channel '' exiting, replication stopped in log 'mysql-bin.000011' at position 12828
造成的原因:
    在mysql中,CREATE PROCEDURE, CREATE FUNCTION, ALTER PROCEDURE,ALTER FUNCTION,CALL, DROP PROCEDURE, DROP FUNCTION等语句都会被写进二进制日志,然后在从服务器上执行。但是,一个执行更新的不确定子程序(存储过程、函数、触发器)是不可重复的,在从服务器上执行(相对与主服务器是重复执行)可能会造成恢复的数据与原始数据不同,从服务器不同于主服务器的情况。

解决办法:设置log_bin_trust_function_creators=1或者将该参数加入到/etc/my.cnf配置文件中

mysql> stop slave;
Query OK, 0 rows affected (0.04 sec)

mysql> set global log_bin_trust_function_creators=on;
Query OK, 0 rows affected (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected (0.12 sec)

        关于log_bin_trust_function_creators,它控制是否可以信任存储函数创建者,不会创建写入二进制日志引起不安全事件的存储函数。如果设置为0(默认值),用户不得创建或修改存储函数,除非它们具有除CREATE ROUTINE或ALTER ROUTINE特权之外的SUPER权限。 设置为0还强制使用DETERMINISTIC特性或READS SQL DATA或NO SQL特性声明函数的限制。 如果变量设置为1,MySQL不会对创建存储函数实施这些限制。 此变量也适用于触发器的创建。

<think>好的,用户现在遇到了MySQL主从复制断开的问题,并且提供了报错信息。我需要先仔细分析报错内容,然后一步步解决。首先,错误信息显示是Worker 1执行事务时失败,关键错误是1062,也就是重复主键的问题。主键'63b5c615-657e-420a-a862-4caf987af693'已经存在,导致从库无法插入数据,从而复制中断。 接下来,我需要考虑可能的原因。常见的原因包括主库和从库数据不一致,比如主库插入了一条数据,但从库已经有了相同主键的记录。或者可能是在主库上做了手动修改,比如跳过某些错误,导致主从数据不同步。此外,主键冲突可能也跟自增ID设置不当有关,但这里的主键是UUID,所以可能不是自增的问题,而是应用层生成UUID时出现了重复,或者之前有数据被手动插入到从库,导致主库的数据过来时冲突。 然后,用户可能需要解决这个问题的方法。通常的步骤是:首先跳过这个错误,让复制继续,然后检查数据一致性,最后防止问题再次发生。跳过错误的方法有几种,比如使用SQL_SLAVE_SKIP_COUNTER或者手动设置GTID_NEXT。不过需要注意,跳过错误后可能会有数据不一致,需要后续检查和修复。 另外,用户可能需要检查为什么会出现重复主键。如果是应用层生成UUID的问题,需要确保UUID生成机制是可靠的,不会产生重复。如果是人为操作导致从库数据不一致,可能需要规范操作流程,避免直接修改从库数据。 在回答时,需要结构清晰,分步骤说明解决方法,同时解释原因,并给出预防措施。还要注意使用中文,技术术语正确,比如GTID、二进制日志位置等。同时,提醒用户谨慎操作,因为跳过错误可能会导致数据不一致,建议在操作前备份数据。</think>### 问题定位与分析 根据报错信息,MySQL主从复制中断的直接原因是 **主键冲突(Error 1062)**。具体表现为: - **从库(Slave)** 尝试执行主库(Master)同步的事务时,发现表 `news.sn_news_details_logs` 的主键(`PRIMARY`)已存在值为 `63b5c615-657e-420a-a862-4caf987af693` 的记录。 - **根本原因**:主库和从库的数据已不一致,可能是由于: 1. 主库或从库被手动修改(如直接写入从库导致数据冲突)。 2. 主从复制延迟期间,主库删除了某条数据但从库未及时同步。 3. 主键生成规则不严格(例如UUID重复或业务逻辑缺陷)。 --- ### 解决步骤 #### 1. **临时恢复主从同步** **方法一:跳过当前错误事务(推荐)** ```sql -- 在从库执行: STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -- 跳过1个错误事件 START SLAVE; ``` - **注意**:若使用GTID模式,需改用以下命令: ```sql STOP SLAVE; SET GTID_NEXT='16bfe30c-69e0-11ee-8a43-002ec71f9a38:22898637'; -- 替换为报错中的事务ID BEGIN; COMMIT; SET GTID_NEXT='AUTOMATIC'; START SLAVE; ``` **方法二:手动删除冲突数据** ```sql -- 在从库删除冲突记录(需谨慎确认数据归属): DELETE FROM news.sn_news_details_logs WHERE primary_key_column = '63b5c615-657e-420a-a862-4caf987af693'; START SLAVE; ``` --- #### 2. **检查数据一致性** 通过工具(如 `pt-table-checksum`)对比主从库数据差异: ```bash pt-table-checksum --host=主库IP --user=校验用户 --password=密码 --databases=news ``` - 若发现不一致,使用 `pt-table-sync` 修复数据。 --- #### 3. **防止问题复现** - **禁止直接写入从库**:确保从库配置为只读模式: ```sql SET GLOBAL read_only = ON; ``` - **规范主键生成**:若主键为UUID,需确保生成逻辑唯一性(如使用 `UUID_SHORT()` 或应用层强校验)。 - **启用自动容错机制**:在从库配置文件(`my.cnf`)中添加: ```ini slave_skip_errors = 1062 -- 跳过重复键错误(慎用,仅限临时应急) ``` --- ### 补充说明 | 关键参数 | 含义 | |-----------------|----------------------------------------------------------------------| | `LAST_ERROR_MESSAGE` | 最后一次复制错误的具体描述,需重点关注主键、唯一键冲突或数据丢失。 | | `GTID` | 全局事务标识符,用于精确定位复制事件(格式:`server_uuid:事务ID`)。 | | `mysql-bin.xxxx` | 主库的二进制日志文件,记录所有数据变更操作。 | --- ### 注意事项 - **跳过错误可能引发数据不一致**,需事后校验修复。 - 若频繁出现主键冲突,需彻底排查业务逻辑或数据库设计缺陷。 如需进一步分析,请提供主从库的 `SHOW SLAVE STATUS\G` 完整输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值