Mysql之AUTO_INCREMENT浅析

2023-11-03 05:38

本文主要是介绍Mysql之AUTO_INCREMENT浅析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 术语
    • 锁模式
    • 注意点
    • 总结
    • 参考链接

AUTO_INCREMENT用于为表中的列设置一个自增序列,在非集群模式下,用它来为主键列自动生成值是一件很方便的事。并且,Mysql提供了一系列的锁机制来保证它的性能跟可靠性,通过这些锁机制,我们可以让它变得很高效。

术语

先来了解后面将要用到的术语。

  • Simple inserts

    能预先知道插入行数的语句。比如说单行插入(不包括INSERT … ON DUPLICATE KEY UPDATE),不带子句的多行插入(自增列不赋值或全赋值)。

  • Bulk inserts

    不能能预先知道插入行数的语句。比如INSERT … SELECT, REPLACE … SELECT 。这种模式下,InnoDB 会在处理时为每一行的自增列一次分配一个自增值

  • Mixed-mode inserts

    INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d');
    

    INSERT … ON DUPLICATE KEY UPDATE

  • Insert-like

    以上所有插入语句的统称

锁模式

锁模式在启动时通过innodb_autoinc_lock_mode这个变量来配置,它有3个值:0, 1, 2。分别对应traditional(传统)、consecutive(连续)、interleaved(交错)3种模式。

Mysql5.6~5.7里,这个配置项的默认值是1,从Mysql8开始,它的默认值2。这个一方面是因为模式2的性能更好,另一方面是因为从Mysql8开始,默认的主从复制的方式由statement-based 改为了row basedrow based 能保证innodb_autoinc_lock_mode=2时主从复制时的数据不会出现不一致的问题。好了,下面开始详细了解这三种锁模式吧!

  • traditional

    在这种模式下,Mysql所有的Insert-like操作都会设置一个表级别的AUTO-INC 锁,这个锁会在单条语句执行完毕时释放。

    也就是说,如果有多个事务同时对同一张表执行Insert-like 操作,那么,即使它们没有操作同一条记录,也会串行执行。所以,它的性能相对另外两种模式来说会比较糟糕。

  • consecutive

    在这种模式下,对于Simple inserts语句,Mysql会在语句执行的初始阶段将一条语句需要的所有自增值会一次性分配出来,并且通过设置一个互斥量来保证自增序列的一致性,一旦自增值生成完毕,这个互斥量会立即释放,不需要等到语句执行结束。

    所以,在consecutive模式,多事务并发执行Simple inserts这类语句时, 相对traditional模式,性能会有比较大的提升。

    由于一开始就为语句分配了所有需要的自增值,那么对于像Mixed-mode inserts这类语句,就有可能多分配了一些值给它,从而导致自增序列出现"空隙"。而traditional模式因为每一次只会为一条记录分配自增值,所以不会有这种问题。

    另外,对于Bulk inserts语句,依然会采取AUTO-INC锁。所以,如果有一条Bulk inserts语句正在执行的话,Simple inserts也必须等到该语句执行完毕才能继续执行。

  • interleaved

    在这种模式下,对于所有的Insert-like语句,都不会存在表级别的AUTO-INC锁,意味着同一张表上的多个语句并发时阻塞会大幅减少。

    但是,这种模式必须运行在row based或者mixed-format(其实说白了也是row based,只不过mysql会根据自增模式为不安全的语句自动选择row based模式)复制模式下。因为interleaved这种模式下对于相同顺序的语句每次执行行都会产生不同的结果(谁竞争到互斥量,谁就能获得生成自增值的权利),所以,如果复制模式是statement-based或者通过binlog进行数据恢复时(牵扯到binlog的语句重放),可能会导致数据不一致。

注意点

  • 自增值的生成后是不能回滚的,所以自增值生成后,事务回滚了,那么那些已经生成的自增值就丢失了,从而使自增列的数据出现空隙

  • 正常情况下,自增列是不存在0这个值的。所以,如果插入语句中对自增列设置的值为0或者null,就会自动应用自增序列。

    那么,如果想在自增列中插入为0这个值,怎么办呢?可以通过将SQL Mode设置为NO_AUTO_VALUE_ON_ZERO即可

  • 在Mysql5.7以及更早之前,自增序列的计数器(auto-increment counter)是保存在内存中的。auto-increment counter在每次Mysql重新启动后通过类似下面的这种语句进行初始化:

    SELECT MAX(AUTO_INC_COLUMN) FROM table_name FOR UPDATE
    

    而从Mysql8开始,auto-increment counter被存储在了redo log中,并且每次变化都会刷新到redo log中。另外,我们可以通过ALTER TABLE … AUTO_INCREMENT = N 来主动修改
    auto-increment counter

总结

  1. 单实例下,可以设置innodb_autoinc_lock_mode=2
  2. 主从
    1. 复制模式为statement-based,设置innodb_autoinc_lock_mode=1
    2. 复制模式为row based或者mixed-format,设置innodb_autoinc_lock_mode=2

参考链接

  • 15.6.1.6 AUTO_INCREMENT Handling in InnoDB
  • 15.18.2 InnoDB Recovery
  • 17.5.1.1 Replication and AUTO_INCREMENT
  • 3.6.9 Using AUTO_INCREMENT

这篇关于Mysql之AUTO_INCREMENT浅析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/335958

相关文章

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

Mysql中设计数据表的过程解析

《Mysql中设计数据表的过程解析》数据库约束通过NOTNULL、UNIQUE、DEFAULT、主键和外键等规则保障数据完整性,自动校验数据,减少人工错误,提升数据一致性和业务逻辑严谨性,本文介绍My... 目录1.引言2.NOT NULL——制定某列不可以存储NULL值2.UNIQUE——保证某一列的每一

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

解密SQL查询语句执行的过程

《解密SQL查询语句执行的过程》文章讲解了SQL语句的执行流程,涵盖解析、优化、执行三个核心阶段,并介绍执行计划查看方法EXPLAIN,同时提出性能优化技巧如合理使用索引、避免SELECT*、JOIN... 目录1. SQL语句的基本结构2. SQL语句的执行过程3. SQL语句的执行计划4. 常见的性能优

SQL Server 中的 WITH (NOLOCK) 示例详解

《SQLServer中的WITH(NOLOCK)示例详解》SQLServer中的WITH(NOLOCK)是一种表提示,等同于READUNCOMMITTED隔离级别,允许查询在不获取共享锁的情... 目录SQL Server 中的 WITH (NOLOCK) 详解一、WITH (NOLOCK) 的本质二、工作

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND

SQL Server安装时候没有中文选项的解决方法

《SQLServer安装时候没有中文选项的解决方法》用户安装SQLServer时界面全英文,无中文选项,通过修改安装设置中的国家或地区为中文中国,重启安装程序后界面恢复中文,解决了问题,对SQLSe... 你是不是在安装SQL Server时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也