1. 首页
  2. mysql面试题

03-三、MySQL 面试题 InnoDB AUTO_INCREMENT ( 中 )

上一章节中,我们介绍了 innodb_autoinc_lock_mode = 0 传统锁模式,知道了在传统锁模式下,所有的 「 insert like 」 语句都会获得一个特殊的 表级 AUTO-INC 锁,这种锁会自动添加到 SQL 语句的末尾 ( 不是事务的末尾 ),以确保以可预测且可重复的顺序为给定的 INSERT 语句序列分配自增值,并确保为任何给定语句分配的自增值都是连续的

今天,我们就来看看剩下的两种模式是怎么样的

innodb_autoinc_lock_mode = 1 连续锁模式

在此 「 连续锁 」 模式下,「 批量插入 」会首先获取一个特殊的表级 AUTO_INC 锁,并一直保持到所有语句执行结束才释放。连续锁模式适用于所有的批量插入语句,包括 INSERT ... SELECTREPLACE ... SELECTLOAD DATA 语句。

Innodb 存储引擎一次只会执行一个持有 AUTO-INC 锁的 SQL 语句。

如果批量插入操作的源表与目标表不同,则会先在源表中选择的第一行上执行共享锁,然后对目标表执行 AUTO-INC 锁。如果批量插入操作的源表和目标表是同一个表,则会先对所有选定的行执行共享锁之后再执行 AUTO-INC

简单插入 「 Simple inserts 」 ( 即预先知道要插入的行数 ) 则是不同的,它会在互斥锁 ( 一个轻量级的锁 ) 的控制下获得所需数量的自增量值来避免表级 AUTO-INC 锁定。但这种获得自增值的互斥锁只在分配过程的持续时间内持有,而不是在语句完成之前。除非另一个事务首先持有 AUTO-INC 锁,否则不使用表级 AUTO-INC 锁。如果另一个事务持有 AUTO-INC 锁,则 「 简单插入 」会一直等待直到自己获得 AUTO-INC 锁,就好像它自己也是批量插入一样

这种锁定模式可以确保,在存在 INSERT 语句情况下,纵使事先不知道行数 ( 以及在语句执行时分配的自增值数 ),任何由 「 INSERT-like 」 分配的所有自增值都是连续的,且确保对基于语句的复制操作是安全的。

简而言之,这种锁模式显着提高了可伸缩性,同时可以安全地进行基于语句的复制。此外,与 「 传统锁」 模式一样,可以确保为任何给定语句分配的自增值数字是连续的。

从某些方面说,与 「 传统锁 」 模式相比,对于任何使用自增值的语句,语义并没有变化,除了下面这个重要的例外

这个例外就是 「 混合模式插入 」 (mixed-mode inserts ) , 在混合模式插入中,那些多行的 「 简单插入 」中的某些行 ( 但不是所有行 ) 会显式为 AUTO\_INCREMENT 列提供一个值。对与这种插入模式,InnoDB 会分配比要插入的行数更多的自增值。

但这样也存在一个问题 ( 可以被忽略的问题 ),因为自动分配的所有值都是连续生成,因此可能高于最后执行的语句生成的自增值,也就是超过的没用到的自增值则被丢失了。

innodb_autoinc_lock_mode = 2 交错锁模式

在 「 交错锁 」模式下,任何 「 INSERT-like 」语句都不会使用表级 AUTO-INC 锁,且多个语句可以同时执行。

这是最快且可扩展性最强的锁模式,但在二进制日志重放 SQL 语句中,会让使用基于语句

的复制或恢复方案变得不安全。

这种锁模式,会确保自增值是唯一的,且可以在所有同时执行的 「 INSERT-like 」 语句中保持单调递增

当然了,这种锁模式也是有缺点的,因为多个语句可以同时生成数字 (即自增值数字的分配会在语句之间交错进行 ) ,会造成任何给定语句插入的行生成的值可能不是连续的

结束语

好复杂的 AUTO-INC 锁模式,翻译的我都头痛了,虽然在翻译的时候知道是啥意思,但是自己写出来,真的是一头雾水。

简单理解这三种锁模式

1、 传统锁模式 – 不管三七二十一,先用表级的 AUTO-INC 锁,直到语句插入完成,然后释放锁
2、 连续锁模式 – 不管三七二十一,先用互斥锁,然后生成所有插入行需要的自增值,然后释放互斥锁,最后使用这些自增值来插入数据。对于行数未知的,那就只能使用 「 传统锁 」 模式了,先锁起来,执行完毕了再释放,因为人家不知道要生成多少自增值啊
3、 交错模式 – 管它刮风下雨,需要的时候再生成,也管它连续与否,用了就是了…

希望读者能够给小编留言,也可以点击[此处扫下面二维码关注微信公众号](https://www.ycbbs.vip/?p=28 "此处扫下面二维码关注微信公众号")

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「方志朋」,公众号后台回复「666」 免费领取我精心整理的进阶资源教程
  4. JS中文网,Javascriptc中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,是给开发者用的 Hacker News,技术文章由为你筛选出最优质的干货,其中包括:Android、iOS、前端、后端等方面的内容。目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。

    本文著作权归作者所有,如若转载,请注明出处

    转载请注明:文章转载自「 Java极客技术学习 」https://www.javajike.com

    标题:03-三、MySQL 面试题 InnoDB AUTO_INCREMENT ( 中 )

    链接:https://www.javajike.com/article/1607.html

« 04-四、MySQL 面试题 InnoDB AUTO_INCREMENT ( 下 )
02-二、MySQL 面试题 InnoDB AUTO_INCREMENT ( 上 )»

相关推荐

QR code