当前位置: 首页 > news >正文

自增主键为什么不是连续的?

前言

如果一个线程回滚,例如唯一键冲突的情况回滚时,回滚了sql语句,但是并没有把自增的值也-1。那么就会导致下一条插入的数据自增id出现了跳跃。


自增主键为什么不是连续的?

  • 前言
  • 执行时机
  • 为什么自增主键不是连续的
  • 为什么不回滚自增主键
  • innodb_autoinc_lock_mode
  • 设置成2导致的问题

执行时机

mysql的自增主键+1的时机是在mysql真正执行之前,获取当前值并加1。

为什么自增主键不是连续的

如果一个线程回滚,例如唯一键冲突的情况回滚时,回滚了sql语句,但是并没有把自增的值也-1。那么就会导致下一条插入的数据自增id出现了跳跃。

为什么不回滚自增主键

之所以不让自增主键回滚是因为:

  1. 假如两个线程一个获取了id =2 ,另一个是id =3 。id=3的完成之后,如果id=2的需要回滚,那么后面再来一个插入请求,就会获取id=2的值,然后再来一个数据就会获取3从而导致主键冲突。
    如果要解决这个冲突:
    1. 就要每次插入时还要去数据库里查询一下是否有这个自增主键。这是非常耗时的,本来一个非常简单的操作,现在就会变得非常复杂。
    2. 还有一种方法就是扩大每次获取自增值的锁时间,对于自增值的锁一般是很快的获取之后+1然后就会释放。如果要防止上面的冲突,就是等这个sql执行完成之后,再允许其它线程获取这个锁。这显然也会大大降低并发值,因此mysql放弃了连续。

innodb_autoinc_lock_mode

那么后来mysql添加了一个参数innodb_autoinc_lock_mode,

  1. 如果设置成0:就是会等一个写入执行完成之后,再让另一个线程获取自增的值
  2. 如果设置成1:那么对于单个的insert值,就会获取到自增值就直接释放。但是对于批量写入或者批量替换的请求,那么就会等这个操作执行完成之后,再让另一个线程获取自增值。
  3. 如果设置成2,那么所有的insert操作都会获取到自增值之后直接释放。不等sql执行结束。

设置成2导致的问题

如果再批量插入A的时候,id是自增1,2,3,4,6,7,另一个线程B也插入了一条数据5,

但是在写入binlog的时候,是一个线程一个线程写入的。

那么线程B插入的数据对应的id只能是线程A开头的或者结尾,如果binlog的format= statement。就会导致主备数据不一致。
所以这这又是一个将binlog的format= row的原因。

这里需要注意 如果线程A不是批量写入的语句。只是一个普通的insert语句ID 1,然后又有另一个线程B获取自增建ID 2。但是再写入binlog时,线程B先写入了,然后线程A写入。
这种情况下 即使binlog的format=statement 也不会导致主备数据的数据不一致。在binlog中还有一个步长的参数,在执行线程B时,步长会为2,ID还是2,执行线程A时,步长是1,ID还是1。

http://www.xdnf.cn/news/1129231.html

相关文章:

  • 华为敏态开发流程敏捷开发费用估算敏态IT财务分析模板
  • flutter下的webview适配rem问题
  • 详解低速容错CAN(附与高速CAN对比表)
  • 三种深度学习模型(LSTM、CNN-LSTM、贝叶斯优化的CNN-LSTM/BO-CNN-LSTM)对北半球光伏数据进行时间序列预测
  • 指数加权的公式推导
  • 大语言模型:高考志愿填报的“新纪元智能参谋”
  • 鸿蒙和Android知识点
  • wkhtmltopdf导出pdf调试参数
  • golang语法-----变量、常量
  • Ubuntu 22.04 安装 mysql-server与 postgreSQL 服务端
  • AI助手指南:从零开始打造Python学习环境(VSCode + Lingma/Copilot + Anaconda + 效率工具包)
  • 倒计时熔断机制的出价逻辑
  • 711SJBH构建制造业信息化人才培训体系的对策-开题报告
  • 【LeetCode Solutions】LeetCode 181 ~ 185 题解
  • 深度学习图像增强方法(一)
  • 编程项目选择思考点以及项目包装的关键点
  • 3-Nodejs-使用fs文件系统模块
  • uniapp打包成 apk
  • 在百亿流量面前,让“不存在”无处遁形——Redis 缓存穿透的极限攻防实录
  • 原点安全签约金网络数科,共建一体化数据安全防护体系
  • 设计模式二:策略模式 (Strategy Pattern)
  • AiPy+豆包:数据分析可视化,一键生成GUI工具
  • Vue.js 动画与过渡:让你的界面“活”起来,提升用户体验的视觉魔法!
  • : $ operator is invalid for atomic vectors
  • 【SpringBoot】实战-开发模式及环境搭建
  • 前端面试专栏-工程化:25.项目亮点与技术难点梳理
  • Python 操作Excel工作表:添加、删除、移动、隐藏
  • omniparser v2 本地部署及制作docker镜像(20250715)
  • Linux 环境下安装 Node.js v16.13.0 完整指南
  • Unity沉浸式/360View/全景渲染