首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

MySQL自增主键为什么不连续

自增值修改机制 自增值修改行为如下: 如果插入数据时id字段指定为0、null或者未指定,那么就把该表AUTO_INCREMENT填到自增字段 如果插入数据时id字段指定了具体,就直接使用语句里指定...自增值变更情况如下,假设某次要插入是X,当前自增值是Y: 如果X<Y,表自增值不变 如果X>=Y,需要把当前自增值修改为自增值 自增值生成算法 从auto_increment_offset...批量插入导致自增值不连续 自增值锁不是一个事务锁,每次申请完就释放,方便其他事务获取自增值。...参数innodb_autoinc_lock_mode不同会影响锁释放时机: 该参数如果为0,语句执行结束释放锁 设置为1:普通insert语句,自增锁在申请马上释放;insert...select...这样批量插入语句等语句结束才释放 设置为2:申请就释放锁 show global variables like 'innodb_autoinc_lock_mode'; 如果innodb_autoinc_lock_mode

8.3K20

何在MySQL中获取表中某个字段为最大和倒数第二条整条数据?

在MySQL中,我们经常需要操作数据库中数据。有时我们需要获取表中倒数第二个记录。这个需求看似简单,但是如果不知道正确SQL查询语句,可能会浪费很多时间。...在本篇文章中,我们将探讨如何使用MySQL查询获取表中倒数第二个记录。 一、查询倒数第二个记录 MySQL中有多种方式来查询倒数第二个记录,下面我们将介绍三种使用最广泛方法。...ID(或者其他唯一)。...1.2、子查询 另一种获取倒数第二个记录方法是使用子查询。我们先查询表中最后一条记录,然后查询它之前一条记录。...------+-----+ | id | name | age | +----+------+-----+ | 4 | Lily | 24 | +----+------+-----+ 三、查询某个字段为最大整条数据

53510
您找到你想要的搜索结果了吗?
是的
没有找到

IGNORE,REPLACE,ON DUPLICATE KEY UPDATE在避免重复插入记录时存在问题及最佳实践

2,表示下次插入行记录id字段从2开始。...详细介绍参见参考博客中自增锁部分,本文简单介绍如下:自增锁是一种特殊表级锁,主要用于获取事务中插入自增字段,也就是我们最常用自增主键id。...执行数据表检索得到结果为: 对比初始化检索结果可知,id字段又1变成了3,name字段由“张三”变成了默认。...插入记录中除了指定字段,其他字段都变成了默认,即导致了数据字段丢失。因而如果要使用REPLACE,一定要保证sql语句中包含期望入库所有字段。...S锁,并获取该记录 insert失败 4 update该记录 获取重复记录S锁,并获取该记录 5 申请该记录X锁,由于T2有该记录S锁,需要等待其释放 update该记录 6 申请该记录

1.5K11

技术分享 | 关于 MySQL 自增 ID 事儿

当我们使用 MySQL 进行数据存储时,一般会为一张表设置一个自增主键,当有数据行插入时,该主键字段则会根据步长与偏移量增长(默认每次+1)。...自增并不是保存在表结构信息内,对于不同版本它们有如下区别: 1.1.1 MySQL 8.0版本之前(重启可能会产生变化): 计数器存储在内存中,重启丢弃,下一次将读取最大一个自增ID...,不是事务结束 连续模式:批量插入时锁持有到该语句执行结束,简单插入时锁持有到申请完自增ID即释放,并非直到语句完成 1.4 计数器三种模式(innodb_autoinc_lock_mode) 通过调整...当 row_id 使用则又会从 0 开始发放,此时新插入数据将覆盖回 row_id=0 数据行。...3.1 自增 ID 输入输出前进行转义 在输出或者获取前对指定字段进行可逆转义操作 优点:实现起来比较简单,无论单体业务或者分布式应用都无需考虑对数据源解析,只需在客户端实现自己转义与解析方法即可

3K10

MySQL Online DDL

GH-OST 使用限制: 不能对有外键关系及触发器表进行 Online DDL 要求所连接获取增量数据 mysql binlog 为 row 格式(会强制转换) 若有同名但是字母大小写不同:...在详细了解 innodb_autoinc_lock_mode 之前,我们需要对自增长插入进行类别划分: 1、Insert-like : insert-like 指所有的插入语句, INSERT、REPLACE...UPDATE 这类 SQL 语句 在了解了以上分类,我们接着来分析 innodb_autoinc_lock_mode 参数各个设置对自增锁影响,总共就 3 个可以设置,即 0、1、2 1、innodb_autoinc_lock_mode...因为有了自增长方式,0 这个选项不应该是新版用户首选项。 2、innodb_autoinc_lock_mode = 1 这是该参数默认。...显然,这是性能最高方式。然而,这会带来一定问题,因为并发插入存在,在每次插入时,自增长可能不是连续

7.7K22

MySQL 主键自增注意事项

松哥之前写过一篇文章和小伙伴们介绍 MySQL binlog 日志文件三种格式: row:binlog 中记录是具体而不是原始 SQL,举一个简单例子,假设表中有一个字段是 UUID,用户执行...如果 binlog 格式是 statement,那么我们最好设置 innodb_autoinc_lock_mode 为 1,这样对于 simple insert 并发插入能力进行了提高,批量插入还是先获取...以上两点主要是针对 InnoDB 存储引擎,如果是 MyISAM 存储引擎,都是先获取 AUTO-INC 锁,插入完成再释放,相当于 innodb_autoinc_lock_mode 变量取值对 MyISAM...首先,我们可以通过如下 SQL 查看当前 innodb_autoinc_lock_mode 取值: 可以看到,我使用 8.0.32 这个版本目前默认是 2。...当上面的 SQL 执行完毕之后,如果我们还想再插入数据,并且插入 ID 不指定,则我们发现自动生成 ID 为 104。

5510

MySQL自增主键详解「建议收藏」

,自增值行为如下: 1.如果插入数据时id字段指定为0、null或未指定,那么就把这个表当前AUTO_INCREMENT填到自增字段 2.如果插入数据时id字段指定了具体,就直接使用语句里指定...假设,某次要插入是X,当前自增值是Y 1.如果X<Y,那么这个表自增值不变 2.如果X>=Y,就需要把当前自增值修改为自增值 自增值生成算法是:从auto_increment_offset...(初始)开始,以auto_increment_increment(步长)为步长,持续叠加,直到找到第一个大于X,作为自增值 三、自增值修改时机 创建一个表t,其中id是自增主键字段、c是唯一索引...id获取表t当前自增值2 3.将传入改成(2,1,1) 4.将表自增值改成3 5.继续执行插入数据操作,由于已经存在c=1记录,所以报Duplicate key error(唯一键冲突...之后,再执行insert into t2 values(null, 5,5),实际上插入数据就是(8,5,5) 这是主键id出现自增id不连续第三种原因 五、自增主键用完了 自增主键字段在达到定义类型上限

5.8K40

深度解析auto-increment自增列Duliplicate key问题

提示:公众号展示代码会自动折行,建议横屏阅读 问题描述 近期,线上有个重要Mysql客户表在从5.6升级到5.7master上插入过程中出现"Duplicate key"错误,而且是在主备及RO实例上都出现...以其中一个表为例,迁移前通过“show create table” 命令查看auto increment id为1758609, 迁移变成了1758598,实际对迁移生成自增列用max求最大为...(3) 解决办法:引擎内部获取自增列时考虑全局autoincrement参数,这样重启第一个插入线程获取自增值就不是max(id) + 1,而是next_id,然后根据next_id设置下一个autoincrement...由于这个过程是加锁保护,其他线程再获取autoincrement时候就不会获取到重复。...心得 (1) autoincrementautoinc_lock_mode及auto_increment_increment这两个参数变化容易导致出现重复key,使用过程中要尽量避免动态去修改。

89820

2021-01-05:mysql自增id实现逻辑是什么样子

innodb_autoinc_lock_mode=1(consecutive lock mode,MySQL 8.0 之前默认 ):对于不确定插入数量语句(例如INSERT ......AutoIncrement 锁模式 获取 AutoIncrement 最新,需要涉及到锁。目前有三种锁模式,对应 innodb_autoinc_lock_mode , 0 ,1,2....SELECT和LOAD DATA)才会采用AUTO-INC锁这种方式,而针对已知数量普通插入,则采用了一种轻量级互斥锁来分配auto_increment列。...因为同步传输是语句,而不是行,语句执行差异导致主从可能主键不一致。...所以,在MySQL 8.0 之前,如果 rollback 导致某些没有使用,重启,这些还是会使用。但是在 MySQL 8.0 之后就不会了。

47710

第03期:列非空与自增

参与 NULL 字段拼接结果都为 NULL,预期可能会有差异 预想把字段 r1 做个拼接,再插入表 t3 里,结果 t3 表记录全为 NULL,跟预期不符。...控制自增属性性能变量:innodb_autoinc_lock_mode innodb_autoinc_lock_mode=0 代表传统模式,也就是说,在对有自增属性字段插入记录时,会持续持有一个表级别的自增锁...innodb_autoinc_lock_mode=1 代表连续模式,和传统模式差不多,不同点在于对于简单插入语句,比如 SQL 2,只在分配 ID 过程中持有一个轻量级互斥锁(线程级别,而不是事务级别...对于要立刻获取插入需求 就是说要获取一张表任何时候最大,应该时刻执行以下 SQL 3 ,而不是 SQL 2。...自增列溢出现象 自增属性列如果到了此列数据类型最大,会发生溢出。比如变更表 f1 自增属性列为 tinyint。 SQL 2 显式插入最大 127, SQL 3 就报错了。

59810

深度解析auto-increment自增列"Duliplicate key"问题

提示:公众号展示代码会自动折行,建议横屏阅读 问题描述 近期,线上有个重要Mysql客户表在从5.6升级到5.7master上插入过程中出现"Duplicate key"错误,而且是在主备及RO实例上都出现...以其中一个表为例,迁移前通过“show create table” 命令查看auto increment id为1758609, 迁移变成了1758598,实际对迁移生成自增列用max求最大为...(3) 解决办法:引擎内部获取自增列时考虑全局autoincrement参数,这样重启第一个插入线程获取自增值就不是max(id) + 1,而是next_id,然后根据next_id设置下一个autoincrement...由于这个过程是加锁保护,其他线程再获取autoincrement时候就不会获取到重复。...心得 (1) autoincrementautoinc_lock_mode及auto_increment_increment这两个参数变化容易导致出现重复key,使用过程中要尽量避免动态去修改。

2.1K40

InnoDB引擎为什么推荐使用自增ID作为主键?

当往一个快满或已满数据页中插入数据时,插入数据会将数据页写满,MySQL 就需要申请数据页,并且把上个数据页中部分数据挪到数据页上。...如果表使用自增主键,那么每次插入记录,记录就会顺序添加到当前索引节点后续位置,当一页写满,就会自动开辟一个页。如下图所示: 这样就会形成一个紧凑索引结构,近似顺序填满。...如果使用非自增主键(如果身份证号或学号等),由于每次插入主键近似于随机,因此每次新纪录都要被插到现有索引页中间某个位置: 此时MySQL不得不为了将记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉...因此,只要可以,请尽量在InnoDB上采用自增字段做主键。 ◆ 二、尽量使用更小主键 在满足业务需求情况下,尽量使用占空间更小主键。...并且从该版本开始,InnoDB存储引擎提供了一个参数innodb_autoinc_lock_mode(自增锁模式)来控制自增长模式,该参数默认为1或者2。

3.2K30

每日一面 - mysql 自增 id 实现逻辑是什么样子

=0(traditional lock mode):获取表锁,语句执行结束释放 innodb_autoinc_lock_mode=1(consecutive lock mode,MySQL 8.0 之前默认...SELECT和LOAD DATA)和 innodb_autoinc_lock_mode=0 一样,其他的确定数量语句在执行前先批量获取 id,之后再执行语句。...SELECT和LOAD DATA)才会采用AUTO-INC锁这种方式,而针对已知数量普通插入,则采用了一种轻量级互斥锁来分配auto_increment列。...因为同步传输是语句,而不是行,语句执行差异导致主从可能主键不一致。...所以,在MySQL 8.0 之前,如果 rollback 导致某些没有使用,重启,这些还是会使用。但是在 MySQL 8.0 之后就不会了。

56520

MySQL重大Bug!自增主键竟然不是连续递增

自增值修改策略 若字段id被定义为AUTO_INCREMENT,在插入一行数据时,自增值行为如下: 若插入数据时id字段指定为0、null 或未指定,则把该表当前AUTO_INCREMENT填到自增字段...若插入数据时id字段指定了具体,则使用语句里指定 根据要插入和当前自增值大小关系,假设要插入X,而当前自增值Y,若: X<Y,则该表自增值不变 X≥Y,把当前自增值修改为自增值 自增值生成算法...两个系统参数默认都是1。 某些场景使用就不全是默认。...所以,默认情况下,若准备插入≥当前自增值: 自增值就是“准备插入+1” 否则,自增值不变 自增值修改时机 表t里面已有如下记录 再执行一条插入数据命令 该唯一键冲突语句执行流程...: 执行器调用InnoDB引擎接口写入一行,传入这一行是(0,1,1) InnoDB发现用户没有指定自增id获取表t当前自增值2 将传入改成(2,1,1) 将表自增值改成3 继续执行插入数据

2.6K00

mysql几种锁_初中常见七种沉淀

这段话表明自增锁是一种特殊表级锁,主要用于事务中插入自增字段,也就是我们最常用自增主键id。通过innodb_autoinc_lock_mode参数可以设置自增主键生成策略。...由此可知,如果你在使用基于语句复制(statement-based replication)请将innodb_autoinc_lock_mode设置为0或1,并在主从上使用相同。...要在服务器重新启动初始化自动递增计数器,InnoDB将在首次插入行到包含AUTO_INCREMENT列表时执行以下语句等效语句。...如果在自动递增计数器初始化前使用SHOW TABLE STATUS语句查看表, InnoDB将初始化计数器,但不会递增该。这个会储存起来以备之后插入语句使用。...如果插入显式指定列行,并且该大于当前计数器,则将计数器设置为指定。 只要服务器运行,InnoDB就使用内存中自动递增计数器。

76520

39 | 自增主键不连续

自增值修改机制 在插入一行数据时候,自增值行为如下: 如果插入数据时 id 字段指定为 0、null 或未指定,那么就把这个表当前 AUTO_INCREMENT 填到自增字段; 如果插入数据时...id 字段指定了具体,就直接使用语句里指定。...备注:在一些场景下,使用就不全是默认。...InnoDB 引擎接口写入一行,传入这一行是 (null,1,1); InnoDB 发现用户没有指定自增 id 获取表 t 当前自增值 2; 将传入改成 (2,1,1); 将表自增值改成...… select 这样批量插入数据语句,自增锁还是要等语句结束才被释放; 这个参数被设置为 2 时,所有的申请自增主键动作都是申请就释放锁。

4.8K10

浅析MySQL存储引擎序列属性

每次序列都会存在数据文件中,因此当服务重启,依旧可以进行序列递增。 备注:两种情况比较特殊,第一种是使用truncate ,序列将重新开始。...,比如当前最大序列为202,删除通过指定起始,是可以重新使用该序列。...这个参数,它用于控制获取自增值加锁方式 innodb_autoinc_lock_mode,它有0、1、2三个。...下面详细说明一下关于innodb_autoinc_lock_mode属性 (1) innodb_autoinc_lock_mode=0 代表传统模式,也就是说,在对有自增属性字段插入记录时,会持续持有一个表级别的自增锁...=1 默认,代表连续模式,和传统模式差不多,不同点在于对于简单插入语句,只在分配 ID 过程中持有一个轻量级互斥锁(线程级别,而不是事务级别),而不是直到语句结束才释放表锁。

1.5K30

MySQL重大Bug!自增主键竟然不是连续递增

自增值修改策略 若字段id被定义为AUTO_INCREMENT,在插入一行数据时,自增值行为如下: 若插入数据时id字段指定为0、null 或未指定,则把该表当前AUTO_INCREMENT填到自增字段...若插入数据时id字段指定了具体,则使用语句里指定 根据要插入和当前自增值大小关系,假设要插入X,而当前自增值Y,若: X X≥Y,把当前自增值修改为自增值 自增值生成算法 从 auto_increment_offset...两个系统参数默认都是1。 某些场景使用就不全是默认。...所以,默认情况下,若准备插入≥当前自增值: 自增值就是“准备插入+1” 否则,自增值不变 自增值修改时机 表t里面已有如下记录 再执行一条插入数据命令 该唯一键冲突语句执行流程: 执行器调用...InnoDB引擎接口写入一行,传入这一行是(0,1,1) InnoDB发现用户没有指定自增id获取表t当前自增值2 将传入改成(2,1,1) 将表自增值改成3 继续执行插入数据(

3.4K10

好险!一入职,就遇到MySQL这么大Bug!差点背锅走人~

问题描述 线上有个重要Mysql客户表在从5.6升级到5.7,master上插入过程中出现"Duplicate key"错误,而且是在主备及RO实例上都出现。...以其中一个表为例,迁移前通过“show create table” 命令查看auto increment id为1758609, 迁移变成了1758598,实际对迁移生成自增列用max求最大为...(3) 解决办法:引擎内部获取自增列时考虑全局autoincrement参数,这样重启第一个插入线程获取自增值就不是max(id) + 1,而是next_id,然后根据next_id设置下一个autoincrement...由于这个过程是加锁保护,其他线程再获取autoincrement时候就不会获取到重复。...心得 (1) autoincrementautoinc_lock_mode及auto_increment_increment这两个参数变化容易导致出现重复key,使用过程中要尽量避免动态去修改。

63820
领券