MySQL -- Innodb是如何处理自增列的
insert into t1(c1,c2) values(1,'a'),(null,'b'),(5,'c'),(null,'d')
另一种"mixed-mode inserts"是insert...on duplicate key update,最差的场景就是一条insert后跟着一条update,产生的自增列的值可能都没有用到。
create table t1(
c1 int(11) not null auto_increment,
c2 varchar(10) default null,
primary key(c1)
) engine = innodb;
tx1: insert into t1 (c2) select 1000 rows from another table ... #事务1插入1000行
tx2: insert into t1 (c2) values ('xxx');
innodb无法提前知道tx1会插入多少条数据,只好每插入一条数据就产生一个自增值。对于表级锁,每次执行执行一条sql语句,所以对于不同的sql语句,自增值的产生不是交错的。
·1表示"consecutive"锁模式
这是默认的锁定模式。在这种模式下,“bulk inserts”使用特殊的AUTO-INC表级锁并将其保持到语句结束。这适用于所有INSERT ... SELECT,REPLACE ... SELECT和LOAD DATA语句。一次只能执行一条持有AUTO-INC锁的语句。如果批量插入操作的源表与目标表不同,则在对源表中选择的第一行加共享锁之后,将对目标表执行AUTO-INC锁。如果批量插入操作的源和目标在同一表中,则在对所有选定行施加共享锁之后,获取AUTO-INC锁。
"Simple inserts"可以提前知道需要哪些自增值,在mutex的帮助下,不需要对表加上标级auto-inc锁。mutex只是在分配自增值得时候存在,不需要等整个sql语句结束才释放。如果有另外的事务持有auto-inc锁得时候,就需要获取表级auto-inc锁了。
此锁模式可确保在存在INSERT语句的情况下(事先不知道行数)(并且随着语句的进行自动分配自增值),所有由“insert-like”语句分配的自动递增值语句是连续的,并且操作对于基于语句的复制是安全的。
简而言之,此锁模式可提高可伸缩性,同时可安全地用于基于语句的复制。此外,与“传统”锁定模式一样,任何给定语句分配的自动增量编号都是连续的。对于任何使用自增的语句,与“传统”模式相比,语义没有任何变化,但有一个重要的例外。
"mixed-mode inserts"例外,其中用户为多行"simple insert"中的某些(但不是全部)行的AUTO_INCREMENT列提供了显式值。对于此类插入,InnoDB分配的自增值比要插入的行数更多。但是,所有自动分配的值都是连续生成的(因此高于由最近执行的先前语句生成的自增值)。"多余"的自增值被丢失。
·2表示"interleaved"锁模式
在这种锁模式下,没有"insert-like"语句使用表级的AUTO-INC锁定,并且可以同时执行多个语句。这是最快,最具扩展性的锁定模式,但是当使用基于语句的复制或恢复方案从二进制日志中重放SQL语句时,这是不安全的。
在这种锁模式下,保证自增值是唯一的,并且在所有同时执行的"insert-like"语句中单调递增。但是,由于多个语句可以同时生成数字(也就是说,在语句之间交错分配数字),因此为任何给定语句插入的行生成的值可能不是连续的。
如果仅执行的语句是"insert-like",为单个语句生成的数字中没有空格。其中要提前知道要插入的行数,则为“除混合模式插入”外,为单个语句生成的数字中没有空格。但是,执行"bulk-inserts"时,任何给定语句分配的自增值可能存在间隙。
Innodb自增锁的使用
1.使用自增列进行复制
如果使用基于语句的复制,innodb_autoinc_lock_mode设置为0或1(主、备都使用相同的配置)。如果是设置为2或者主备设置不一样,不能保证准备端一致。
如果是使用基于行的、混合模式的复制,所有自增锁模式都是安全的,因为基于行的复制对sql的执行顺序是不敏感的(混合模式会将基于语句的不安全的复制转换成行复制)。
2.自增值的丢失和序列空隙(sequence gaps)
在所有自增锁模式中(0,1,2),如果使用自增值得事务发生了回滚,这些自增值就丢失了。这些值是不可以重用的,这样就产生了gap。
3.自增列指定null或0值
在所有自增锁模式中(0,1,2),如果将自增列指定为null或0,innodb会自行给自增列赋值
4.自增列指定为负值
可以插入赋值,但是不能在负值得基础上进行自增
5.超过自增列指定的最大值
超过自增列指定的最大值就不能自增了。
6."mixed-mode inserts"中自增值得使用
"mixed-mode inserts"中有"simple insert"指定的自增值,也有没有指定的。在不同的自增锁模式下结果是不同的。
7.在插入的过程中修改自增值
会导致重复的值。
Innodb自增计数器的初始化
创建了自增列后,对应的数据字典中包含一个自增计数器,用来为列赋值。这个计数器是存储在内存中,而不是磁盘上。
在实例启动后,innodb会执行类似下面的语句来为计数器初始化:
select max(ai_col) from table_name for update;
缺省情况下,会将获取的值增加1。也可以修改参数auto_increment_increment进行配置。
如果表是空的,计数器的值就是1。
MySQL -- Innodb是如何处理自增列的的更多相关文章
- MySQL面试题之为什么要为innodb表设置自增列做主键?
为什么要为innodb表设置自增列做主键? 1.使用自增列做主键,写入顺序是自增的,和B+数叶子节点分裂顺序一致 2.表不指定自增列做主键,同时也没有可以被选为主键的唯一索引,InnoDB就会选择内置 ...
- mysql 深度解析auto-increment自增列"Duliplicate key"问题
转载自:https://cloud.tencent.com/developer/article/1367681 问题描述 近期,线上有个重要Mysql客户的表在从5.6升级到5.7后master上插入 ...
- mysql iot 主键自增列问题
mysql 如何避免热点块? 主键按sn自增列 Oracle 可以通过翻转索引 比如 插入101 102 103 104 变成101 201 301 401 分散数据 反转索引坏处,无法index r ...
- MySQL innodb的组合索引各个列中的长度不能超过767,
MySQL索引的索引长度问题 MySQL的每个单表中所创建的索引长度是有限制的,且对不同存储引擎下的表有不同的限制. 在MyISAM表中,创建组合索引时,创建的索引长度不能超过1000,注意这里索 ...
- MySQL使用AUTO_INCREMENT列的表注意事项之update自增列篇
1)对于MyISAM表,如果用UPDATE更新自增列,如果列值与已有的值重复,则会出错:如果大于已有的最大值,则会自动更新表的AUTO_INCREMENT,操作是安全的. (2)对于innodb表,u ...
- MySQL--自增列学习
##=====================================================================================## 在数据库表设计中会纠 ...
- MySQL--自增列持久化问题
====================================================================== 自增列持久化问题 5.5/5.6/5.7三个版本中,MyS ...
- [MySQL FAQ]系列 — 为什么InnoDB表要建议用自增列做主键
我们先了解下InnoDB引擎表的一些关键特征: InnoDB引擎表是基于B+树的索引组织表(IOT): 每个表都需要有一个聚集索引(clustered index): 所有的行记录都存储在B+树的叶子 ...
- (转)mysql中InnoDB表为什么要建议用自增列做主键
InnoDB引擎表的特点 1.InnoDB引擎表是基于B+树的索引组织表(IOT) 关于B+树 (图片来源于网上) B+ 树的特点: (1)所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关 ...
随机推荐
- powerdesigner 生成数据库脚本
PowerDesigner导出所有SQL脚本 操作:Database=>Generate Database PowerDesigner怎么导出建表sql脚本 1 按照数据库类型,切换数据库. D ...
- PHPUnit单元测试
单元测试 PHPUnit <?php /** * 定义一个用来被测试的类RemoteConnect * @author json * */ class RemoteConnect{ public ...
- 微信小程序 - loading(组件)
更新日期: 2019/3/8:首次发布 2019/3/12:增加loadOpacity透明度控制,默认0.5. 以及修改居中方式 Loading 参数: 1. type:loading(必需参数) 2 ...
- 共享权限ACL列表出现SID现象
http://www.minasi.com/forum/topic.asp?TOPIC_ID=16842 Basically here's what happens, and why it doesn ...
- sql按分时段统计
),,) ctime, ) num FROM [eschool_1].[dbo].kg_Kaoqin ),,) ),,)
- tomcat7配置
<?xml version='1.0' encoding='utf-8'?><!-- Licensed to the Apache Software Foundation (ASF) ...
- Python 模块浅析
如果你退出Python解释器重新进入,以前创建的一切定义(变量和函数)就全部丢失了.因此,如果你想写一些长久保存的程序,最好使用一个文本编辑器来编写程序,把保存好的文件输入解释器. 我们称之为创建一个 ...
- Influxdb数据压缩
环境: CentOS6.5_x64InfluxDB版本:1.1.0 数据压缩可以参考: https://docs.influxdata.com/influxdb/v1.1/concepts/stora ...
- 〖Linux〗Kubuntu文件管理器单例的设置(即:一个工作区只一个文件管理器)
有没有一种,情况: 1. 程序A打开了文件管理器: 2. 程序B又打开了文件管理器: 导致开了两个文件管理器,太不舒服了: 搜索下 kubuntu dolphin single instance,果然 ...
- 【Linux】文件批量重命名
例如:我们现在有如下文件列表 我们现在想要把.log..LOG与.rar为扩展名的文件全部重新命名,具体脚本如下: #!/bin/sh ##------------------------------ ...