DB2 锁问题分析与解释
DB2 锁问题分析与解释
DB2 应用中常常会遇到锁超时与死锁现象,那么这样的现象产生的原因是什么呢。本文以试验的形式模拟锁等待、锁超时、死锁现象。并给出这些现象的根本原因。
试验环境:
DB2 v9.7.0.6
AIX 6.1.0.0
採用默认的隔离级别CS
STUDENT表的DDL与初始内容
------------------------------------------------
-- DDL Statements for table "E97Q6C "."STUDENT"
------------------------------------------------
CREATE TABLE "E97Q6C "."STUDENT" (
"AGE" INTEGER ,
"NAME" CHAR(8) )
IN "USERSPACE1" ;
$ db2 "select * from student"
AGE NAME
----------- --------
3 xu
5 gao
2 liu
1 gu
试验1:验证insert操作与其它操作的锁等待问题
session 1中发出insert操作,在session 2中观察insert,update,delete操作是否会锁超时。
session 1
---------
$ db2 +c "insert into student values(4, 'miao')"
DB20000I The SQL command completed successfully.
session 2
---------
$ db2 "insert into student values(6, 'mu')"
DB20000I The SQL command completed successfully.
$ db2 "update student set name='gu' where age=1"
DB20000I The SQL command completed successfully.
$ db2 "delete from student where age=2"
DB20000I The SQL command completed successfully.
----------------------------------------------------------------------------
结论1:当session 1对表作insert操作时,session 2对该表的insert及其它行的update,delete操作都不会有问题
----------------------------------------------------------------------------
试验2:验证update操作与其它操作的锁等待问题
session 1中发出update操作,在session 2中观察insert,update,delete操作是否会锁超时。
--------------
session 1
---------
$ db2 commit
$ db2 "select * from student"
AGE NAME
----------- --------
3 xu
5 gao
6 mu
4 miao
1 gu
5 record(s) selected.
$ db2 +c "update student set name = 'qing' where age=4"
DB20000I The SQL command completed successfully.
session 2
---------
$ db2 "insert into student values(6, 'mu')"
DB20000I The SQL command completed successfully.
$ db2 "update student set name='gu' where age=1"
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0911N The current transaction has been rolled back because of a deadlock
or timeout. Reason code "68". SQLSTATE=40001
$ db2 "delete from student where age=2"
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0911N The current transaction has been rolled back because of a deadlock
or timeout. Reason code "68". SQLSTATE=40001
----------------------------------------------------------------------------
结论2:当session 1对表某一行做update操作时,session 2能够对该表作insert操作,但不同意对其它行的delete和update操作
----------------------------------------------------------------------------
试验3:验证delete操作与其它操作的锁等待问题
session 1中发出delete操作,在session 2中观察insert,update,delete操作是否会锁超时。
Session 1
---------
$ db2 commit
$ db2 +c "delete from student where age=4"
DB20000I The SQL command completed successfully.
session 2
---------
$ db2 "insert into student values(6, 'mu')"
DB20000I The SQL command completed successfully.
$ db2 "update student set name='gu' where age=1"
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0911N The current transaction has been rolled back because of a deadlock
or timeout. Reason code "68". SQLSTATE=40001
$ db2 "delete from student where age=2"
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0911N The current transaction has been rolled back because of a deadlock
or timeout. Reason code "68". SQLSTATE=40001
----------------------------------------------------------------------------
结论3:当应用1对表某一行做delete操作时,应用2能够对该表作insert操作。但不同意对其它行的delete和update操作
----------------------------------------------------------------------------
总的结论是:
应用对表作insert操作时。其它操作不受影响,也不受其它操作影响。
作update,delete操作时,其它的update和delete操作受影响。
为了解释以上现象的原因,我们首先看一下上面的操作须要什么样的锁。
session 1.
---------
$ db2 rollback
$ db2 +c "insert into student values(7,'han')"
DB20000I The SQL command completed successfully.
$ db2pd -db qsmiao -locks
结论:insert操作须要表级的IX锁和行级的X锁。
注:IX锁。该锁的拥有者在拥有对应行的X锁时能够更改该行的数据。
$ db2 rollback
$ db2 +c "update student set name='yan' where age=5"
DB20000I The SQL command completed successfully.
$ db2pd -db qsmiao -locks
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcWluZ3NvbmczMzMz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast">
结论: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
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcWluZ3NvbmczMzMz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast">
$ 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
$ 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" <--没有发生锁等待现象,直接成功
DB20000I The SQL command completed successfully.
能够看到,已经通过索引攻克了该锁超时问题。假设读者有兴趣的话,能够看下建立索引之后的訪问计划。
以下模拟一个死锁现象
试验5:模拟死锁,步骤例如以下
第一步:session 1 获得 锁 LOCK1
第二步:session 2 获得 锁 LOCK2
第三步:session 2 申请 锁 LOCK1
第四步:session 1 申请 锁 LOCK2
为了避免死锁之前产生锁超时,先将锁超时控制參数设为-1(表示永远等待)
update db cfg using locktimeout -1
之后重新启动数据库
session 1
---------
$ db2 +c "update student set name = 'an' where age = 1" <--获得锁LOCK1,成功
DB20000I The SQL command completed successfully.
session 2
---------
$ db2 +c "update student set name = 'two' where age = 4" <--获得锁LOCK2,成功
DB20000I The SQL command completed successfully.
$ db2 +c "update student set name = 'four' where age = 1" <--申请锁LOCK1,hang住。由于LOCK1被session 1持有
session 1
---------
$ db2 +c "update student set name = 'three' where age = 4" <--申请锁LOCK2,hang住,由于LOCK2被session 2持有
这时已经发生了死锁,10s之后,这两个session有一个会报出例如以下死锁(reason code 2)错误。还有一个session成功运行
SQL0911N The current transaction has been rolled back because of a deadlock
or timeout. Reason code "2". SQLSTATE=40001
參考资料:
标准表的锁定方式和存取方案,这里您能够看到具体的加锁方式
http://www-01.ibm.com/support/knowledgecenter/SSEPGG_9.7.0/com.ibm.db2.luw.admin.perf.doc/doc/r0005275.html?lang=zh
附。仅仅能在发生死锁或者锁等待的时候才干用db2pd查看锁的信息。以下附上怎样採用事件监控器监控死锁/锁超时。事件监控器能够抓取一段时间内的锁事件
db2 update db cfg for sample using MON_LOCKWAIT hist_and_values MON_DEADLOCK hist_and_values MON_LOCKTIMEOUT hist_and_values MON_LW_THRESH 10000
db2 "CREATE EVENT MONITOR LOCKEVMON FOR LOCKING WRITE TO UNFORMATTED EVENT TABLE (TABLE LOCKEVMON)"
db2 set event monitor LOCKEVMON state=1
重现问题
db2 flush event monitor LOCKEVMON
db2 set event monitor LOCKEVMON state=0
cp /home/db2users/e97q6c/sqllib/samples/java/jdbc/db2evmonfmt.java ./
cp /home/db2users/e97q6c/sqllib/samples/java/jdbc/DB2EvmonLocking.xsl ./
export PATH=/home/db2users/e97q6c/sqllib/java/jdk64/bin:$PATH
javac db2evmonfmt.java
java db2evmonfmt -d sample -ue LOCKEVMON -ftext -u e97q6c -p e97q6c > deadlock.txt
more deadlock.txt 能够看到有关的SQL语句。
请參考
http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-1004lockeventmonitor/
DB2 锁问题分析与解释的更多相关文章
- linux RCU锁机制分析
openVswitch(OVS)源代码之linux RCU锁机制分析 分类: linux内核 | 标签: 云计算,openVswitch,linux内核,RCU锁机制 | 作者: yuzhih ...
- DB2锁机制
相比较Oracle来说,DB2的锁机制麻烦了很多,而且这个麻烦带来的不是性能的上升而是下降,不过如果细致了解的话,只能感慨不愧是数据库理论诞生的公司,在实现数据库理论上比Oracle全面得多. ...
- SQL Server中CURD语句的锁流程分析
我只在数据库选项已开启“行版本控制的已提交读”(READ_COMMITTED_SNAPSHOT为ON)中进行了观察. 因此只适用于这种环境的数据库. 该类数据库支持四种不同事务隔离级别,下面分别观察数 ...
- MySQL锁等待分析【2】
MySQL锁等待分析[1]中对锁等待的分析是一步一步来的.虽然最后是分析出来了,可是用时是比较长的:理清各个表之间的关系后,得到如下SQL语句,方便以后使用 select block_trx.trx_ ...
- ElasticSearch评分分析 explian 解释和一些查询理解
ElasticSearch评分分析 explian 解释和一些查询理解 按照es-ik分析器安装了ik分词器.创建索引:PUT /index_ik_test.索引包含2个字段:content和nick ...
- DB2锁表或超时解决方案
DB2锁表或超时 一.场景 对数据表进行更新(查询没问题),错误提示如下: SQLCODE=-911, SQLSTATE=40001, DRIVER=3.63.75SQL0911N The curre ...
- Java多线程——线程八锁案例分析
Java多线程——线程八锁案例分析 摘要:本文主要学习了多线程并发中的一些案例. 部分内容来自以下博客: https://blog.csdn.net/dyt443733328/article/deta ...
- 图解Janusgraph系列-并发安全:锁机制(本地锁+分布式锁)分析
图解Janusgraph系列-并发安全:锁机制(本地锁+分布式锁)分析 大家好,我是洋仔,JanusGraph图解系列文章,实时更新~ 图数据库文章总目录: 整理所有图相关文章,请移步(超链):图数据 ...
- Redisson 实现分布式锁原理分析
Redisson 实现分布式锁原理分析 写在前面 在了解分布式锁具体实现方案之前,我们应该先思考一下使用分布式锁必须要考虑的一些问题. 互斥性:在任意时刻,只能有一个进程持有锁. 防死锁:即使有 ...
随机推荐
- YYH的苍天大竹(NOIP模拟赛Round 6)
题目描述 YYH擅长种竹子.今天他收获了一根竹子,准备将这根柱子卖给CHS.这个竹子有n-1个竹节.CHS要求一定要从竹节的地方砍,而且砍成若干段后每一段竹子中最长的一小段竹子和最短的一小段的长度差不 ...
- 牧场行走(LCA)
神奇传送门 好吧,这题很有意思.. 第一眼撇的时候还以为是(SPFA)呜.... 然后发现要Q次询问就想到了LCA 但是发现不是求LCA.. 于是想到了一个神奇的定律: 两点的LCA一定在u到v的最短 ...
- Linux内核中的中断栈与内核栈的补充说明【转】
转自:http://blog.chinaunix.net/uid-12461657-id-3487463.html 原文地址:Linux内核中的中断栈与内核栈的补充说明 作者:MagicBoy2010 ...
- Linux 设备驱动--- 阻塞型字符设备驱动 --- O_NONBLOCK --- 非阻塞标志【转】
转自:http://blog.csdn.net/yikai2009/article/details/8653697 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 阻塞 阻 ...
- Selenium2+python自动化11-定位一组元素find_elements【转载】
前言 前面的几篇都是讲如何定位一个元素,有时候一个页面上有多个对象需要操作,如果一个个去定位的话,比较繁琐,这时候就可以定位一组对象. webdriver 提供了定位一组元素的方法,跟前面八种定位方式 ...
- C#集合类:动态数组、队列、栈、哈希表、字典(转)
1.动态数组:ArrayList 主要方法:Add.AddRange.RemoveAt.Remove 2.队列:Queue 主要方法:Enqueue入队列.Dequeue出队列.Peek返回Queue ...
- 学习hibernate,这个系列很不错
从这里入,感谢作者啊. 看了很多资料,这个是最能让我入门的.感觉. http://blog.csdn.net/yerenyuan_pku/article/details/52745486
- 跨集群拷贝hdfs
拷贝 A集群的test目录到B集群的test目录 问题1: cause:java.io.IOException: Failed to run job : User root cannot submit ...
- #423 Div2 C
#423 Div2 C 题意 给出 n 个字符串以及他们在 S 串中出现的位置,求字典序最小的 S 串.保证给出的字符串不会冲突. 分析 模拟就好.用并查集思想优化,数组 nxt[i] 表示从 i 开 ...
- 洛谷——P1100 高低位交换
P1100 高低位交换 题目描述 给出一个小于2^32的正整数.这个数可以用一个32位的二进制数表示(不足32位用0补足).我们称这个二进制数的前16位为“高位”,后16位为“低位”.将它的高低位交换 ...