楼主: winterroot

问个innodb死锁问题

[复制链接]
论坛徽章:
52
2015年新春福章
日期:2015-03-06 11:57:312012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:25生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:32:552012新春纪念徽章
日期:2012-02-07 09:59:35
11#
发表于 2011-12-19 15:23 | 只看该作者
本帖最后由 jinguanding 于 2011-12-19 15:25 编辑
winterroot 发表于 2011-12-19 12:45
死锁产生的条件我当然知道,不知道你有没有看我的问题,我的问题其实就是第二个事务到底占用了哪个资源导 ...

意向锁是一种锁的等待状态,排优先级的,并不是真正获得了加锁的权利,只是加锁的优先权的大小而已...

MySQL数据库InnoDB存储引擎源码角度解读死锁检测  http://www.mysqlops.com/2011/12/05/innodb-dead-lock.html

使用道具 举报

回复
论坛徽章:
3
ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262012新春纪念徽章
日期:2012-01-04 11:53:29蜘蛛蛋
日期:2012-03-09 15:07:54
12#
发表于 2011-12-19 15:25 | 只看该作者
winterroot 发表于 2011-12-19 14:28
但是,第一个事务已经取得了S锁,而S锁和IX是不兼容的。这是怎么回事?是不是因为意向锁只是针对表锁的, ...

好吧,我承认我也晕了

1.在第二个事务delete语句执行后
------------
TRANSACTIONS
------------
Trx id counter 125D1C46
Purge done for trx's n < 125D1C44 undo n < 0
History list length 321
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 64, query id 610 localhost root
show engine innodb status
---TRANSACTION 125D1C45, ACTIVE 18 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s)
MySQL thread id 63, query id 606 localhost root updating
delete from t where i=1
------- TRX HAS BEEN WAITING 18 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1816 page no 3 n bits 72 index `GEN_CLUST_INDEX` of table `ywang`.`t` trx id 125D1C45 lock_mode X locks rec but not gap waiting
------------------
TABLE LOCK table `ywang`.`t` trx id 125D1C45 lock mode IX
RECORD LOCKS space id 1816 page no 3 n bits 72 index `GEN_CLUST_INDEX` of table `ywang`.`t` trx id 125D1C45 lock_mode X locks rec but not gap waiting
---TRANSACTION 125D1C44, ACTIVE 20 sec
2 lock struct(s), heap size 376, 1 row lock(s)
MySQL thread id 62, query id 605 localhost root
TABLE LOCK table `ywang`.`t` trx id 125D1C44 lock mode IS
RECORD LOCKS space id 1816 page no 3 n bits 72 index `GEN_CLUST_INDEX` of table `ywang`.`t` trx id 125D1C44 lock mode S locks rec but not gap
----------------------------
END OF INNODB MONITOR OUTPUT
============================

第二个事务的相关锁信息LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s)
是不是说明它在等2个锁,一个IS一个是S?

2.这个时候数据库里

mysql> select * from INNODB_LOCKS
    -> ;
+-------------------+-------------+-----------+-----------+-------------+-------------------+------------+-----------+----------+----------------+
| lock_id           | lock_trx_id | lock_mode | lock_type | lock_table  | lock_index        | lock_space | lock_page | lock_rec | lock_data      |
+-------------------+-------------+-----------+-----------+-------------+-------------------+------------+-----------+----------+----------------+
| 125D1C60:1816:3:2 | 125D1C60    | X         | RECORD    | `ywang`.`t` | `GEN_CLUST_INDEX` |       1816 |         3 |        2 | 0x00000038EF01 |
| 125D1C5F:1816:3:2 | 125D1C5F    | S         | RECORD    | `ywang`.`t` | `GEN_CLUST_INDEX` |       1816 |         3 |        2 | 0x00000038EF01 |
+-------------------+-------------+-----------+-----------+-------------+-------------------+------------+-----------+----------+----------------+
2 rows in set (0.04 sec)

mysql> select * from INNODB_LOCK_WAITS;
+-------------------+-------------------+-----------------+-------------------+
| requesting_trx_id | requested_lock_id | blocking_trx_id | blocking_lock_id  |
+-------------------+-------------------+-----------------+-------------------+
| 125D1C60          | 125D1C60:1816:3:2 | 125D1C5F        | 125D1C5F:1816:3:2 |
+-------------------+-------------------+-----------------+-------------------+
1 row in set (0.00 sec)


啊啊啊,抓狂了,晚上回去看看书

使用道具 举报

回复
论坛徽章:
3
ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262012新春纪念徽章
日期:2012-01-04 11:53:29蜘蛛蛋
日期:2012-03-09 15:07:54
13#
发表于 2011-12-19 15:26 | 只看该作者
winterroot 发表于 2011-12-19 14:28
但是,第一个事务已经取得了S锁,而S锁和IX是不兼容的。这是怎么回事?是不是因为意向锁只是针对表锁的, ...

好吧,我承认我也晕了

1.在第二个事务delete语句执行后
------------
TRANSACTIONS
------------
Trx id counter 125D1C46
Purge done for trx's n < 125D1C44 undo n < 0
History list length 321
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 64, query id 610 localhost root
show engine innodb status
---TRANSACTION 125D1C45, ACTIVE 18 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s)
MySQL thread id 63, query id 606 localhost root updating
delete from t where i=1
------- TRX HAS BEEN WAITING 18 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1816 page no 3 n bits 72 index `GEN_CLUST_INDEX` of table `ywang`.`t` trx id 125D1C45 lock_mode X locks rec but not gap waiting
------------------
TABLE LOCK table `ywang`.`t` trx id 125D1C45 lock mode IX
RECORD LOCKS space id 1816 page no 3 n bits 72 index `GEN_CLUST_INDEX` of table `ywang`.`t` trx id 125D1C45 lock_mode X locks rec but not gap waiting
---TRANSACTION 125D1C44, ACTIVE 20 sec
2 lock struct(s), heap size 376, 1 row lock(s)
MySQL thread id 62, query id 605 localhost root
TABLE LOCK table `ywang`.`t` trx id 125D1C44 lock mode IS
RECORD LOCKS space id 1816 page no 3 n bits 72 index `GEN_CLUST_INDEX` of table `ywang`.`t` trx id 125D1C44 lock mode S locks rec but not gap
----------------------------
END OF INNODB MONITOR OUTPUT
============================

第二个事务的相关锁信息LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s)
是不是说明它在等2个锁,一个IS一个是S?

2.这个时候数据库里

mysql> select * from INNODB_LOCKS
    -> ;
+-------------------+-------------+-----------+-----------+-------------+-------------------+------------+-----------+----------+----------------+
| lock_id           | lock_trx_id | lock_mode | lock_type | lock_table  | lock_index        | lock_space | lock_page | lock_rec | lock_data      |
+-------------------+-------------+-----------+-----------+-------------+-------------------+------------+-----------+----------+----------------+
| 125D1C60:1816:3:2 | 125D1C60    | X         | RECORD    | `ywang`.`t` | `GEN_CLUST_INDEX` |       1816 |         3 |        2 | 0x00000038EF01 |
| 125D1C5F:1816:3:2 | 125D1C5F    | S         | RECORD    | `ywang`.`t` | `GEN_CLUST_INDEX` |       1816 |         3 |        2 | 0x00000038EF01 |
+-------------------+-------------+-----------+-----------+-------------+-------------------+------------+-----------+----------+----------------+
2 rows in set (0.04 sec)

mysql> select * from INNODB_LOCK_WAITS;
+-------------------+-------------------+-----------------+-------------------+
| requesting_trx_id | requested_lock_id | blocking_trx_id | blocking_lock_id  |
+-------------------+-------------------+-----------------+-------------------+
| 125D1C60          | 125D1C60:1816:3:2 | 125D1C5F        | 125D1C5F:1816:3:2 |
+-------------------+-------------------+-----------------+-------------------+
1 row in set (0.00 sec)


啊啊啊,抓狂了,晚上回去看看书

使用道具 举报

回复
论坛徽章:
1
ITPUB十周年纪念徽章
日期:2011-11-01 16:20:28
14#
 楼主| 发表于 2011-12-19 15:41 | 只看该作者
jinguanding 发表于 2011-12-19 15:22
客户端A:
START TRANSACTION;
SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE; ----①

那如果我把例子中的delete语句改成select * from t where i=1 for update, 这样也会产生死锁,这时第二个事务为什么不等待第一个事务commit或者rollback,然后再获得X锁呢?

使用道具 举报

回复
论坛徽章:
52
2015年新春福章
日期:2015-03-06 11:57:312012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:25生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:32:552012新春纪念徽章
日期:2012-02-07 09:59:35
15#
发表于 2011-12-19 16:35 | 只看该作者
winterroot 发表于 2011-12-19 15:41
那如果我把例子中的delete语句改成select * from t where i=1 for update, 这样也会产生死锁,这时第二个 ...

FOR UPDATE 也是属于独占锁,与DELETE ...操作是类似的...

使用道具 举报

回复
论坛徽章:
1
ITPUB十周年纪念徽章
日期:2011-11-01 16:20:28
16#
 楼主| 发表于 2011-12-19 17:27 | 只看该作者
jinguanding 发表于 2011-12-19 16:35
FOR UPDATE 也是属于独占锁,与DELETE ...操作是类似的...

第一个事务能顺利执行下去,为什么会死锁呢?
为什么不是这样呢:第一个事务取得X锁,第二个事务继续等待,第二个事务提交,第一个事务取得X锁。

使用道具 举报

回复
论坛徽章:
52
2015年新春福章
日期:2015-03-06 11:57:312012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:25生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:33:22生肖徽章2007版:龙
日期:2012-02-07 10:32:552012新春纪念徽章
日期:2012-02-07 09:59:35
17#
发表于 2011-12-19 17:31 | 只看该作者
winterroot 发表于 2011-12-19 17:27
第一个事务能顺利执行下去,为什么会死锁呢?
为什么不是这样呢:第一个事务取得X锁,第二个事务继续等待 ...

关键是其内部可能认为 无法再获得此锁 你测试过程不要乱了,先准备好,推荐文章:
MySQL InnoDB之事务与锁详解  http://www.mysqlops.com/2011/02/16/mysql-innodb-lock.html

使用道具 举报

回复
论坛徽章:
28
2010数据库技术大会纪念徽章
日期:2010-05-13 09:34:232012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:25版主2段
日期:2012-07-05 02:21:032013年新春福章
日期:2013-02-25 14:51:24ITPUB社区12周年站庆徽章
日期:2013-08-12 09:34:36马上有车
日期:2014-02-19 11:55:14
18#
发表于 2011-12-20 13:07 | 只看该作者
意向锁只是针对表锁

使用道具 举报

回复
论坛徽章:
3
ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262012新春纪念徽章
日期:2012-01-04 11:53:29蜘蛛蛋
日期:2012-03-09 15:07:54
19#
发表于 2011-12-20 16:51 | 只看该作者
winterroot 发表于 2011-12-19 14:28
但是,第一个事务已经取得了S锁,而S锁和IX是不兼容的。这是怎么回事?是不是因为意向锁只是针对表锁的, ...

我觉得你指的事行锁而 IS IX 是否与S以及X锁兼容,(S,X)指的是表锁
BTW,你的表如果没有索引,innodb会使用表锁

使用道具 举报

回复
论坛徽章:
1
ITPUB十周年纪念徽章
日期:2011-11-01 16:20:28
20#
 楼主| 发表于 2011-12-20 18:28 | 只看该作者
jiwang1980 发表于 2011-12-20 16:51
我觉得你指的事行锁而 IS IX 是否与S以及X锁兼容,(S,X)指的是表锁
BTW,你的表如果没有索引,innodb ...

没有索引不会使用表锁。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表