数据恢复咨询热线:400-666-3702  

欢迎访问南京兆柏数据恢复公司,专业数据恢复15年

兆柏数据恢复公司

 常见问题

 当前位置: 主页 > 常见问题

MySQL引发的监控问题

浏览量: 次 发布日期:2023-10-11 19:28:35

​MySQL引发的监控问题

  一个线上的小案例

  微信公众号:DBA随笔

  今天在线上发现一个问题,挺有意思的,这里简单记录下。问题的背景是查看一个Grafana监控的时候,发现监控没有数据了:

  从图中可以看到4月1日之后,监控就没有输出数据了。

  于是决定排查一下这个问题。排查思路如下:

  1、监控数据源配置是否准确;

  2、监控数据是否采集完整;

连云港数据恢复

  3、监控数据所在数据库是否可以访问;

  经过查看,监控数据从4月开始就缺失了,由于监控数据采集程序的日志不够全面,所以花了很长时间才定位到根本原因:监控数据写入数据库的时候,报错了。

  其实报错信息也比较简单,如下:

  这个明眼人一看,就是主键冲突了,冲突的id值是4294967295。那就开始排查主键冲突的问题吧。1、表结构查看

  首先查看表结构,看着似乎没什么异样,如下:

  2、查看数据

  这里找到上面的报出冲突的自增id值,发现是4294967295 ,然后使用select语法来查看这个id对应的数据是否存在:

  发现这条数据也在表里面。

  于此同时,发现这个表结构里面的auto_increment值也是4294967295

  这就比较奇怪了,自增id一般都会是当前表中id最大值的下一个id值,例如表中最大id是10,自增id的值应该是11.

  为什么这个自增id和表里面的最大id值一样?(可能有的小伙伴已经知道答案了,但是排查的时候,我确实没反应过来)3、数据修复

  先尝试手动delete这条id=4294967295冲突的数据,再重新插入id=4294967295新的数据,看看能不能恢复吧。

  结果是:

  删除后重新插入id=4294967295不报错,但是后续的新数据插入时候又报如下错误:

  似乎没解决问题。

  既然id=4294967295的数据冲突,那我们把这个id加1,看看手工插入一条数据能不能行:

  不得不说,这个输出的结果有很大的误导意义

  注意,我们插入的数据是id=4294967296,但是报错还是显示id=4294967295,死活就跟这条数据过不去了!!!

  (这里我以为我发现了什么惊天大bug,喊来两个同事,一起看看这个问题。)

  再次删除id=4294967295的数据,插入id=4294967296的数据:

  我去,没有了那个坏id的数据,后面的id终于也能插入了???等等,有个warning(同事提醒),看下:

  好吧,MySQL已经给出了答案了:id是int 类型的,这个自增值溢出了。

  找个测试表试试

  到这里,这个问题的原因就算找到了,也能稳定复现这个问题。

  使用alter table语句,将这个线上表的主键id列改为bigint类型的即可。

  测试环境看一发:

  从结果中不难看出来,这个操作不能online,会拷贝表里面所有的数据。

  线上重要表的操作最好使用pt-osc工具或者gh-ost工具执行。

  这里再给一个不同类型的id范围的表:

  说实话,这些范围边缘数据,平时不注意的话,看到了可能也反应不过来,如果你够细心,对它们很敏感,可能这个问题一分钟就解决了,根本不需要排查。

  最终,监控数据也回来了。

  修复前:

  修复后:

  上述情况是在MySQL 5.5 版本上操作的,MySQL8.0中会不会有所改善。

  看来MySQL8.0对于这种情况,支持的友好一点。

  当表里面有最大id的情况下,插入一个更大的id:MySQL5.5会报最大的id冲突,有一定的误导;MySQL8.0直接报错,更严谨;

  当表里没有最大id值,但是自增id为最大id值,插入一个更大的id,MySQL5.5会插入成功,但是发生数据截断,提示warning;MySQL8.0会直接报错,更严谨。

  综上,升级MySQL8.0吧。

  今天就这么多,睡觉了。

相关推荐