Innodb 与自增长auto_increment

简介:

Innodb与Myisam存储引擎对auto_crement的限制:

Innodb中自增长的列必须是索引,同时必须是索引的第一个列,否则会报如下错误:there can be only one column and it must be defined as a key;MyISAM没有这个限制。

MyISAM采用表锁设计,自增长不用考虑并发问题;

auto_increment在Innodb工作方式:

含有auto_increment列的表在Innodb数字字典中包含一个自增长的计数器,仅存在内存而不是磁盘上;

初始化auto_increment的值:

server 启动后,对表进行插入的时候,innodb获取互斥锁等价于:SELECT MAX(ai_col) FROM T FOR UPDATE;语句取回的值逐次加一,并被赋给列和自动增长计数器。自动增长计数器被初始化之后,如果插入一个明确指定的列值,而且该值大于当前计数器值,则计数器被设置为指定列值。如果没有明确指定一个值,InnoDB给计数器增加一,并且赋新值给该列。


自增长不连续的原因:

当使用表锁的方式进行auto_increment 值的插入时,为了提供插入性能,该锁是在完成自增列的插入后释放,并不是在事务完成后才释放。所以自增列不连续一般出现了事务回滚操作。

当使用互斥量的方式插入值的时候,由于并发的存在可能会造成值的不连续性;


自增长与锁:

在5.1.22版本之前,采用一种特殊的表锁机制- auto-inc Locking,锁不是在一个事务完成后释放,而是在完成对自增长值插入的SQL语句之后立即释放;这个只是在一定程度上提高了并发插入效率,但对于insert...select的大数据量的插入会影响插入的性能;

在5.1.22之后的版本,innodb采用轻量级互斥量的自增长,对语句插入的行数,innodb提前分配好自增的值该为多少,后面的语句无需等待前面未执行完的语句即可执行(因为对插入的行数已知,自增的值已提前通过互斥量分配好);

举例:某一insert语句1执行前,表的AUTO_INCREMENT=1,语句1的插入行数已知为3,innodb在语句1的实际插入操作执行前就预分配给该语句三个自增值,当有一个新的insert语句2要执行时,读取的AUTO_INCREMENT=4,这样虽然语句1可能还没有执行完,语句2就可直接执行无需等待语句2。

注意:对于语句中如果明确设定一个自增值,同时插入多个值,并利用其自增的特性,可能会造成其主键冲突;举例:如果当前的自增值为4,插入下面的语句将会造成主键冲突:INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d'); 因为所有自增值的增长都是根据前一个语句的最大自增值来确定的;

锁设计的参数:innodb_autoinc_lock_mode 参数值 0 1(默认值) 2

0:表示使用auto-inco 表锁机制(不推荐),优点是在不发生回滚的情况下,能保证自增值是连续的,但并发效率很慢;

1:使用互斥量(mutex)对内存中的计数器进行累加,对于 “bulk insert”来说还是使用表锁机制,如果使用auto-inc 产生自增长的值,此时再进行“simple inserts”操作时,仍旧使用 auto-inc的方式产生自增值;优点:就算binlog复制是在sbr的方式下,那也能保证数据的连续性;

(“bulk insert” 是指在插入前不确定要插入的行数的语句,比如 insert...select ;replace...select;load data)

(“simple insert”是指插入前就能确定插入行数的语句;比如insert ;replace;不包含:insert... on dupliate key update...这样的语句)

2:对于所有的语句都使用互斥量获得自增长值;优点:并发效率高;缺点:可能会造成自增值的不连续性;最好是基于RBR模式进行复制,保持主从数据的一致性;






本文转自 位鹏飞 51CTO博客,原文链接:http://blog.51cto.com/weipengfei/1299792,如需转载请自行联系原作者

目录
相关文章
|
7月前
|
存储 SQL 关系型数据库
MySQL 5.7和 MySQL8.0 InnoDB auto_increment 初始化的区别
在MySQL 5.7及之前,自动递增计数器只存于内存,重启后需通过查询确定初始值。从MySQL 8.0开始,计数器变化时写入重做日志,检查点时保存至数据字典,确保重启后能基于持久化的最大值初始化,避免查询,增强连续性和一致性。[[MySQL参考手册, 3099页]](https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html)
|
SQL 关系型数据库 MySQL
MySQL中ENGINE=InnoDB、AUTO_INCREMENT的意思
MySQL中ENGINE=InnoDB、AUTO_INCREMENT的意思
|
9天前
|
存储 关系型数据库 MySQL
Mysql索引:深入理解InnoDb聚集索引与MyisAm非聚集索引
通过本文的介绍,希望您能深入理解InnoDB聚集索引与MyISAM非聚集索引的概念、结构和应用场景,从而在实际工作中灵活运用这些知识,优化数据库性能。
57 7
|
1月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
本文介绍了MySQL InnoDB存储引擎中的数据文件和重做日志文件。数据文件包括`.ibd`和`ibdata`文件,用于存放InnoDB数据和索引。重做日志文件(redo log)确保数据的可靠性和事务的持久性,其大小和路径可由相关参数配置。文章还提供了视频讲解和示例代码。
141 11
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
|
16天前
|
存储 关系型数据库 MySQL
MySQL引擎InnoDB和MyISAM的区别?
InnoDB是MySQL默认的事务型存储引擎,支持事务、行级锁、MVCC、在线热备份等特性,主索引为聚簇索引,适用于高并发、高可靠性的场景。MyISAM设计简单,支持压缩表、空间索引,但不支持事务和行级锁,适合读多写少、不要求事务的场景。
48 9
|
1月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的表空间
InnoDB是MySQL默认的存储引擎,主要由存储结构、内存结构和线程结构组成。其存储结构分为逻辑和物理两部分,逻辑存储结构包括表空间、段、区和页。表空间是InnoDB逻辑结构的最高层,所有数据都存放在其中。默认情况下,InnoDB有一个共享表空间ibdata1,用于存放撤销信息、系统事务信息等。启用参数`innodb_file_per_table`后,每张表的数据可以单独存放在一个表空间内,但撤销信息等仍存放在共享表空间中。
|
1月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的段、区和页
MySQL的InnoDB存储引擎逻辑存储结构与Oracle相似,包括表空间、段、区和页。表空间由段和页组成,段包括数据段、索引段等。区是1MB的连续空间,页是16KB的最小物理存储单位。InnoDB是面向行的存储引擎,每个页最多可存放7992行记录。
|
1月前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL的InnoDB存储引擎
InnoDB是MySQL的默认存储引擎,广泛应用于互联网公司。它支持事务、行级锁、外键和高效处理大量数据。InnoDB的主要特性包括解决不可重复读和幻读问题、高并发度、B+树索引等。其存储结构分为逻辑和物理两部分,内存结构类似Oracle的SGA和PGA,线程结构包括主线程、I/O线程和其他辅助线程。
【赵渝强老师】MySQL的InnoDB存储引擎
|
6月前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)