专栏名称: 数据分析与开发
伯乐在线旗下账号,分享数据库相关技术文章、教程和工具,另外还包括数据库相关的工作。偶尔也谈谈程序员人生 :)
目录
相关文章推荐
数据中心运维管理  ·  冷却分配单元:液冷系统的核心 ·  4 天前  
数据中心运维管理  ·  国家标准《数据中心设计标准》修订工作正式启动 ·  2 天前  
数据中心运维管理  ·  国内首个洞库式数据中心!贵安腾讯七星数据中心 ... ·  昨天  
Java知音  ·  MyBatis批量插入几千条数据,请慎用fo ... ·  昨天  
数据分析与开发  ·  强烈建议尽快搞个软考证!(重大利好) ·  1 周前  
51好读  ›  专栏  ›  数据分析与开发

一次离奇的 MySQL 死锁分析

数据分析与开发  · 公众号  · 数据库  · 2016-11-18 20:10

正文

(点击上方公众号,可快速关注)


来源:李晶莹

链接:http://blog.jobbole.com/107817/


1、故事起因于2016年11月15日的一个生产bug。业务场景是:归档一个表里边的数据到历史表里边,同是删除主表记录。


2、背景场景简化如下(数据库引擎InnoDb,数据隔离级别RR[REPEATABLE])


-- 创建表test1

CREATE TABLE test1 (

id int(11) NOT NULL AUTO_INCREMENT,

name varchar(10) NOT NULL,

PRIMARY KEY (id)

);

insert into test1 values('hello');

 

-- 创建表test2

CREATE TABLE test2 (

id int(11) NOT NULL AUTO_INCREMENT,

name varchar(10) NOT NULL,

PRIMARY KEY (id)

);

 

-- Transcation 1

begin;

insert into test2 select * from test1 where id = 1;

delete from test1 where id = 1;

 

-- Transcation 2

begin;

insert into test2 select * from test1 where id = 1;


3、具体执行顺序


Transcation1Transcation2
begin;
— 这条sql得到test1表主键索引锁共享锁S(id=1) insert into test2 select * from test1 where id = 1;


begin;
— 这条sql试图获取test1表主键索引锁共享锁S(id=1),但是已经被T1占有,所以它进入锁请求队列.
insert into test2 select * from test1 where id = 1;
— 这条sql试图把自己拥有的test1表主键索引锁共享锁S(id=1)升级为排它锁X(id=1)
— 这时T1也发起一个锁请求,这个时候mysql发现锁请求队列里边已存在一个事物T2对(id=1)的这条记录申请了S锁,死锁产生了。
delete from test1 where id = 1;


死锁产生后mysql根据两个事务的权重,事务2的权重更小,被选为死锁的牺牲者,rollback。
T2 rollback 之后T1成功获取了锁执行成功


Mysql 官方解释


Deadlock occurs here because client A needs an X lock to delete the row. However, that lock request cannot be granted because client B already has a request for an X lock and is waiting for client A to release its S lock. Nor can the S lock held by A be upgraded to an X lock because of the prior request by B for an X lock. As a result, InnoDBgenerates an error for one of the clients and releases its locks. The client returns this error。


实际场景和mysql文档有些区别,文档里边要获取的是X锁。具体事例里边要获取的是S锁。


Mysql 官方文档:http://dev.mysql.com/doc/refman/5.7/en/innodb-deadlock-example.html



关注「数据库开发」

看更多精选数据库技术文章

↓↓↓