[MySQL Bug]bug#61209简析

—————————————————

MySQL bug#61209,changelog如下,在5.5.23被fix

InnoDB: Running concurrent bulk inserts on a server with auto_increment_offset=1,auto_increment_increment greater than 1, and innodb_autoinc_lock_mode=1 could result in intermittent errors like the following, even with the primary key set to auto_increment and omitted from the INSERT statement:

 

Duplicate entry 'value' for key 'PRIMARY'

The workaround was to set auto_increment_offset=1 or innodb_autoinc_lock_mode=0 (“traditional”). (Bug #13817703, Bug #61209)

 

之前已经介绍过了innodb 如何处理auto inc的代码流程,现在来看看在innobase_next_autoinc里是如何来计算的。

假定我们设置:

set global  auto_increment_increment=3;

set global auto_increment_offset=2;

例如对于一条简单的SQL:insert into tt values (NULL),(NULL)

 

函数innobase_next_autoinc的参数:

–current   当前的值                                     (1)

–increment  申请保留的区间长度                  (6)

–offset      auto_increment_offset的值         (2)

–max_value    该自增列类型最大容许的值      (2147483647)

 

1.当offset > increment时,设置offset=0,也就是忽略掉auto_increment_offset

2.确定next_value的值

a.当max_value <= current时,next_value = max_value; (溢出)

b.当offset<=1时(1或0视为等同):

如果max_value – current <= increment ,  next_value = max_value; (溢出)

否则next_value = current + increment 

c.当max_value > current,且offse>1时

next_value = ((|current – offset| / increment) + 1)*increment+offset

可以看出来代码逻辑还是很简单的

现在在来看看test case

session 1

SQL1:insert into tt values (NULL),(NULL);

{interval_min = 2, interval_values = 2, interval_max = 8, next = 0x0}

innobase_next_autoinc的返回值为((1-2)/6+1)*6+2=8

table->autoinc=8

插入记录2,5

SELECT GET_LOCK(‘a’, 100);

session 2

SQL2:INSERT INTO tt (a) VALUES (NULL), (NULL), (NULL + GET_LOCK(‘a’, 1800));  

{interval_min = 8, interval_values = 3, interval_max = 17, next = 0x0}

调用函数innobase_next_autoinc两次

第一次返回值((8-2)/9+1)*9+2=11

table->autoinc=11

第二次调用是在写第3个记录时(在write_row函数中调用)

返回值为(((table->autoinc-auto_increment_offset)/auto_increment_increment+1))* auto_increment_increment+ auto_increment_offset

=((11-2)/3+1)*3+2=14

table->autoinc=14

在尝试插入第三个记录时会block住

session 1

SQL3:INSERT INTO tt (a) VALUES (NULL), (NULL), (NULL);

{interval_min = 14, interval_values = 3, interval_max = 23, next = 0x0}

同样调用函数innobase_next_autoinc两次

第一次返回值为20

第二次返回值为24

插入记录14,17,20

而每个预留区间的最小值是和table->auto_inc相关的,显然这里自增值发生了错乱,SQL3应该从17开始而不是14

官方patch请点击这里

主要修改了innobase_next_autoinc函数

SQL1的返回值为8

SQL2的返回值为17

SQL3的返回值为26

实际上稍微扩大了table->auto_inc的值,以避免出现交叉。加上patch后的innobase_next_autoinc函数的参数修改为:

–current     当前值

–need         需要自增值的个数

–step          auto_increment_increment

–offset        auto_increment_offset

–max_value   该自增类型的最大可能值

next_value=(|offset – current| / step)

next_value*=step

next_value+=( need * step +offset)

因此

 

SQL1的返回值为8 (|2-1|/3=0; 0*3; 0+2*3+2=8)

SQL2的返回值为17(|2-8|/3=2;2*3=6;6+3*3+2=17)

SQL3的返回值为26(|2-17|/3=5;5*3=15;15+3*3+2=26)

 

这样就可以保证table->autoinc的值不会重叠了。

时间: 2024-10-23 18:43:13

[MySQL Bug]bug#61209简析的相关文章

mysql存储过程事务管理简析_Mysql

ACID:Atomic.Consistent.Isolated.Durable 存储程序提供了一个绝佳的机制来定义.封装和管理事务. 1,MySQL的事务支持 1)MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关: Sql代码 复制代码 代码如下: MyISAM:不支持事务,用于只读程序提高性能 InnoDB:支持ACID事务.行级锁.并发 Berkeley DB:支持事务 MyISAM:不支持事务,用于只读程序提高性能 InnoDB:支持ACID事务.行级锁.并发 Ber

MySQL事务处理与应用简析_Mysql

事务处理在各种管理系统中都有着广泛的应用,比如人员管理系统,很多同步数据库操作大都需要用到事务处理.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!删除的SQL语句delete from userinfo where ~~~delete from mail where ~~delete from article where~~~~如果没有事务处理,在你删除的过程中,假设出错了,只执行了第一

[MySQL Bug] bug#65111碎碎念

changelog里的描述: InnoDB: In a transaction using the REPEATABLE READ isolation level, an UPDATE or DELETE statement for anInnoDB table could sometimes overlook rows recently committed by other transactions. As explained inSection 14.3.9.2, "Consistent N

大数据相关概念的界定与简析

通过对大数据相关概念进行明确界定,企业可以正确地规划自己的数据体系,并且对传统的技术方法与新兴的技术方法进行合适地定位. IT技术迅猛发展,新技术层出不穷,但业界却普遍对许多基本概念产生混淆.在当今最为流行的大数据领域也出现了这样的情况.结构化数据.非结构化数据等概念被频繁引用,却各方往往各执一词.对数据概念的混淆已经在很大程度上影响了企业对其数据体系进行清晰.正确的规划.本文的作者从实际工作出发,试图对一些关键的大数据相关概念给出明确的定义,并进行简要的解析. 一.按数据特征分类 ■结构化数据

Rails系统中的AJAX开发技术简析(2)

ajax|rails 五. 使用link_to_remote Rails有若干帮助者方法以在你的视图的模板中实现Ajax.一种最简单且很通用的方法就是link_to_remote().让我们考察一个简单的web页面-它实现询问时间并且有一个链接,用户可以点击这个链接来获得当前的时间.该应用程序经由link_to_remote()使用Ajax以检索时间并且显示它于web页面. 我的视图模板(index.rhtml)看起来象: <html><head><title>Ajax

Rails系统中的AJAX开发技术简析(3)

ajax|rails 六. 使用form_remote_tag 这个form_remote_tag()帮助函数与link_to_remote()很相似,除了它也发送一个HTML表单的内容之外.这意味着该行动处理器可以使用用户输入的数据来形成响应.这个实例显示了一个web页面-它有一个列表和一个支持Ajax的表单-该表单能够让用户添加一些选项到该列表中. 我的视图模板(index.rhtml)看上去象: <html><head><title>Ajax List Demo&

简析JAVA的XML编程

xml|编程  个人认为这篇文章通俗易懂,值得推荐.    XML作为全球通用的结构化语言,越来越受人们青睐,各种开发平台(比如Microsoft Studio系列.Oracle系列.Inprise Borland系列等)也都把支持XML开发作为宣传口号之一 .由于笔者所从事的电子政务开发较早的引入了XML,所以尝到了许多甜头,在许多项目中利用XML数据交换信息,省去了许多麻烦事,不用制定繁锁的数据格式,利用XML数据易于表达,也利于一线开发者跟踪调试.         笔者先前也曾发表过相关的

ORA-12913: 错误简析,及处理心得

错误|心得                                    ORA-12913: 错误简析,及处理心得     事先声明,因为工作变动,偶有整一年没有摸过ORACLE了,呵呵    昨天晚上装完ORACLE后,准备创建属于自己的表空间的时候,出现了ORA-12913: 无法创建字典管理的表空前. 当然了,故障排除很简单,找到文档,看一眼就排除了. 但既然在ORACLE9I之后,系统缺省安装时为本地管理表空间(Local Managed Tablespace)LMT,好处多多

ug建模以后有限元分析的步骤简析

  ug建模以后有限元分析的步骤简析.许多正在学习ug这个软件的网友最近都在议论一个问题,那就是:ug怎么进行有限元分析.要解决这个问题,我们需要先来了解一下什么是ug有限元分析.而网上关于ug有限元分析的教程还是挺多的,但是,小编总结了一下规律之后发现,ug有限元分析的步骤基本上离不开8个步骤,下面,就一起来看看今天的ug建模以后有限元分析的步骤简析! ug有限元分析 推荐:ug4.0软件下载 什么是ug有限元分析? 有限元分析(FEA,Finite Element Analysis)利用数学