MySQL案例-奇怪的duplicate primary
发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,-------------------------------------------------------------------------------------------------记录文
千家信息网最后更新 2025年02月01日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安全错误
数据库的锁怎样保障安全
数据库某个字段null
世界十大云数据库排行榜
蔬东坡软件开发
数据库安装提示挂起
福建信息技术会考数据库管理
数据库的安全机制管理实验原理
vue音乐怎么播放数据库音乐
网络技术有哪些定义
终焉誓约手游服务器叫什么
mybatis查询数据库
退出服务器登录
将文件写入数据库
税控服务器管理在哪里
中国人民国网络安全法
河北软件开发价格走势
南京现代软件开发产业化
软件开发高中会学吗
排队叫号系统软件开发
舟山手机游戏软件开发
佛山家政软件开发报价
东城区正规软件开发调试
盛立金融软件开发招聘
数据库客户档案
网络安全入门学什么语言
网站开发数据库问题
信息技术网络安全教育教案
linux查看服务器安装的软件
华为云盘无法连接服务器
人工智能网络安全哪个工资高
网络技术教学基础课