前段时间某数据表运行过程中,出现自增字段突然跳跃式增长的问题,潜心研究发现,问题导致原因可能是因为并发写入导致

于是通过各种途径查阅是因为innodb_autoinc_lock_mode参数设置的不同表现所在,于是进行了调整,在此对该参数的理解记录一二。

官方原文地址:https://dev.mysql.com/doc/refman/8.0/en/innodb-auto-increment-handling.html#innodb-auto-increment-initialization

中文翻译地址:https://blog.csdn.net/ashic/article/details/53810319

其文章中主要提及,mysql的3种插入方式以及innodb_autoinc_lock_mode的3种参数选择相关内容

三种模式简要说明

首先,该参数仅在InnoDB引擎下生效,myisam引擎下,无论什么样自增id锁都是表级锁
0:traditonal (每次都会产生表锁)
1:consecutive (mysql的默认模式,会产生一个轻量锁,simple insert会获得批量的锁,保证连续插入)
2:interleaved (不会锁表,来一个处理一个,并发最高)

如何理解,以及参数如何选择?

1、innodb_autoinc_lock_mode为0时的,也就是官方说的traditional级别

该自增锁是表锁级别,且必须等待当前SQL执行完成后或者回滚掉才会释放,这样在高并发的情况下可想而知自增锁竞争是比较大的

2、innodb_autoinc_lock_mode为1时的,也就是官方说的consecutive级别

这时如果是单一的insert SQL,可以立即获得该锁,并立即释放,而不必等待当前SQL执行完成(除非在其他事务中已经有session获取了自增锁)。另外当SQL是一些批量insert sql时,比如insert into ...select ...,load data,replace ..select..时,这时还是表级锁,可以理解成退化为必须等待当前SQL执行完才释放。可以认为,该值为1时是相对比较轻量的锁,也不会对复制产生影响,唯一的缺陷是产生的自增值不一定是完全连续的

3、innodb_autoinc_lock_mode为2时,也就是官方说的interleaved 级别

所有insert种类的SQL都可以立马获得锁并释放,这时的效率最高。但是会引入一个新的问题:当binlog_format为statement时,这时的复制没法保证安全,因为批量的insert,比如insert ..select..语句在这个情况下,也可以立马获取到一大批的自增id值,不必锁整个表,slave在回放这个sql时必然会产生错乱

问题分析

在此我们看到mysql的默认模式是2,官方表示其是连续插入,但实际上在这一模式simple insert做了优化,由于simple insert一次性插入值的个数可以立马得到确定,所以mysql可以一次生成几个连续的值,用于这个insert语句,而只要语句得到了相应的值后就可以提前释放锁,这就导致插入是连续的,但如果插入的语句存在错误的话(本次的值已经被分配,下次会增加),实际上自增的字段可能不连续

也就是说该模式只保证插入的连续性,但自增字段的连续性无法保证,而我们遇到的问题恰恰是要保证自增字段的连续性。

于是综合考虑之后我们启用了0模式,观察一段时间之后发现满足我们的需求,保证了字段的连续性。

至此问题得到解决。

作者:旧旧的 <393210556@qq.com> 解决问题的方式,就是解决它一次

MySQL自增锁模式innodb_autoinc_lock_mode参数理解调优的更多相关文章

  1. MySQL AutoIncrement--自增锁模式

    自增锁模式 在MYSQL 5.1.22版本前,自增列使用AUTO_INC Locking方式来实现,即采用一种特殊的表锁机制来保证并发插入下自增操作依然是串行操作,为提高插入效率,该锁会在插入语句完成 ...

  2. 深入剖析 MySQL 自增锁

    之前的文章把 InnoDB 中的所有的锁都介绍了一下,包括意向锁.记录锁...自增锁巴拉巴拉的.但是后面我自己回过头去看的时候发现,对自增锁的介绍居然才短短的一段. 其实自增锁(AUTO-INC Lo ...

  3. MySQL自增列锁模式 innodb_autoinc_lock_mode不同参数下性能测试

    对于innodb_autoinc_lock_mode 各种参数的值的含义,网上也有各种详解,看完觉得意犹未尽,这里不做阐述,只动手测试,看看性能上,到底有没有理论上所说的差别.对于自增列的锁定,据说是 ...

  4. MySQL自增锁等待问题解决

    有网友再群里问:在做基准测试时候,批量插入数据时,有很多自增锁等待,我告诉他解决办法: 1.innodb_autoinc_lock_mode=2 2.innodb_autoextend_increme ...

  5. Mysql研磨之InnoDB行锁模式

    事务并发带来的一些问题 (1)更新丢失(LostUpdate):当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题最后的更新覆盖了由其 ...

  6. mysql 开发进阶篇系列 7 锁问题(innodb锁争用情况及锁模式)

    1 .获取innodb行锁争用情况 1.1 通过检查innodb_row_lock状态变量来分析系统上的行锁的争夺情况 SHOW STATUS LIKE 'innodb_row_lock%' 通过in ...

  7. 关于mysql中的锁总结

    一.锁的基本信息: 共享锁(s):又称读锁.允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁.若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁 ...

  8. 从一个死锁看mysql innodb的锁机制

    背景及现象 线上生产环境在某些时候经常性的出现数据库操作死锁,导致业务人员无法进行操作.经过DBA的分析,是某一张表的insert操 作和delete操作发生了死锁.简单介绍下数据库的情况(因为涉及到 ...

  9. MySQL事务与锁

    MySQL事务与锁 锁的基本概念 锁是计算机协调多个进程或线程并发访问某一资源的机制. 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISA ...

随机推荐

  1. CodeForces:#448 div2 B. XK Segments

    传送门:http://codeforces.com/contest/895/problem/B B. XK Segments time limit per test1 second memory li ...

  2. 笔记-python-内存管理

    笔记-python-内存管理 1.      内存使用 1.1.    对象的内存使用 a = 1 1是一个对象,a是引用,指向1. >>> id(a) 1951821280 这个数 ...

  3. sql中比较大小

    if object_id('tempdb..#dataOldNew1') is not null drop table #dataOldNew1 select distinct store_cd ,i ...

  4. day20 Django Models 操作,多表,多对多

    1 Django models 获取数据的三种方式: 实践: viwes def business(request): v1 = models.Business.objects.all() v2 = ...

  5. python3与django中@property详解

    django提供了内置装饰器 @staticmethod\@classmethod\property 在OSQA中,@property的使用频率是非常高的.下面就是它的使用方法: @property ...

  6. 【Gas Station】cpp

    题目: There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. ...

  7. IOS开发学习笔记012-核心语法

    1.点语法 2.成员变量的作用域 3. @property和@synthesize 4.id类型 5.构造方法 6.自定义构造方法 7.模板修改 8.Category - 分类 9.类扩展 一.点语法 ...

  8. plsql编程

    ORACLE PL/SQL编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设计语言,该 ...

  9. Android EditText禁止换行键(回车键enter)

    在EditText所在的xml文件中,设置android:singleLine="true", 则可以禁止掉虚拟键盘: maxlength为该EditText的最大输入长度: &l ...

  10. Github新手使用学习详解

    Github新手使用学习详解 (一)git的使用学习 首先下载git bash,安装一路默认选择即可. 安装好后第一步,获取ssh key,即属于自己的密钥: 打开Git bash后输入以下代码: $ ...