2019独角兽企业重金招聘Python工程师标准>>>

引言

MySQL中auto_increment字段估计大家都经常用到,特别是innodb引擎。我也经常用,只知道mysql可以保证这个字段在多进程操作时的原子性,具体原理又是什么,后来查阅了MySQL手册以及相关资料,了解了个大概。

本文只探究了mysql5.5中innodb引擎auto_increment的问题。

定义

使用auto_increment的字段可能生成唯一的标识。

如何使用

可在建表时可用“AUTO_INCREMENT=n”选项来指定一个自增的初始值。

可用alter table table_name AUTO_INCREMENT=n命令来重设自增的起始值。

使用规范

AUTO_INCREMENT是数据列的一种属性,只适用于整数类型数据列。

设置AUTO_INCREMENT属性的数据列应该是一个正数序列,所以应该把该数据列声明为UNSIGNED,这样序列的编号个可增加一倍。

AUTO_INCREMENT数据列必须有唯一索引,以避免序号重复(即是主键或者主键的一部分)。

AUTO_INCREMENT数据列必须具备NOT NULL属性。

AUTO_INCREMENT数据列序号的最大值受该列的数据类型约束,如TINYINT数据列的最大编号是127,如加上UNSIGNED,则最大为255。一旦达到上限,

AUTO_INCREMENT就会失效。

当进行全表删除时,MySQL AUTO_INCREMENT会从1重新开始编号。全表删除的意思是发出以下两条语句时: delete from table_name;

或者

truncate table table_name

原理(这里面是重点)

传统auto_increment原理

mysql innodb引擎的表中的auto_increment字段是通过在内存中维护一个auto-increment计数器,来实现该字段的赋值,注意自增字段必须是索引,而且是索引的第一列,不一定要是主键。例如我现在在我的数据库test中创建一个表t,语句如下: CREATE TABLE `t_test` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',

PRIMARY KEY (`id`),

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测试表'

则字段a为auto_increment类型,在mysql服务器启动后,第一次插入数据到表t_test时,InnoDB引擎会执行等价于下面的语句: SELECT MAX(id) FROM t FOR UPDATE;

Innodb获取到当前表中id字段的最大值并将增加1(默认是增加1,如果要调整为增加其他数目,可以设置auto_increment_increment这个配置的设置)然后赋值给该列以及内存中该表对应的计数器

在传统的auto_increment设置中,每次访问auto-increment计数器的时候, INNODB都会加上一个名为AUTO-INC锁直到该语句结束(注意锁只持有到语句结束,不是事务结束).AUTO-INC锁是一个特殊的表级别的锁,用来提升包含auto_increment列的并发插入性能.因此,两个事务不能同时获取同一个表上面的AUTO-INC锁,如果持有AUTO-INC锁太长时间可能会影响到数据库性能(比如INSERT INTO t1... SELECT ... FROM t2这类语句).

改进后

基于上面传统方式的问题(性能太差),在mysql5.1开始,新增加了一个配置项innodb_autoinc_lock_mode来设定auto_increment方式.

可以设置的值为0,1,2.其中0就是第一节中描述的传统auto_increment机制,而1和2则是新增加的模式,默认该值为1,可以中mysql配置文件中修改该值.这里主要来看看这两种新的方式的差别;

在描述差别前需要先明确几个插入类型:

simple inserts

能够确定具体的插入行数的语句。

bulk inserts

事先无法确定插入行数的语句

mixed-mode inserts

有些行指定了auto_increment列的值有些没有指定

下面看看设置innodb_autoinc_lock_mode为不同值时的情况:

innodb_autoinc_lock_mode=0(traditional lock mode)

传统的auto_increment机制,这种模式下所有针对auto_increment列的插入操作都会加AUTO-INC锁,分配的值也是一个个分配,是连续的,正常情况下也不会有间隙(当然如果事务rollback了这个auto_increment值就会浪费掉,从而造成间隙)。

innodb_autoinc_lock_mode=1(consecutive lock mode)

这种情况下,针对bulk inserts才会采用AUTO-INC锁这种方式,而针对simple inserts,则采用了一种新的轻量级的互斥锁来分配auto_increment列的值。当然,如果其他事务已经持有了AUTO-INC锁,则simple inserts需要等待.

需要注意的是,在innodb_autoinc_lock_mode=1时,语句之间是可能出现auto_increment值的间隔的。比如mixed-mode inserts以及bulk inserts中都有可能导致一些分配的auto_increment值被浪费掉从而导致间隙。后面会有例子。

innodb_autoinc_lock_mode=2(interleaved lock mode)

这种模式下任何类型的inserts都不会采用AUTO-INC锁,性能最好,但是在同一条语句内部产生auto_increment值间隙。此外,这种模式对statement-based replication也不安全。

mysql auto_increment 原理_[Mysql]mysql原理之Auto_increment相关推荐

  1. MySQL学习笔记_关于MySQL的字符类型VARCHAR长度知识总结

    MySQL学习笔记_关于MySQL的字符类型VARCHAR长度知识总结 一.VARCHAR存储和行长度限制 1.VARCHAR(N)中,N指的是字符的长度,VARCHAR类型最大支持65535,指的是 ...

  2. mysql自增id原理_《MySQL自增ID》告诉你不为人知的“秘密”......

    原标题:<MySQL自增ID>告诉你不为人知的"秘密"...... 作者:Sunshine Koo 1.概述 " MySQL数据库是最常使用的数据库之一,我们 ...

  3. linux mysql依赖关系_[Linux]-MySQL主从复制

    MySQL支持的复制类型: 1) 基于语句的复制.在主服务器上执行的SQL语句,在从服务器上执行同样的语句.MySQL默认采用基于语句的复制,效率比较高: 2) 基于行的复制.把改变的内容复制过去,而 ...

  4. mysql多大_洞悉MySQL底层架构:游走在缓冲与磁盘之间

    提起MySQL,其实网上已经有一大把教程了,为什么我还要写这篇文章呢,大概是因为网上很多网站都是比较零散,而且描述不够直观,不能系统对MySQL相关知识有一个系统的学习,导致不能形成知识体系.为此我撰 ...

  5. mysql悲观群_谈谈mysql的悲观和乐观锁

    悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.之前有写过一篇文章关于并发的处理思路和解决方案,这里我单独将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍一 ...

  6. mysql语句命令_常用MySQL语句(命令行)

    # 命令行客户端MySQLMySQL是一个关系型数据库管理系统 安装MySQL服务端软件使用: sudo apt-get install mysql-server 安装MySQL客户端软件使用: su ...

  7. mysql 如何提交_提交mysql

    Can't call commit when autocommit=true(转) java.sql.SQLException: Can't call commit when autocommit=t ...

  8. mysql性能视频教程_[视频教程] MySQL性能管理及架构设计 (完整版)

    第1章 实例和故事 决定电商11大促成败的各个关键因素. 1-1 什么决定了电商双11大促的成败 1-2 在双11大促中的数据库服务器 1-3 在大促中什么影响了数据库性能 1-4 大表带来的问题 1 ...

  9. mysql 客户端 交叉编译_移植mysql到嵌入式ARM平台

    移植MySQL到嵌入式ARM平台 MySQL没有专门针对ARM的版本,移植到ARM没有官方文档可参考,因此,暂时参考这样一篇文档: http://blog.chinaunix.net/space.ph ...

  10. mysql核心数据库_从MySQL基础进军MySQL核心架构 178集MySQL数据库核心基础视频教程 MySQL基础案例教程...

    从MySQL基础进军MySQL核心架构 178集MySQL数据库核心基础视频教程 MySQL基础案例教程 课程目录 (1) 01MySQL基础_课程引入.avi (2) 02MySQL基础_为什么学习 ...

最新文章

  1. 微软亚洲研究院王井东:下一代视觉识别的通用网络结构是什么样的?
  2. 一步步分析AI如何玩Flappy Bird
  3. 第十一章:集合(一)
  4. StringBuffer 和 StringBuilder 的 3 个区别!
  5. go项目部署到linux服务器
  6. 机器学习---实战---K-近邻算法--笔记
  7. android动态添加的页面怎么加功能_Android跳转应用安装页面
  8. 借口很多呀嘛接口也很多呀嘛态也很多
  9. redis5 外部不能连接_【硬见小百科】PCB连接的方法
  10. 关于Java基础你不得不会的34个问题
  11. 统计学习方法-李航(2)
  12. idea中,springboot项目部署到docker
  13. redis命令执行流程分析
  14. Java基础学习总结(129)——Arrays.asList得到的List进行add和remove等操作出现异常解析
  15. Java 建模:子整体软件开发
  16. [转]coolfire黑客入门教程系列之(五)
  17. 云宏大讲坛 | 灵活轻便的云宏CNware虚拟防火墙
  18. 关于 chrome 上支付宝安全控件无法使用,以及检测不到数字证书的问题
  19. 使用Python读取Windows注册表
  20. 有这5类人最难成为银行的优质客户!

热门文章

  1. ECS vs K8S
  2. CentOS详解top命令各个数据的含义
  3. Facebook开源计算机视觉目标检测平台Detectron
  4. 解决gradle下载慢的问题
  5. centos7 redis5.0以前版本 集群部署示例 - 第一篇
  6. 工厂三兄弟之简单工厂模式
  7. 项目启动正常,访问网页500怎么办?【思考问题要全面,小问题或许就是问题的关键,小本本记下来!!!】
  8. 什么是Kibana?Kibana安装与配置(win_Elasticsearch)
  9. mybatis实现反向工程
  10. C语言文件操作 给M个数随机分组