首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Innodb主键和辅助索引的更新锁顺序

Innodb主键和辅助索引的更新锁顺序
EN

Stack Overflow用户
提问于 2016-06-30 07:48:14
回答 1查看 836关注 0票数 1

当我研究由两个更新查询引起的死锁时。这是有道理的,我不明白。1.行锁设置顺序? 2.主索引和辅助索引上的锁设置顺序,当更新执行时? 3.显示INNODB状态显示等待的x锁结构,它是同时需要的还是在其他授予之后需要的? 4.如果一个锁结构不想锁某些行,进程是原子的吗?

下面是我的死锁:表:

代码语言:javascript
复制
CREATE TABLE `study_update_deadlock` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `u_key` bigint(20) DEFAULT NULL,
    `nu_key` bigint(20) DEFAULT NULL,
    `version` int(11) DEFAULT NULL,
    `quantity` int(11) DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `nu_key` (`nu_key`),
    KEY `u_key` (`u_key`)
) ENGINE=InnoDB AUTO_INCREMENT=5000001 DEFAULT CHARSET=latin1 COMMENT='根据非唯一主键更新是发生死锁'

更新查询1:

代码语言:javascript
复制
update study_update_deadlock set version=version+1 where u_key=1663577608119220637 and nu_key=12498159

更新查询2:

代码语言:javascript
复制
update study_update_deadlock set quantity=quantity+1 where u_key=1470344318505049187 and nu_key=12498159

DB ExampleRows中的若干行

方案的关键:

  1. 根据nu_key索引更新
  2. 两个查询更新不同的行,但两行具有相同的nu_key索引
  3. TRX1锁等待5锁结构?是否将所有锁要求添加到锁图中?
  4. TRX2持有PrimaryKey,并等待锁定nu_key索引。但是根据我所知道的先设置索引锁,锁要求不是原子的吗?
  5. 隔离等级:RR

DeadLock显示INNODB状态

代码语言:javascript
复制
2016-06-29 18:58:32 700001f3b000
*** (1) TRANSACTION:
TRANSACTION 76027, ACTIVE 0 sec fetching rows
mysql tables in use 3, locked 3
LOCK WAIT 5 lock struct(s), heap size 1184, 8 row lock(s)
MySQL thread id 33311, OS thread handle 0x700001ab7000, query id 204129 localhost root updating
update study_update_deadlock set quantity = quantity+1 where u_key= 1470344318505049187 and nu_key=12498159
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 16 page no 22255 n bits 392 index `PRIMARY` of table `test`.`study_update_deadlock` trx id 76027 lock_mode X locks rec but not gap waiting
Record lock, heap no 255 PHYSICAL RECORD: n_fields 7; compact format; info bits 0
 0: len 4; hex 8036731e; asc  6s ;;
 1: len 6; hex 0000000128fa; asc     ( ;;
 2: len 7; hex 770000179e081e; asc w      ;;
 3: len 8; hex 97163705443d799d; asc   7 D=y ;;
 4: len 8; hex 8000000000beb4ef; asc         ;;
 5: len 4; hex 800000bb; asc     ;;
 6: len 4; hex 8000005a; asc    Z;;

*** (2) TRANSACTION:
TRANSACTION 76028, ACTIVE 0 sec starting index read
mysql tables in use 3, locked 3
4 lock struct(s), heap size 1184, 3 row lock(s)
MySQL thread id 33312, OS thread handle 0x700001f3b000, query id 204130 localhost root updating
update study_update_deadlock set version = version+1 where u_key= 1663577608119220637 and nu_key=12498159
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 16 page no 22255 n bits 392 index `PRIMARY` of table `test`.`study_update_deadlock` trx id 76028 lock_mode X locks rec but not gap
Record lock, heap no 255 PHYSICAL RECORD: n_fields 7; compact format; info bits 0
 0: len 4; hex 8036731e; asc  6s ;;
 1: len 6; hex 0000000128fa; asc     ( ;;
 2: len 7; hex 770000179e081e; asc w      ;;
 3: len 8; hex 97163705443d799d; asc   7 D=y ;;
 4: len 8; hex 8000000000beb4ef; asc         ;;
 5: len 4; hex 800000bb; asc     ;;
 6: len 4; hex 8000005a; asc    Z;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 16 page no 22336 n bits 952 index `nu_key` of table `test`.`study_update_deadlock` trx id 76028 lock_mode X waiting
Record lock, heap no 660 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 8; hex 8000000000beb4ef; asc         ;;
 1: len 4; hex 8036731c; asc  6s ;;

*** WE ROLL BACK TRANSACTION (2)
EN

回答 1

Stack Overflow用户

发布于 2016-08-12 04:49:51

这是由间隙锁和记录锁造成的。GDB欺骗mysql源代码可以发现,MySQL内部DOC有一些KeyPoint,但丢失了一些细节。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38116980

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档