V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
vm97
V2EX  ›  MySQL

mysql 自增 ID 突然变为 int 最大值问题

  •  
  •   vm97 · 33 天前 · 4701 次点击
    这是一个创建于 33 天前的主题,其中的信息可能已经有所发展或是发生改变。

    阿里云 RDS mysql5.7 , 一个几百行的表,突然一条插入的记录自增 ID 成了 2147483647 ,已经排除了无限循环错误写入导致的 ID 自增溢出,或者在插入时错误的带入 ID 值,还有什么可能原因么?

    31 条回复    2025-03-07 21:57:38 +08:00
    rlds
        1
    rlds  
       33 天前
    你可能需要关注下这个
    [img]https://pic2.ziyuan.wang/user/rainerosion/2025/03/1741311183908_c8898ad81d69c.png[/img]
    rlds
        2
    rlds  
       33 天前
    咦,v2 的图片咋显示的来着,,没显示。。
    youngforever
        3
    youngforever  
       33 天前
    用了 INSERT INTO ON DUPLICATE KEY UPDATE 或者 REPLACE INTO ,如果调用频率很高,id 也会变的很大
    cheese
        4
    cheese  
       33 天前
    @rlds #2 只支持几个特定的图床,直接贴 imgur 链接,会自动解析,另外回复不支持 markdown 语法
    shenjinpeng
        5
    shenjinpeng  
       33 天前
    也可以检查一下程序是不是出 bug 写入了 big int id
    iyiluo
        6
    iyiluo  
       33 天前   ❤️ 1
    开 general log 日志,重新复现一下,看看日志里面有没有踪迹
    jifengg
        7
    jifengg  
       33 天前
    一种可能:之前写入过 id=2147483647 或 2147483646 的数据,又删掉了数据,但是这个表的下次自增值已经变成 2147483647 了
    layxy
        8
    layxy  
       33 天前
    看下 binlog 记录
    dcsuibian
        9
    dcsuibian  
       33 天前
    我分析了一下:
    首先,MySQL BUG 不太可能,5.7 又不是什么新版本,有的话早就被人发现了
    其次,sb 同事插入了手动插入了一条 2147483646 的数据,然后删除,可能性也非常低

    以上两种排除了以后,基本就可以认为是程序错误导致的插入
    就我的经验来说最有可能的是之前插入过,然后删除或回滚了

    我估计题主的技术栈是 Java+MyBatis
    那出现错误的代码我觉得很有可能是这样的:
    for(int i=0;i<XXX;i++){
    save(); // 插入
    }
    因为某些 BUG ,所以导致这个 XXX 是 Integer.MAX_VALUE ,有可能是在寻找最小索引或最小值的时候出了问题
    vm97
        10
    vm97  
    OP
       33 天前
    感谢各位回复,之前偷懒日志没配置好,我先把日志弄好。确实也怀疑是循环错误写入导致的 ID 爆了,但是库里没记录,也没相关的代码逻辑,包括 mybatis 的日志也未发现异常。我先配好 mysql 日志再观察下
    Karte
        11
    Karte  
       33 天前   ❤️ 1
    可能是你的 MyBaits 上没有 @TableId(value = "id", type = IdType.AUTO).

    有些时候 mybaits 会根据策略自动对 ID 进行赋值, 而不是使用自增主键.
    ktin
        12
    ktin  
       33 天前
    有没有用 insert ignore
    Karte
        13
    Karte  
       33 天前
    可以具体看下 com.baomidou.mybatisplus.core.MybatisParameterHandler#populateKeys.

    如果我记得没错是这.
    snow0
        14
    snow0  
       33 天前
    估计是 mybatis 的问题
    skymei
        15
    skymei  
       33 天前
    如果写入了一条指定 ID 值超过上限的数据,也会变成这样
    qianyan
        16
    qianyan  
       33 天前
    不知道你是什么原因,但如果是 mybatis-plus 注解了 TableId ,但没标记自增的话,会有这个问题的。
    qindan
        17
    qindan  
       33 天前
    改为 uuid 吧
    A555
        18
    A555  
       33 天前
    @vm97 mysql binlog 看看
    PaulSamuelson
        19
    PaulSamuelson  
       33 天前
    是不是谁把 dev 的 id 发到了 master 上?例如 dev curl 把地址一改,调到线上去了。
    kphcdr
        20
    kphcdr  
       33 天前
    用了事务,但是事务回滚,也会导致自增 ID 变大
    skyyan
        21
    skyyan  
       33 天前
    纯 sql 吗 还是说用了 持久层框架,如果持久层框架 注意自增方式
    warrenwt
        22
    warrenwt  
       33 天前
    看下你的 entity 里面的 id 有没有加自增注解
    FlorentinoAriza
        23
    FlorentinoAriza  
       33 天前
    FlorentinoAriza
        24
    FlorentinoAriza  
       33 天前
    @FlorentinoAriza #23 只是随便选了张图片展示下,可不是广告奥
    irisdev
        25
    irisdev  
       33 天前
    @kphcdr 长知识了,自增 id 竟然不是按照表现有的 id 增长的,这不类似于取号器了
    herm2s
        26
    herm2s  
       33 天前
    mybatis 的问题?或者谁手动设置了 AUTO_INCREMENT 的值?
    gsx008com
        27
    gsx008com  
       33 天前
    @Karte #11 一般就是这个
    opengps
        28
    opengps  
       33 天前
    有没有可能,某种报错一直在占用 id ,导致出现了最大值
    Huelse
        29
    Huelse  
       33 天前
    @irisdev 自增 id 就是数据库维护了一个序列号表,你甚至可以改当前自增值`ALTER TABLE tbl AUTO_INCREMENT = 100;`
    https://dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html
    TeslaLyon
        30
    TeslaLyon  
       33 天前
    结案了吗?
    sagaxu
        31
    sagaxu  
       33 天前
    @irisdev

    当自增字段没有指定明确的值时,自增 ID 就是个计数器,包括 pgsql 的 serial 也是,每次有 insert 或 replace...时就+1 ,无论执行成功还是失败,+1 不会退回,完全不受表中实际值的影响。

    当明确指定了该字段的值时,若指定值大于自增字段当前值,就更新计数器到指定值+1 ,此时是受表的现有值的影响的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1296 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 17:28 · PVG 01:28 · LAX 10:28 · JFK 13:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.