MySQL案例-奇怪的duplicate primary
发表于:2025-11-13 作者:千家信息网编辑
千家信息网最后更新 2025年11月13日,-------------------------------------------------------------------------------------------------记录文
千家信息网最后更新 2025年11月13日MySQL案例-奇怪的duplicate primary-------------------------------------------------------------------------------------------------记录文---------------------------------------------------------------------------------------------------------------
结论先行: 最终只是解决了这个问题, 没有找到根本的原因, 本文只有针对这个问题的分析和思考;
现象:
在Master-5.0.X与Slave-5.7.17进行同步的时候, slave worker抛出了一个错误, duplicate primary;
错误信息如图:
分析:
看上去是个很正常的报错, 主键重复, 出现这个这个问题的可能性有不少, 不过这次的问题比较蹊跷,
因为这个slave是用mydumper新做的, 刚开始同步几条数据就报错, 有点奇怪;
看了一眼表的数据, pk=13的记录确实存在, 那么久看看relaylog, 找一下完整的语句;
找到这个语句以后, 发现事情有点不对(ノへ ̄、)
由于使用了auto_increment作为主键, binlog会在记录这类语句的时候在binlog的statement之前注明主键的具体值;
从binlog的内容来看, 这个语句明显不应该是插入pk=13的记录, 应该是91391才对;
那么如果从Master把这条数据单独导出来, 直接手动导入的话, 跳过这个错误, 也是能解决问题;
看了一眼relaylog, 到导出数据的时候, 都没有再对这条数据进行修改, let's go~
PS: 因为Master的写入很少, 所以才能这么干, 繁重业务的话, 就跳过这种办法吧...
为了保险起见, 新建了一个测试库, 先试一下这么导数据会不会有问题;

把数据导进去看看;

导入没有问题, 而且数据内容也ok, 那么把数据往同步的库里面导入试试.......
(ノへ ̄、)看样子同步报错并不是意外.....
后来还陆陆续续做过以下尝试:
怀疑表有问题, 毕竟从5.0.X的库导入到5.7.17, 所以尝试了: alter表; mysql_upgrade; 检查auto_increament的值;
怀疑使用了假的relaylogㄟ( ▔, ▔ )ㄏ : 重新做同步;
语句有问题(╯‵□′)╯︵┻━┻ : 从已经有这条数据的测试库直接用insert...select来插入数据;
全部都没有用~
最后才把疑点放到这张表的触发器上;
这个触发器是用来做表字符集转换的, 以前在别的数据库中也用到过,这次报错的信息也不是触发器的内容,按道理来说应该是没啥问题的;
不过除了触发器, 好像真没有什么有可能会出问题的地方了, 试着删了这个触发器之后, 发现一切正常了......
最后的解决方法就只能删了所有的触发器;
思考:
首先遇到这个问题的时候, 去查了relaylog, 第一时间的猜测是binlog的问题或者是表的问题,
因为从报错信息里面可以看出来, sql_thread在重演这一条语句的时候, 认为pk=13, 但是binlog里面记录的明显是91391;
那么就有可能是sql_thread在这一块event的时候, 没有认出来这个insert_id=91391的信息, 直接忽略掉了(虽然binlog都是v4, 但是天知道有什么bug不是..),
用了系统自己的auto_increament计数值(因为Master的写入量很少, 考虑到13这个值也不大, 所以产生这种猜测);
所以检查了表的auto_increament值, 也尝试了mysql_upgrade和alter重建表, 但是都没用;
之后发现binlog是statement, 这个语句并没有把所有列的值进行显式的赋值, 而且和后面的另外一条语句组成了一个事务,
如果把完整的信息都列出来, 或者把这个语句拆出来做成一个单独的事务, 是不是就没问题了?
所以之后单独把那一行数据导出来, 再尝试插入到表里面, 不管是source sql文件还是insert...select也不行;
从这几次尝试之后, 基本也能判断不是SQL的问题了;
最后才把注意力放到触发器上面, 这是测试表和业务表唯一的区别, 但是报错里面的信息完全和触发器没关系;
不过在这次出问题的表上, 还是有一些端倪显示出触发器可能有问题, 那就是表自己记录的auto_increament值,
表里面的最大值是91390, 插入失败的数据是91391, 表中记录的auto_increament是91392;
但是发现自己对这方面的了解不多, 也没办法确定这个auto_increament的值是不是查找根本原因的切入点;
路漫漫..... _(:з」∠)_
PS: 源库导出结构的时候, 已经确认源库没有触发器和存储过程, 而且也可以确认5.0.X和5.7的binlog都是v4;
PPPPPPPPPS: 毕竟从5.0.X往5.7做同步不是一个常见的场景, 姑且就当做是跨版本的同步问题吧, 如果能换成row模式的话, 好想看看会不会出问题;
结论先行: 最终只是解决了这个问题, 没有找到根本的原因, 本文只有针对这个问题的分析和思考;
现象:
在Master-5.0.X与Slave-5.7.17进行同步的时候, slave worker抛出了一个错误, duplicate primary;
错误信息如图:
分析:
看上去是个很正常的报错, 主键重复, 出现这个这个问题的可能性有不少, 不过这次的问题比较蹊跷,
因为这个slave是用mydumper新做的, 刚开始同步几条数据就报错, 有点奇怪;
看了一眼表的数据, pk=13的记录确实存在, 那么久看看relaylog, 找一下完整的语句;
找到这个语句以后, 发现事情有点不对(ノへ ̄、)
由于使用了auto_increment作为主键, binlog会在记录这类语句的时候在binlog的statement之前注明主键的具体值;
从binlog的内容来看, 这个语句明显不应该是插入pk=13的记录, 应该是91391才对;
那么如果从Master把这条数据单独导出来, 直接手动导入的话, 跳过这个错误, 也是能解决问题;
看了一眼relaylog, 到导出数据的时候, 都没有再对这条数据进行修改, let's go~
PS: 因为Master的写入很少, 所以才能这么干, 繁重业务的话, 就跳过这种办法吧...
为了保险起见, 新建了一个测试库, 先试一下这么导数据会不会有问题;

把数据导进去看看;

导入没有问题, 而且数据内容也ok, 那么把数据往同步的库里面导入试试.......
(ノへ ̄、)看样子同步报错并不是意外.....
后来还陆陆续续做过以下尝试:
怀疑表有问题, 毕竟从5.0.X的库导入到5.7.17, 所以尝试了: alter表; mysql_upgrade; 检查auto_increament的值;
怀疑使用了假的relaylogㄟ( ▔, ▔ )ㄏ : 重新做同步;
语句有问题(╯‵□′)╯︵┻━┻ : 从已经有这条数据的测试库直接用insert...select来插入数据;
全部都没有用~
最后才把疑点放到这张表的触发器上;
这个触发器是用来做表字符集转换的, 以前在别的数据库中也用到过,这次报错的信息也不是触发器的内容,按道理来说应该是没啥问题的;
不过除了触发器, 好像真没有什么有可能会出问题的地方了, 试着删了这个触发器之后, 发现一切正常了......
最后的解决方法就只能删了所有的触发器;
思考:
首先遇到这个问题的时候, 去查了relaylog, 第一时间的猜测是binlog的问题或者是表的问题,
因为从报错信息里面可以看出来, sql_thread在重演这一条语句的时候, 认为pk=13, 但是binlog里面记录的明显是91391;
那么就有可能是sql_thread在这一块event的时候, 没有认出来这个insert_id=91391的信息, 直接忽略掉了(虽然binlog都是v4, 但是天知道有什么bug不是..),
用了系统自己的auto_increament计数值(因为Master的写入量很少, 考虑到13这个值也不大, 所以产生这种猜测);
所以检查了表的auto_increament值, 也尝试了mysql_upgrade和alter重建表, 但是都没用;
之后发现binlog是statement, 这个语句并没有把所有列的值进行显式的赋值, 而且和后面的另外一条语句组成了一个事务,
如果把完整的信息都列出来, 或者把这个语句拆出来做成一个单独的事务, 是不是就没问题了?
所以之后单独把那一行数据导出来, 再尝试插入到表里面, 不管是source sql文件还是insert...select也不行;
从这几次尝试之后, 基本也能判断不是SQL的问题了;
最后才把注意力放到触发器上面, 这是测试表和业务表唯一的区别, 但是报错里面的信息完全和触发器没关系;
不过在这次出问题的表上, 还是有一些端倪显示出触发器可能有问题, 那就是表自己记录的auto_increament值,
表里面的最大值是91390, 插入失败的数据是91391, 表中记录的auto_increament是91392;
但是发现自己对这方面的了解不多, 也没办法确定这个auto_increament的值是不是查找根本原因的切入点;
路漫漫..... _(:з」∠)_
PS: 源库导出结构的时候, 已经确认源库没有触发器和存储过程, 而且也可以确认5.0.X和5.7的binlog都是v4;
PPPPPPPPPS: 毕竟从5.0.X往5.7做同步不是一个常见的场景, 姑且就当做是跨版本的同步问题吧, 如果能换成row模式的话, 好想看看会不会出问题;
问题
数据
触发器
语句
时候
同步
信息
尝试
内容
错误
测试
明显
业务
事务
办法
原因
根本
还是
面的
分析
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络安全工程师渗透测试岗位
中华人民共和国网络安全法共有
什么存放数据库数据
python常用数据库6
互联网数据库编程题
零基础教你制作数据库
统筹协调网络安全股
建立关系数据库的步骤
对网络安全了解情况
软件开发什么最好就业
网络意识形态包括网络安全吗
通信网络技术实训
java查询大数据数据库
中国的DNS服务器属于哪个公司
支架设计软件开发
鼎合互联网科技有限公司
esi数据库类型
江苏互联网软件开发销售电话
数据库查询慢创建索引
苏州阿里云服务器一键诊断
网络安全新闻app
db2查询数据库
福建师范大学首届网络安全
茂南区汇辉网络技术服务部
软件开发增量的能力
数据库系统概论思维导图第二章
数据库的字典值是什么意思
贵州手机软件开发商
国泰安数据库股权性质缺失
网络技术与云计算技术展望