你的位置:首页 > 数据库

[数据库]mysql死锁

出处:kelvin19840813 的博客 http://www.cnblogs.com/kelvin19840813/

您的支持是对博主最大的鼓励,感谢您的认真阅读。本文版权归作者所有,欢迎转载,但请保留该声明。

 

转载wiki:   https://zh.wikipedia.org/wiki/%E6%AD%BB%E9%94%81

死锁(英语:Deadlock),又译为死结,计算机科学名词。当两个以上的运算单元,双方都在等待对方停止运行,以获取系统资源,但是没有一方提前退出时,这种状况,就称为死锁。在多任务操作系统中,操作系统为了协调不同进程,能否获取系统资源时,为了让系统运作,就必须要解决这个问题。

这里指的是进程死锁,是个计算机技术名词。它是操作系统或软件运行的一种状态:在多任务系统下,当一个或多个进程等待系统资源,而资源又被进程本身或其它进程占用时,就形成了死锁。有个变种叫活锁。

简介
例如,一个进程 p1占用了显示器,同时又必须使用打印机,而打印机被进程p2占用,p2又必须使用显示器,这样就形成了死锁。

死锁的预防
如果系统中只有一个进程,当然不会产生死锁。如果每个进程仅需求一种系统资源,也不会产生死锁。不过这只是理想状态,在现实中是可遇不可求的。

死锁的四个条件是:

禁止抢占:no preemption

持有和等待:hold and wait

互斥:mutual exclusion

循环等待:circular waiting

预防死锁就是至少破坏这四个条件其中一项,即破坏“禁止抢占”、破坏“持有等待”、破坏“资源互斥”和破坏“循环等待”。

死锁的避免
我们也可以尝试回避死锁。因为在理论上,死锁总是可能产生的,所以操作系统尝试监视所有进程,使其没有死锁。

死锁的消除
最简单的消除死锁的办法是重启系统。更好的办法是终止一个进程的运行。

同样也可以把一个或多个进程回滚到先前的某个状态。如果一个进程被多次回滚,迟迟不能占用必需的系统资源,可能会导致进程饥饿。

 

下面给出一个show engine innodb status定位那条记录导致是死锁的案例:

 

1. 表结构如下:

CREATE TABLE `post_76` (
`pid` int(10) unsigned NOT NULL COMMENT '帖子id',
`fid` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT '论坛id',
`tid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '主题id',
`first` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否是首贴',
`author` varchar(15) NOT NULL DEFAULT '' COMMENT '作者姓名',
`authorid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '作者id',
`reppost` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '引用回复的pid',
`invisible` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否通过审核',
`dateline` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '发表时间',
`shieldtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '屏蔽时间',
`message` mediumtext CHARACTER SET utf8mb4 NOT NULL COMMENT '消息',
`useip` varchar(15) NOT NULL DEFAULT '' COMMENT '发帖者IP',
`attachment` tinyint(1) NOT NULL DEFAULT '0' COMMENT '附件',
`anonymous` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否为匿名回复',
`status` int(10) NOT NULL DEFAULT '0' COMMENT '帖子状态',
`position` int(8) unsigned NOT NULL DEFAULT '1' COMMENT '帖子位置信息',
`source` tinyint(3) NOT NULL DEFAULT '0' COMMENT '帖子来源,0=Qzone,1=Android,2=Iphone',
PRIMARY KEY (`pid`),
KEY `fid` (`fid`),
KEY `authorid` (`authorid`,`invisible`),
KEY `invisible` (`invisible`),
KEY `reppost` (`reppost`),
KEY `displayorder` (`tid`,`dateline`),
KEY `status` (`status`,`shieldtime`),
KEY `idx_tid_position` (`tid`,`position`),
KEY `idx_tid_first_dateline` (`tid`,`first`,`dateline`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='帖子表'

 

2. show engine innodb status输出:

------------------------
LATEST DETECTED DEADLOCK
------------------------
2016-08-24 14:48:44 7f7b1f9db700
*** (1) TRANSACTION:
TRANSACTION 70672124, ACTIVE 46 sec fetching rows
mysql tables in use 1, locked 1
LOCK WAIT 6 lock struct(s), heap size 1184, 9 row lock(s)
MySQL thread id 30, OS thread handle 0x7f7b1fd26700, query id 5293 IP地址 root Searching rows for update
update post_76 set position = position - 1 where (tid = 16326635 and position>15)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 5495 page no 1437 n bits 120 index `PRIMARY` of table `db_name`.`post_76` trx id 70672124 lock_mode X locks rec but not gap waiting
Record lock, heap no 41 PHYSICAL RECORD: n_fields 19; compact format; info bits 32
0: len 4; hex 0e7f48f2; asc H ;;          这个是第1个字段也是主键: 16进制转成10进制是 243222770 
1: len 6; hex 000004365efb; asc 6^ ;;
2: len 7; hex 5200000f1b1055; asc R U;;
3: len 3; hex 000037; asc 7;;
4: len 4; hex 00f91feb; asc ;;
5: len 1; hex 80; asc ;;
6: len 11; hex 3230303273756966656e67; asc 2002suifeng;;
7: len 4; hex 003a4c70; asc :Lp;;
8: len 4; hex 00000000; asc ;;
9: len 1; hex 81; asc ;;
10: len 4; hex 54d5a7a3; asc T ;;
11: len 4; hex 00000000; asc ;;
12: len 6; hex e9a1b6e9a1b6; asc ;;          中文"顶顶" utf8编码  , 翻译网站 http://www.isthisthingon.org/unicode/
13: len 10; hex 312e31322e32382e3735; asc 1.12.28.75;;
14: len 1; hex 80; asc ;;
15: len 1; hex 80; asc ;;
16: len 4; hex 80000000; asc ;;
17: len 4; hex 00000012; asc ;;
18: len 1; hex 81; asc ;;

*** (2) TRANSACTION:
TRANSACTION 70672123, ACTIVE 98 sec updating or deleting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1184, 2 row lock(s), undo log entries 1
MySQL thread id 29, OS thread handle 0x7f7b1f9db700, query id 5291 IP地址 root updating
delete from post_76 where pid = 243222770
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 5495 page no 1437 n bits 120 index `PRIMARY` of table `db_name`.`post_76` trx id 70672123 lock_mode X locks rec but not gap
Record lock, heap no 41 PHYSICAL RECORD: n_fields 19; compact format; info bits 32
0: len 4; hex 0e7f48f2; asc H ;;            这个是第1个字段也是主键: 16进制转成10进制是 243222770
1: len 6; hex 000004365efb; asc 6^ ;;
2: len 7; hex 5200000f1b1055; asc R U;;
3: len 3; hex 000037; asc 7;;
4: len 4; hex 00f91feb; asc ;;
5: len 1; hex 80; asc ;;
6: len 11; hex 3230303273756966656e67; asc 2002suifeng;;
7: len 4; hex 003a4c70; asc :Lp;;
8: len 4; hex 00000000; asc ;;
9: len 1; hex 81; asc ;;
10: len 4; hex 54d5a7a3; asc T ;;
11: len 4; hex 00000000; asc ;;
12: len 6; hex e9a1b6e9a1b6; asc ;;              中文"顶顶" utf8编码 , 翻译网站 http://www.isthisthingon.org/unicode/
13: len 10; hex 312e31322e32382e3735; asc 1.12.28.75;;
14: len 1; hex 80; asc ;;
15: len 1; hex 80; asc ;;
16: len 4; hex 80000000; asc ;;
17: len 4; hex 00000012; asc ;;
18: len 1; hex 81; asc ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 5495 page no 2876 n bits 640 index `idx_tid_position` of table `db_name`.`post_76` trx id 70672123 lock_mode X locks rec but not gap waiting
Record lock, heap no 559 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
0: len 4; hex 00f91feb; asc ;;
1: len 4; hex 00000012; asc ;;
2: len 4; hex 0e7f48f2; asc H ;;