$mysql-VmysqlVer14.12Distrib5.0.81,forunknown-linux-gnu(x86_64)usingEditLinewrapper
表结构:
(二).还有一种情况是负责mysql死锁检测的是一个递归函数lock_deadlock_recursive(),当递归的深度depth超过LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK和cost超过LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK两个内部变量的时候,mysql就会抛出死锁信息;
从showinnodbstatus中deadlock的信息来看:
(1).transaction1显示了正在向occur_dead_lock_table中插入一行数据,它正在等待获得表上的索引ind_occur_dead_lock_table的一个x锁(lock_modeXlocksgapbeforerecinsertintentionwaiting);(2).transaction2的信息包括两部分:已经持有的锁和正在等待的锁;已持有的锁为一个向occur_dead_lock_table表中插入记录的时候,在其索引上获得的X锁;正在等待的锁为在表occur_dead_lock_table上的一个AUTO-INC锁;
上面的一个信息中很重要的一个锁等待为事务2在等待auto-inc锁,下面我们来分析一下在mysql中auto-increment列的实现:
5.0(5.1.22以下)和5.1(5.1.22以上)在自增列上的实现方式:
a.在5.0(5.1.22以下),auto_increment的实现机制为在innodb存储引擎的内存结构中维护一个自增长计数器,该计数器的值由:Selectmax(auto_inc_col)fromtforupdate得到,插入操作首先从这个计数器中得到值,然后赋予自增长列(auto_inclocking),可以看到这个锁本质上是一种表锁,那么其缺点就是必须等待前一个插入完成后,这样在大并发下,其插入性能的并发性不然较差;b.在5.1(5.1.22以上)中增加了另外一种实现机制,在innodb引擎中提供了一种轻量级互斥量(mutex)的自动增长机制,对于普通的insert操作,innodb用一个mutex去对内存中的计数器进行累加,去掉了对原表的表锁机制,无疑会对部分插入提高较大的性能,该机制在5.1(5.1.22以上)中为自增长值实现的默认方式;
Thereisanewinnodb_autoinc_lock_modesystemvariabletoconfigurethelockingbehaviorthatInnoDBusesforgeneratingauto-incrementvalues.Thedefaultbehaviornowisslightlydifferentfrombefore,whichinvolvesaminorincompatibilityformultiple-rowinsertsthatspecifyanexplicitvaluefortheauto-incrementcolumninsomebutnotallrows.
“SHOWINNODBSTATUSdeadlockinfoincorrectwhendeadlockdetectionaborts”.Printthecorrectlockownerwhenrecursivefunctionlock_deadlock_recursive()exceedsitsmaximumdepthLOCK_MAX_DEPTH_IN_DEADLOCK_CHECK.
综上所述,将版本从5.0升级到5.1的版本(5.1.48或者5.1.61)是不错的选择,同时在业务上可以考虑选择由应用程序产生了一个序列值来插入到数据库中,代替数据库的auto_incement。