DB2锁问题分析与解释(3)
来源:未知 责任编辑:责任编辑 发表时间:2015-03-01 01:41 点击:次
结论:update操作需要表级的IX锁和行级的X锁。
$ db2 rollback
$ db2 +c "delete from student where age=6"
DB20000I The SQL command completed successfully.
$ db2pd -db qsmiao -locks
结论:update操作需要表级的IX锁和对应的行级的X锁(这里因为3条记录的age都为6,因此需要3个行级锁)。
现在的问题是:为什么insert和update,delete操作需要的锁一样(表级的IX锁,对应行级的X锁),但是表现的效果却不一样呢?
为了解决这个问题,看一下他们的执行计划吧:
$ db2expln -d qsmiao -g -statement "insert into student values(5, 'gao')" -terminal
$ db2expln -d qsmiao -g -statement "update student set name='qing' where age=4" -terminal
$ db2expln -d qsmiao -g -statement "delete from student where age=6" -terminal
从上面的执行计划中可以看到原因:insert操作不需要表扫描,而update和delete操作都需要全表扫描,而且会在扫描的时候试图对每一行加U锁。
导致锁超时的原因就是表扫描
例如session 1要更新表的某一行,会在该行加上X锁。之后, session 2试图更新该表的另一行,进行全表扫描时,就会试图对A占用的那一行加上U锁,但无能为力,最终导
致锁超时。
为了验证该说法,可以抓取锁等待的消息,session 1
---------
$ db2 +c "update student set name='hehe' where age = 4"
DB20000I The SQL command completed successfully.
session 2
---------
$ db2 +c "delete from student where age=6"
<-------这时会hang住,因为它在等session 1的锁
session 3
---------
$ db2pd -db qsmiao -wlocks <---在锁超时发生之前,抓取锁等待的消息
Locks being waited on :
AppHandl [nod-index] TranHdl Lockname Type Mode Conv Sts CoorEDU AppName AuthID AppID
15393 [000-15393] 2 00020004000000000000000952 Row ..X G 7818 db2bp E97Q6C *LOCAL.e97q6c.141016035113
15408 [000-15408] 16 00020004000000000000000952 Row ..U W 10153 db2bp E97Q6C *LOCAL.e97q6c.141016035219
可以看到,是因为U锁和X锁的不兼容导致锁等待,最后导致锁超时。
为了解决该锁等待问题,可以在查询谓词所涉及的列age上建立索引,避免全表扫描
试验4:通过建立索引,消除锁等待现象
session 1
---------
$ db2 rollback
$ db2 +c "lock table student in share mode"
$ db2 +c "create index stu_idx on student(age)"
$ db2 commit
相关新闻>>
最新推荐更多>>>
- 发表评论
-
- 最新评论 更多>>