db2pd命令捕获死锁信息
- 格式:docx
- 大小:29.15 KB
- 文档页数:8
db2解决死锁的方法DB2是一种常见的关系型数据库管理系统,它被广泛应用于企业级应用程序中。
然而,随着应用程序的复杂性增加和并发访问的增加,死锁问题也变得越来越常见。
在本文中,我们将探讨一些使用DB2解决死锁问题的方法。
1. 死锁的定义和原因死锁是指两个或多个事务彼此等待对方持有的资源,从而导致所有事务无法继续执行的状态。
死锁通常发生在并发访问数据库时,其中一个事务正在使用某个资源,而另一个事务需要访问相同的资源。
死锁的发生原因可以归结为四个条件:互斥(资源只能被一个事务使用)、持有并等待(一个事务持有资源并等待另一个事务的资源)、不可剥夺(资源不能被其他事务抢占)、循环等待(多个事务形成循环等待资源)。
2. 使用锁机制避免死锁在DB2中,可以使用锁机制来避免死锁的发生。
锁是一种机制,用于协调并发事务对共享资源的访问。
DB2提供了两种类型的锁:共享锁和排他锁。
共享锁允许多个事务同时读取资源,但不允许写入资源;排他锁只允许一个事务同时读取或写入资源。
为了避免死锁,可以采取以下策略:- 在事务开始时,尽量将锁的范围缩小到最小,只锁定必要的资源。
- 在事务执行期间,尽量减少锁的持有时间,执行完操作后尽快释放锁。
- 避免循环等待,即事务在请求资源时按照统一的顺序进行,避免形成死锁的循环等待。
3. 设置适当的隔离级别DB2提供了多种隔离级别,用于控制事务之间的相互影响。
不同的隔离级别对并发访问的控制程度不同。
在选择隔离级别时,需要权衡事务的一致性和性能。
在避免死锁的角度考虑,可以选择较低的隔离级别,如读取已提交(Read Committed)。
较低的隔离级别可以减少锁的竞争,从而降低死锁的风险。
但同时,较低的隔离级别也可能导致数据不一致的问题,需要根据具体业务需求进行权衡。
4. 监控和诊断死锁DB2提供了一些工具和功能,用于监控和诊断死锁问题。
可以通过以下方式来实现:- 使用DB2的系统监控工具,如db2pd命令和db2top工具,可以实时查看数据库的锁和死锁情况。
作业:1.使用命令监控锁的情况,使用类型2.练习在CLP命令中使用不同的隔离级别3.使用快照监控数据库的使用情况4.使用表函数监控SQL语句的使用情况1.使用命令监控锁的情况,使用类型[myinst@ye ~]$ db2 activate database mydb3SQL1493N The application is already connected to an active database.#查看锁表--看应用在等什么[myinst@ye ~]$ db2pd -db mydb3 -locks showlock waitDatabase Member 0 -- Database MYDB3 -- Active -- Up 0 days 01:50:51 -- Date 2015-08-18-15.48.27.193864Locks:Address TranHdl Lockname Type Mode Sts Owner Dur HoldCount Att ReleaseFlg rrIID TableNm SchemaNm[myinst@ye ~]$ db2 get db cfg |grep DLCHKTIME#是DB2检查死锁的间隔时间,该值为10000msInterval for checking deadlock (ms) (DLCHKTIME) = 10000[myinst@ye ~]$ db2 get db cfg |grep LOCKTIMEOUT#锁等待最长时间,单位是秒Lock timeout (sec) (LOCKTIMEOUT) = -1Lock timeout events (MON_LOCKTIMEOUT) = NONE#查看当前的隔离级别[myinst@ye ~]$ db2 "SELECT CURRENT ISOLATION FROM SYSIBM.SYSDUMMY1"#查看锁表--用快照[myinst@ye ~]$ db2 "GET SNAPSHOT FOR LOCKS ON mydb3"Database Lock SnapshotDatabase name = MYDB3Database path = /www/db2/db2test/myinst/NODE0000/SQL00001/MEMBER0000/Input database alias = MYDB3Locks held = 0Applications currently connected = 1Agents currently waiting on locks = 0Snapshot timestamp = 08/18/2015 15:53:47.009051Application handle = 13Application ID = *LOCAL.DB2.150818055741Sequence number = 00001Application name = db2fw0CONNECT Authorization ID = MYINSTApplication status = Connect CompletedStatus change time = Not CollectedApplication code page = 1386Locks held = 0Total wait time (ms) = 0Application handle = 12Application ID = *LOCAL.DB2.150818055740Sequence number = 00001Application name = db2lusedCONNECT Authorization ID = MYINSTApplication status = Connect CompletedStatus change time = Not CollectedApplication code page = 1208Locks held = 0Total wait time (ms) = 0Application handle = 11Application ID = *LOCAL.DB2.150818055739Sequence number = 00001Application name = db2wlmdCONNECT Authorization ID = MYINSTApplication status = Connect CompletedStatus change time = Not CollectedApplication code page = 1208Locks held = 0Total wait time (ms) = 0Application handle = 10Application ID = *LOCAL.DB2.150818055738 Sequence number = 00001Application name = db2taskdCONNECT Authorization ID = MYINSTApplication status = Connect CompletedStatus change time = Not Collected Application code page = 1208Locks held = 0Total wait time (ms) = 02.练习在CLP命令中使用不同的隔离级别DB2隔离级别分为如下四种:a、可重复读(Repeatable Read,RR)b、读稳定性(Read Stability,RS)c、游标稳定性(Cursor Stability,CS)d、未提交读(Uncommitted Read,UR)DB2默认的隔离级别为:游标稳定性(CS)[myinst@ye ~]$ db2 list command optionsCommand Line Processor Option SettingsBackend process wait time (seconds) (DB2BQTIME) = 1No. of retries to connect to backend (DB2BQTRY) = 60 Request queue wait time (seconds) (DB2RQTIME) = 5Input queue wait time (seconds) (DB2IQTIME) = 5 Command options (DB2OPTIONS) =Option Description Current Setting ------ ---------------------------------------- ----------------a Display SQLCA OFF-b Auto-Bind ON-c Auto-Commit ON-d Retrieve and display XML declarations OFF-e Display SQLCODE/SQLSTATE OFF-f Read from input file OFF-i Display XML data with indentation OFF-j Return code for system calls OFF-l Log commands in history file OFF-m Display the number of rows affected OFF-n Remove new line character OFF-o Display output ON-p Display interactive input prompt ON-q Preserve whitespaces & linefeeds OFF-r Save output to report file OFF-s Stop execution on command error OFF-t Set statement termination character OFF-v Echo current command OFF-w Display FETCH/SELECT warning messages ON-x Suppress printing of column headings OFF-z Save all output to output file OFF[myinst@ye ~]$ db2 "update command options using c off"DB20000I The UPDATE COMMAND OPTIONS command completed successfully.[myinst@ye ~]$ db2 +c(c) Copyright IBM Corporation 1993,2007Command Line Processor for DB2 Client 10.5.5You can issue database manager commands and SQL statements from the command prompt. For example:db2 => connect to sampledb2 => bind sample.bnddb2 => select * from emp for update with rrID CNAME----------- --------------------1 a1 record(s) selected.db2 => select * from emp for update with csID CNAME----------- --------------------1 a1 record(s) selected.db2 => select * from emp for update with urID CNAME----------- --------------------1 a1 record(s) selected.db2 => select * from emp for update with rsID CNAME----------- --------------------1 a1 record(s) selected.[myinst@ye ~]$ db2 "create table lck(pid int, uid int, id int, name varchar(10))"; DB20000I The SQL command completed successfully.[myinst@ye ~]$ db2 "alter table lck alter column pid set not null";DB20000I The SQL command completed successfully.[myinst@ye ~]$ db2 "reorg table lck";DB20000I The REORG command completed successfully.db2 => create unique index uniqindx on lck(uid)DB20000I The SQL command completed successfully.db2 => create index normalindx on lck(id)DB20000I The SQL command completed successfully.db2 => insert into lck values(1,1,1,'test1')DB20000I The SQL command completed successfully.db2 => insert into lck values(2,2,2,'test2')DB20000I The SQL command completed successfully.db2 => insert into lck values(3,3,3,'test3')DB20000I The SQL command completed successfully.db2 => insert into lck values(4,4,3,'test3')DB20000I The SQL command completed successfully.db2 => insert into lck values(5,5,5,'test5')DB20000I The SQL command completed successfully.db2 => runstats on table lck and detailed indexes all shrlevel change DB20000I The RUNSTATS command completed successfully.[myinst@ye ~]$ db2 +cdb2 => select * from lck where pid=1 for update with rrPID UID ID NAME----------- ----------- ----------- ----------1 1 1 test11 record(s) selected.db2 => select * from lck where name='test2' for update with rrPID UID ID NAME----------- ----------- ----------- ----------2 2 2 test21 record(s) selected.db2 => select * from lck where name='test2' for update with rsPID UID ID NAME----------- ----------- ----------- ----------2 2 2 test21 record(s) selected.db2 => select * from lck where id=3 for update with rrPID UID ID NAME----------- ----------- ----------- ----------3 3 3 test34 4 3 test32 record(s) selected.db2 => select * from lck where id=3 for update with rsPID UID ID NAME----------- ----------- ----------- ----------3 3 3 test34 4 3 test3 2 record(s) selected.session2:[myinst@ye ~]$ db2 -t出现了表锁#可以查看表锁情况3.使用快照监控数据库的使用情况[myinst@ye ~]$ db2 get monitor switchesMonitor Recording SwitchesSwitch list for member 0Buffer Pool Activity Information (BUFFERPOOL) = OFFLock Information (LOCK) = OFFSorting Information (SORT) = OFFSQL Statement Information (STATEMENT) = OFFTable Activity Information (TABLE) = OFFTake Timestamp Information (TIMESTAMP) = ON 08/18/2015 13:54:41.614454 Unit of Work Information (UOW) = OFF[myinst@ye ~]$ db2 update monitor switches using lock on statement onDB20000I The UPDATE MONITOR SWITCHES command completed successfully. [myinst@ye ~]$ db2 get monitor switchesMonitor Recording SwitchesSwitch list for member 0Buffer Pool Activity Information (BUFFERPOOL) = OFFLock Information (LOCK) = ON 08/18/2015 13:59:57.793842 Sorting Information (SORT) = OFFSQL Statement Information (STATEMENT) = ON 08/18/2015 13:59:57.793842 Table Activity Information (TABLE) = OFFTake Timestamp Information (TIMESTAMP) = ON 08/18/2015 13:54:41.614454 Unit of Work Information (UOW) = OFF#查看快照信息--查看数据库管理器级别快照信息[myinst@ye ~]$ db2 get snapshot for dbmDatabase Manager SnapshotNode type = Enterprise Server Edition with local and remote clientsInstance name = myinstNumber of members in DB2 instance = 1Database manager status = ActiveProduct name = DB2 v10.5.0.5Service level = s141128 (IP23633)Private Sort heap allocated = 0Private Sort heap high water mark = 0Post threshold sorts = Not CollectedPiped sorts requested = 0Piped sorts accepted = 0Start Database Manager timestamp = 08/18/2015 13:54:41.614454Last reset timestamp =Snapshot timestamp = 08/18/2015 14:19:34.072548Remote connections to db manager = 7Remote connections executing in db manager = 0Local connections = 1Local connections executing in db manager = 0Active local databases = 1High water mark for agents registered = 12Agents registered = 12Idle agents = 0Committed private Memory (Bytes) = 24051712Switch list for member 0Buffer Pool Activity Information (BUFFERPOOL) = OFFLock Information (LOCK) = ON 08/18/2015 13:57:37.650306 Sorting Information (SORT) = OFFSQL Statement Information (STATEMENT) = ON 08/18/2015 13:59:57.860423 Table Activity Information (TABLE) = OFFTake Timestamp Information (TIMESTAMP) = ON 08/18/2015 13:54:41.614454Unit of Work Information (UOW) = OFFAgents assigned from pool = 23Agents created from empty pool = 15Agents stolen from another application = 0High water mark for coordinating agents = 12Hash joins after heap threshold exceeded = 0OLAP functions after heap threshold exceeded = 0[myinst@ye ~]$ db2 get snapshot for database on mydb3Database SnapshotDatabase name = MYDB3Database path = /www/db2/db2test/myinst/NODE0000/SQL00001/MEMBER0000/Input database alias = MYDB3Database status = ActiveCatalog database partition number = 0Catalog network node name = Operating system running at database server= LINUXAMD64Location of the database = LocalFirst database connect timestamp = 08/18/2015 13:57:36.024785Last reset timestamp =Last backup timestamp = 08/11/2015 14:21:39.000000Snapshot timestamp = 08/18/2015 14:22:19.669943Number of automatic storage paths = 1Automatic storage path = /www/db2/db2testNode number = 0State = In UseHigh water mark for connections = 9Application connects = 23Secondary connects total = 8Applications connected currently = 1Appls. executing in db manager currently = 0Agents associated with applications = 8Maximum agents associated with applications= 9Maximum coordinating agents = 9Number of Threshold Violations = 0Locks held currently = 0Lock waits = 0Time database waited on locks (ms) = 0Lock list memory in use (Bytes) = 38400Deadlocks detected = 0Lock escalations = 0Exclusive lock escalations = 0Agents currently waiting on locks = 0Lock Timeouts = 0Number of indoubt transactions = 0#查看应用级别快照信息#db2 get snapshot for application agentid appl-handler#注:appl-handler可以从list applicaitions的输出中得到[myinst@ye ~]$ db2 "get snapshot for application agentid 8"Application SnapshotApplication handle = 8Application status = UOW WaitingStatus change time = Not CollectedApplication code page = 1208Application country/region code = 1DUOW correlation token = *LOCAL.myinst.150818055736 Application name = db2bpApplication ID = *LOCAL.myinst.150818055736 Sequence number = 00003TP Monitor client user ID =TP Monitor client workstation name =TP Monitor client application name =TP Monitor client accounting string =Connection request start timestamp = 08/18/2015 13:57:36.024785 Connect request completion timestamp = 08/18/2015 13:57:37.664637 Application idle time = 6 minutes 39 seconds CONNECT Authorization ID = MYINSTClient login ID = myinstConfiguration NNAME of client = Client database manager product ID = SQL10055Process ID of client application = 2658Platform of client application = LINUXAMD64Communication protocol of client = Local ClientInbound communication address = *LOCAL.myinstDatabase name = MYDB3Database path = /www/db2/db2test/myinst/NODE0000/SQL00001/MEMBER0000/Client database alias = MYDB3Input database alias =Last reset timestamp =Snapshot timestamp = 08/18/2015 14:48:27.627417 Authorization level granted =User authority:DBADM authoritySECADM authorityDATAACCESS authorityACCESSCTRL authorityGroup authority:SYSADM authorityCREATETAB authorityBINDADD authorityCONNECT authorityIMPLICIT_SCHEMA authorityCoordinator member number = 0Current member number = 0Coordinator agent process or thread ID = 21Current Workload ID = 1Agents stolen = 0Agents waiting on locks = 0Maximum associated agents = 1Priority at which application agents work = 0Priority type = DynamicLock timeout (seconds) = -1Locks held by application = 0Lock waits since connect = 0Time application waited on locks (ms) = 0Deadlocks detected = 0Lock escalations = 0Exclusive lock escalations = 0Number of Lock Timeouts since connected = 0Total time UOW waited on locks (ms) = Not CollectedTotal sorts = 0Total sort time (ms) = Not CollectedTotal sort overflows = 0#查看表级别快照信息#db2 get snapshot for tables on dbname#注:需要把tables快照开关设为ON才会有作用[myinst@ye ~]$ db2 "get snapshot for tables on mydb3"Table SnapshotFirst database connect timestamp = 08/18/2015 13:57:36.024785Last reset timestamp =Snapshot timestamp = 08/18/2015 14:46:14.123659Database name = MYDB3Database path = /www/db2/db2test/myinst/NODE0000/SQL00001/MEMBER0000/Input database alias = MYDB3Number of accessed tables = 6Table ListTable Schema = SYSIBMTable Name = SYSTABLESTable Type = CatalogData Object Pages = 8Index Object Pages = 20LOB Object pages = 120Rows Read = Not CollectedRows Written = 40Overflows = 0Page Reorgs = 0Table Schema = SYSIBMTable Name = SYSINDEXESTable Type = CatalogData Object Pages = 5Index Object Pages = 10LOB Object pages = 1Rows Read = Not CollectedRows Written = 42Overflows = 0Page Reorgs = 0Table Schema = SYSTOOLSTable Name = HMON_ATM_INFOTable Type = UserData Object Pages = 2Index Object Pages = 4Rows Read = Not CollectedRows Written = 0Overflows = 1Page Reorgs = 0Table Schema = SYSIBMTable Name = SYSDATAPARTITIONSTable Type = CatalogData Object Pages = 1Index Object Pages = 14Rows Read = Not CollectedRows Written = 1Overflows = 0Page Reorgs = 0Table Schema = SYSIBMTable Name = SYSPLANTable Type = CatalogData Object Pages = 6Index Object Pages = 10LOB Object pages = 56Rows Read = Not CollectedRows Written = 4Overflows = 0Page Reorgs = 0Table Schema = SYSIBMTable Name = SYSCOLDISTTable Type = CatalogData Object Pages = 123Index Object Pages = 84Rows Read = Not CollectedRows Written = 120Overflows = 0Page Reorgs = 0#查看锁快照信息#db2 get snapshot for locks on dbname 这条命令很有用,可以查看具体有哪些锁。
本文通过一个实例讲解了在DB2版本9以后,如何使用db2pd命令捕获死锁信息死锁经常会存在于我们的应用系统中,如何捕获死锁信息并解决死锁问题,是一个比较复杂的问题。
DB2提供了死锁事件监控器来获取死锁信息,可以非常方便地获取死锁信息。
从DB2版本8.2.2开始,DB2也可以使用db2pd命令和db2cos脚本来获取死锁信息,提供了一种新的途径来获取死锁信息。
从DB2版本9开始,我们可以使用db2pd -catch 命令来捕获错误信息,然后调用一个sqllib/db2cos 的脚本收集出错时的现场信息。
该命令的使用语法如下:Usage:-catch clear | status | <errorCode> [<action>] [count=<count>]Sets catchFlag to catch error or warning.Error Codes:<sqlCode>[,<reasonCode>] / sqlcode=<sqlCode>[,<reasonCode>]ZRC (hex or integer)ECF (hex or integer)"deadlock" or "locktimeout"Actions:[db2cos] (default) Run sqllib/db2cos callout script[lockname=<lockname>] Lockname for catching specific lock(lockname=000200030000001F0000000052)[locktype=<locktype>] Locktype for catching specific lock(locktype=R or locktype=52)下面我们通过一个实例来讲解如何使用db2pd -catch命令获取死锁信息。
db2pd对锁的监控(30分钟)目的:掌握db2pd对于锁信息监控的使用技巧1.打开3个db2cmd窗口,并分别连接到sample数据库2.在第一个窗口中输入3.在第二个窗口中输入此时,这条命令会等待。
下面我们用db2pd来分析这种等待的情况。
4.在第三个窗口中输入db2pd -db sample -locks wait showlocksdb2pd报告了有两个交易(TranHdl: Transaction Handler)产生了锁等待,其中一个交易(TranHdl=6)的锁状态(Mode)为G,表示该锁已被授予(Granted),另外一个交易(TranHdl=2)的锁为等待(W, Waiting)。
5.为了查出在那张表上产生了锁等待,我们在第三个窗口中输入db2 "SELECT TABSCHEMA, TABNAME FROM SYSCAT.TABLES WHERE TBSPACEID = 2 AND TABLEID = 6"由此,我们查出在EMPLOYEE这张表上产生了锁等待。
由此,我们完成了从事务到应用的对应,我们发现事务2,6分别属于应用30, 34,而且这两个应用都处于Write的状态。
因此,我们确定是写操作产生了锁等待。
7.我们需要近一步查出产生锁等待的应用程序的程序名,我们在第三个窗口中输入db2pd -agents由此,我们也找出了是哪两个客户端进程(Process ID)产生了锁等待。
8.能否近一步看出是什么样的SQL语句产生了锁?首先通过以下语句获得应用程序的更多信息,其中L-Anch ID表示上次执行的SQL,C-Anch ID表示当前执行的SQL:db2pd -db sample -applications9.得到上述信息后,我们再通过下述语句,就可以找出产生锁等待的SQL语句了db2pd -db sample -dynamic结果如下图所示:。
1.打开 db2pd – Monitor and Troubleshoot DB Command,如图 3 所示。
图 3. DB2 Information Center 中关于 db2pd 工具的信息调用 db2pd 工具有两种方式。
可以用交互模式调用 db2pd 工具,或者直接在操作系统命令提示符下运行。
要是用交互模式执行该工具,可以在操作系统命令提示符下输入 db2pd –interactive 或者直接输入 db2pd,这样将看到 db2pd 命令提示符db2pd>,可以输入命令选项。
使用–help 选项可以获得帮助信息。
退出 db2pd 命令提示符只需要输入 quit 或者 q。
图 4 中的例子说明了如何使用交互模式显示当前的代理。
图 4. 用交互模式调用 db2pd在操作系统命令提示符下调用该工具可以输入带有命令选项的 db2pd 命令。
下面的例子(图 5)使用 -agents 选项显示了所有的活动代理。
图 5. 在操作系统命令提示符下调用 db2pd此外,还可以通过将选项保存在文件中或者在 DB2PDOPT 环境变量中设置选项来控制该命令。
下面的例子(图 6)说明可以将 -agents 选项保存在一个(在该例中)名叫file.out的文件中,然后使用 db2pd –command file.out 执行选项。
图 6. 将 db2pd 选项保存在文件中如果要使用 DB2PDOPT 环境变量,可以将 DB2PDOPT 设成需要的选项然后像下面这样调用 db2pd:图 7. 在 DB2PDOPT 环境变量中设置 db2pd 选项更好的是,可以指定–repeat 参数重复该命令。
比方说,下面的命令每 2 秒钟显示一次 DB2 内存信息,共 5 次:db2pd –mempools –repeat 2 5此外,通过 file= 参数还可以将特定 db2pd 命令选项的结果保存到文件中。
file 和 repeat 参数可以结合使用:回页首监控的例子下面这些例子说明了如何用 db2pd 工具监控您的数据库环境。
使用 db2pd 进行监视和故障诊断因为 db2pd 工具可从 DB2® 内存集合迅速返回即时信息,所以该工具可用于故障诊断。
该工具不需要获得任何锁存器或使用任何引擎资源就可以收集信息。
因此,在 db2pd 收集信息时,有可能(并且预计)会检索到正在更改的信息;这样,数据可能不是十分准确。
如果遇到正在更改的内存指针,可使用信号处理程序来防止 db2pd 异常终止。
这可能会导致输出中出现诸如以下的消息:“正在更改的数据结构已强制终止命令”。
虽然如此,该工具对于故障诊断却非常有用。
在不锁存的情况下收集信息有两个好处:检索速度更快并且不会争用引擎资源。
如果要在出现特定 SQLCODE、ZRC 代码或 ECF 代码时捕获关于数据库管理系统的信息,那么可以使用 db2pdcfg -catch 命令完成此操作。
捕获到错误时,将启动 db2cos(调出脚本)。
db2cos 文件可以自动改变,以便运行解决问题所需的任何 db2pd 命令、操作系统命令或任何其他命令。
在 UNIX® 和Linux™ 上,模板文件 db2cos 位于 sqllib/bin 中。
在 Windows® 操作系统上,db2cos 位于 $DB2PATH in 目录中。
以下是使用 db2pd 快速故障诊断的一组示例。
场景 1:诊断锁定等待使用 db2pd -db <database name> -locks -transactions -applications -dynamic 命令来获取下列结果:锁定:Address TranHdl Lockname Type Mode Sts Owner Dur HldCnt Att ReleaseFlg0x07800000202E5238 3 00020002000000040000000052 Row ..X G 3 1 0 0x00000x400000000x07800000202E4668 2 00020002000000040000000052 Row ..X W* 2 1 0 0x00000x40000000对于使用 -db 数据库名称选项指定的数据库,开头的结果会显示该数据库的锁定。
DB2 V9.7 锁事件监控简介在大型 DB2 环境中,存在多个应用程序相互竞争数据资源的情况,为保证数据完整性,DB2 采用了锁机制来保护用户的修改不丢失。
随着应用程序数量的增多、复杂性的提高,诊断和排除应用程序锁定争用情况的工作可能相当复杂而且耗费DBA 很多时间。
在 V9.7 中,DB2 新增了锁定事件监视器和其他工具通过收集锁定数据来帮助 DBA 简化锁引起应用程序性能问题。
在 V9 以前版本中,如果希望诊断锁问题,我们可以采用表函数SNAP_GET_LOCKWAIT 查看当前锁等待情况,或者使用 GET SNAPSHOT FOR LOCKS 命令获取相关信息。
在 V9.1 版本中,DB2 增加了管理视图 SYSIBMADM.SNAPLOCKWAIT 用于返回锁等待信息。
无论是表函数 SNAP_GET_LOCKWAIT 或者管理视图 SYSIBMADM. SNAPLOCKWAIT,我们必须在锁定发生的瞬间执行查询才能获得当前的锁定信息。
而应用程序的锁发生具有随机性,对于已经超时回滚或者死锁回滚的应用,则上面的方法不能看到锁定模式、锁定对象等信息,也看不到哪些应用程序因为执行哪些 SQL 语句引起锁问题。
DB2V9.7 提供了锁定事件监视器用于在发生锁定事件时自动捕获关于事件的描述性信息。
锁定事件监视器捕获的信息可以标识引起的锁定争用所涉及的关键应用程序,同时还可以捕获这些应用程序因为执行何种 SQL 语句而引起锁。
与 DB2 以前版本中的死锁事件监视器不同,锁定事件监视器同时捕获关于锁定请求者(接收到死锁或锁定超时错误或者等待锁定时的耗用时间超出指定时间长度的应用程序)和当前锁定所有者的信息。
DB2V9.7 提供的锁定事件监视器可以捕获其锁定数据的活动的类型包括:∙SQL 语句,例如:DML 、DDL 、CALL∙LOAD 命令∙REORG 命令∙BACKUP DATABASE 命令∙实用程序请求在使用了 DB2V9.7 锁定事件监视器后,IBM 不推荐继续使用早期的死锁事件监视器(CREATE EVENT MONITOR FOR DEADLOCKS 语句和DB2DETAILDEADLOCK),同时不推荐使用锁定超时报告功能(DB2_CAPTURE_LOCKTIMEOUT 注册表变量)。
性能测试中DB2数据库死锁问题浅析一、引言性能测试中发现死锁,是比较严重的问题。
笔者从事主机性能测试多年,死锁问题却较为少见。
有幸在一个小项目的测试中,发现死锁,倒成了一次难得的学习机会。
在笔者进行该项目测试时,选用同一行部100个账户,执行关联账户和解除关联交易测试。
当开展解除关联交易测试因成功率不足而排查问题时,发现其逆交易关联账户交易出现少量死锁。
进一步定位该问题过程中,解除关联交易也出现一例因死锁导致交易失败的情况。
异常表中记录了发生死锁的程序Z1和表A,除此之外,CQM中显示程序Z1、Z2、Z3存在SQL大于1秒情况,SQLCODE显示-913(因为死锁或超时导致不成功执行)。
打印系统死锁报告进一步分析问题。
二、DB2锁机制为了讲清楚本次测试发现的死锁问题,需要先对DB2数据库常用锁类型和隔离级别进行简单回顾。
常用锁类型:Share —共享锁,即S锁,只能进行读操作。
Update —更新锁,即U锁,可以进行更新操作。
Exclusive —排它锁,即X锁。
它们三者的使用关系见下表。
以目前所持有的为S锁举例,请求锁如果是S锁和U锁,则允许同时存在,X锁不行。
简单来说,就是事务对一个数据对象加了S锁,可以允许其它事务对这同一个数据对象再加S锁或U锁,但不允许加X锁。
数据库隔离级别:RR —Repeatable Read如果使用这种隔离级,在一个事务中所有被读取过的行上都会被加上S锁,直到该事务被提交或回滚,行上的锁才会被释放。
这样可以保证在一个事务中即使多次读取同一行,得到的值也不会改变。
另外,在同一事务中如果以同样的搜索标准重新打开已被处理过的游标,得到的结果集不会改变。
即通常所说的无幻象。
RS —Read Stability如果使用这种隔离级,在一个事务中所有符合条件的行上都会被加上S锁,直到该事务被提交或回滚,行上的锁才会被释放。
这样可以保证在一个事务中即使多次读取同一行,得到的值不会改变。
查看锁表 db22010-11-11 17:34方法一:用db2pd注意执行db2pd命令时如果数据库没有激活,则会报这个错误:Database dbname not activated on database partition 0.首先激活一下数据库: db2 activate database dbname看应用在等什么#db2pd -db eos -locks showlock waitDatabase Partition 0 -- Database EOS -- Active -- Up 0 days 07:42:56Locks:Address TranHdl Lockname Type Mode Sts Owner Dur HldCnt Att Rlse0x2C8E0760 3 02001806078066020000000052 Row ..X W 2 1 0 0 0x0 TbspaceID 2 TableID 156 RecordID 0x2668007锁的类型为Row(行锁),X锁(排他锁),下面是我们最关心的锁的位置TbspaceID 2 TableID 156 RecordID 0x2668007其中TbspaceID为表空间ID,TableID为表的ID,RecordID代表具体位置,全部应该是0x0266807,其中前面三个字节为page number,为0x02668,后面一个字节代表solt identifier,为0x073、找到相应的表#db2 "select tbspace,tabschema,tabname,tableid,tbspaceid from syscat.tables where tbspaceid=2 and tableid=1560"TBSPACE TABSCHEMA TABNAME TABLEID TBSPACEID------------ ----------- ---------- ------- ---------USERSPACE1 DB2INST1 AA_TEST 156 21 record(s) selected.方法二:用快照UPDATE MONITOR SWITCHES USING LOCK ONGET SNAPSHOT FOR LOCKS ON <dbname>update monitor switches using lock off方法三:#show all the switchesdb2 get monitor switches#switch-name:BUFFERPOOL、LOCK、SORT、STATEMENT、TABLE、TIMESTAMP 和 UOW#set the switches ON/OFFdb2 update monitor switches using table off#DB2 snapshot 用于锁定位(管理视图)db2 get snapshot for locks on <table or dbname >Select substr(tabschema,1,8) as tabschema, substr(tabname,1,15) as tabname,lock_object_type, lock_mode, lock_mode_requested, agent_id_holding_lkFrom sysibmadm.lockwaits注:db2 +c为不自动提交(commit)SQL语句,也可以通过 db2 update command options using c off关闭自动提交(autocommit,缺省是自动提交)db2 +c insert into lgxswfc values(2)+++++++++++++ExAMPLE+++++++++++#session1db2 +c insert into lgxswfc values(2)+++#session2db2 select * from lgxswfc#此时session2 挂起+++#session3Select substr(tabschema,1,8) as tabschema, substr(tabname,1,15) as tabname,lock_object_type, lock_mode, lock_mode_requested, agent_id_holding_lkFrom sysibmadm.lockwaitsdb2 FORCE APPLICATION(agent_id_holding_lk); --结束进程。
分析锁等待事件,找出锁表语句1.找出锁等待情况db2pd -db foticdb -locks wait showlocks// -file lockwait.txt导出结果到文件lockwait.txt可以看到上图中有一个X锁,TranHdl=106,Sts=G(锁的授权者即持有者),事务TranHdl=91的锁类型为U,Sts=W,即处于锁等待状态,Owner=106,即91的事务等待106的事务释放锁事务91才能执行。
如果需要找到事务106所执行的SQL,必须找到事务106对应的APPID。
2.找到事务对应的AppHandldb2pd -db fotest –transactions以上返回结果中可以看到事务91对应的AppHandl=59574,事务106对应的AppHandl=59131。
3.找到应用程序对应的AnchIDdb2pd -db fotest -applications可以看到上图中AppHandl=59131的应用L-AnchID=233,L-StmtUID=74.找到L-AnchID=233,L-StmtUID=7对应的SQLdb2pd -db fotest -dynamic上图中可以看到AnchID=233,StmtUID=7的应用执行的SQL为Update locktest set suibian=33 where suibian=22到此所有查询都结束。
5.总结应为db2pd是数据库实时监测,正式执行查找,可一次导出以上所有信息,到文件中,再分析锁表情况。
执行语句:db2pd -db foticdb -locks wait showlocks -transactions -agents -applications -dynamic -file db2pd.out -repeat 15 40//-repeat 15 40为没隔15s执行一次db2pd语句,总共执行40次//-file 将结果导出到db2pd.out文件中。
记录⼀次问题解决:DB2死锁解决办法(SQLCODE=-
911,SQLSTATE=40001)
(DB2的数据库)在做update更新的时候,发⽣了死锁。
后台报的错误为:SQLCODE=-911, SQLSTATE=40001
---------------------------------------
SQLCODE=-911, SQLSTATE=40001 错误的原因:是在执⾏update语句的时候发⽣了死锁
SQLCODE=-911, SQLSTATE=40001 解决⽅法:
---------------------------------------
然后我在CSDN上看到⼀个解决办法,成功搞定死锁
db2 命令⾏:
1、⽤管理员⽤户登录:db2 connect to 你的数据库名 user ⽤户名 using 密码
2、db2 "get snapshot for locks on 数据库名"
-------上⾯语句执⾏完成以后,你可以找到下⾯⼀段⽂字
应⽤程序句柄 = 689
应⽤程序标识 = *LOCAL.DB2.120711101108
序号 = 00001
应⽤程序名 = javaw.exe
CONNECT 授权标识 = DB2ADMIN
应⽤程序状态 = UOW 正在等待
3、db2 "force application(689)" 689就是上⾯查询出来的应⽤程序句柄
杀掉死锁进程。
本文通过一个实例讲解了在DB2版本9以后,如何使用db2pd命令捕获死锁信息死锁经常会存在于我们的应用系统中,如何捕获死锁信息并解决死锁问题,是一个比较复杂的问题。
DB2提供了死锁事件监控器来获取死锁信息,可以非常方便地获取死锁信息。
从DB2版本8.2.2开始,DB2也可以使用db2pd命令和db2cos脚本来获取死锁信息,提供了一种新的途径来获取死锁信息。
从DB2版本9开始,我们可以使用db2pd -catch 命令来捕获错误信息,然后调用一个sqllib/db2cos 的脚本收集出错时的现场信息。
该命令的使用语法如下:Usage:-catch clear | status | <errorCode> [<action>] [count=<count>]Sets catchFlag to catch error or warning.Error Codes:<sqlCode>[,<reasonCode>] / sqlcode=<sqlCode>[,<reasonCode>]ZRC (hex or integer)ECF (hex or integer)"deadlock" or "locktimeout"Actions:[db2cos] (default) Run sqllib/db2cos callout script[lockname=<lockname>] Lockname for catching specific lock(lockname=000200030000001F0000000052)[locktype=<locktype>] Locktype for catching specific lock(locktype=R or locktype=52)下面我们通过一个实例来讲解如何使用db2pd -catch命令获取死锁信息。
如无特殊说明,命令均使用DB2实例用户执行。
1、将$HOME/sqllib/cfg/db2cos例子脚本拷贝到$HOME/sqllib下,并改变属性为实例用户添加执行权限:cp $HOME/sqllib/cfg/db2cos $HOME/sqllibchmodu+x $HOME/sqllib/db2cos2、设置db2pd -catch捕获死锁信息,当死锁出现的时候调用db2cos命令。
可以使用如下命令之一:1)db2pd -catch deadlock2)db2pd -catch -911,2例子输出如下:$ db2pd -catch deadlockError Catch #1Sqlcode: 0ReasonCode: 0ZRC: -2146435070ECF: 0Component ID: 0LockName: Not SetLockType: Not SetCurrent Count: 0Max Count: 255Bitmap: 0xA1Action: Error code catch flag enabledAction: Execute sqllib/db2cos callout script此时查看db2diag.log的输出,可以看到类似信息:2006-03-30-17.23.01.128996+480 I25427C274 LEVEL: EventPID : 1773620 TID : 1 PROC : db2pdINSTANCE: db2fp9i1 NODE : 000FUNCTION: DB2 UDB, RAS/PD component, pdErrorCatch, probe:30 START : Error catch set for ZRC -2146435070我们可以看到错误捕获机制已经启动。
3、新开一个命令窗口,我们称之为窗口1,输入如下命令:$db2 +cdb2 => connect to sampleDatabase Connection InformationDatabase server = DB2/6000 8.2.2SQL authorization ID = DB2FP9I1Local database alias = SAMPLEdb2 => create table tstdlock1 (id int, name char(10))DB20000I The SQL command completed successfully.db2 => commitDB20000I The SQL command completed successfully.db2 => insert into tstdlock1 values(1,'test1')DB20000I The SQL command completed successfully.4、再新开一个命令窗口,我们称之为窗口2,输入如下命令:$db2 +cdb2 => connect to sampleDatabase Connection InformationDatabase server = DB2/6000 8.2.2SQL authorization ID = DB2FP9I1Local database alias = SAMPLEdb2 => create table tstdlock2 (id int, name char(10))DB20000I The SQL command completed successfully.db2 => commitDB20000I The SQL command completed successfully.db2 => insert into tstdlock2 values(2,'test2')DB20000I The SQL command completed successfully.db2 => select * from tstdlock1此时该命令会挂起,处于锁等待状态,等待窗口1中的insert语句完成后才能继续进行。
5、切换到窗口1,输入如下命令:db2 => select * from tstdlock2此时该命令也会挂起,处于锁等待状态,等待窗口2中的insert语句完成后才能继续进行。
6、等待一段时间,取决于数据库的配置参数DLCHKTIME的设置,默认为10秒。
就会发现窗口2中的事务因为死锁回滚:SQL0911N The current transaction has been rolled back because of a deadlockor timeout. Reason code "2". SQLSTATE=40001而窗口1中的命令执行成功:db2 => select * from tstdlock2ID NAME----------- ----------0 record(s) selected.注意:在实际的测试中,也可能是窗口1中的事务回滚。
此时查看db2diag.log文件,会看到如下信息:2006-03-30-17.29.05.273286+480 I28093C411 LEVEL: EventPID : 1597606 TID : 1 PROC : db2agent (SAMPLE) 0INSTANCE: db2fp9i1 NODE : 000 DB : SAMPLEAPPHDL : 0-8 APPID: *LOCAL.db2fp9i1.060330092553FUNCTION: DB2 UDB, trace services, pdInvokeCalloutScript, probe:10START : Invoking sqllib/db2cos script from global services sqlzeMapZrc2006-03-30-17.29.05.868458+480 I28505C388 LEVEL: EventPID : 1597606 TID : 1 PROC : db2agent (SAMPLE) 0INSTANCE: db2fp9i1 NODE : 000 DB : SAMPLEAPPHDL : 0-8 APPID: *LOCAL.db2fp9i1.060330092553FUNCTION: DB2 UDB, trace services, pdInvokeCalloutScript, probe:20STOP : Completed invoking sqllib/db2cos script说明我们的错误捕获机制已经成功捕获到死锁信息,并且调用了db2cos脚本。
此时查看$HOME/sqllib/db2dump目录,会看到db2cos.rpt文件。
注意,对于出现死锁的情况,我们的错误捕获机制会两次调用db2cos脚本,第一次是在事务回滚前,第二此则是事务回滚后。
查看死锁的信息,我们应该关注第一次调用db2cos脚本的输出。
现在我们看一下db2cos例子脚本的内容,可以看到出现死锁时我们的处理机之:"DEADLOCK")echo "Lock Deadlock Caught" >> $HOME/sqllib/db2dump/db2cos.rptdate>> $HOME/sqllib/db2dump/db2cos.rptecho "Instance " $instance >> $HOME/sqllib/db2dump/db2cos.rptecho "Datbase: " $database >> $HOME/sqllib/db2dump/db2cos.rptecho "Partition Number:" $dbpart>> $HOME/sqllib/db2dump/db2cos.rptecho "PID: " $pid>> $HOME/sqllib/db2dump/db2cos.rptecho "TID: " $tid>> $HOME/sqllib/db2dump/db2cos.rptecho "Function: " $function >> $HOME/sqllib/db2dump/db2cos.rptecho "Component: " $component >> $HOME/sqllib/db2dump/db2cos.rptecho "Probe: " $probe >> $HOME/sqllib/db2dump/db2cos.rptecho "Timestamp: " $timestamp >> $HOME/sqllib/db2dump/db2cos.rptecho "AppID: " $appid>> $HOME/sqllib/db2dump/db2cos.rptecho "AppHdl: " $apphld>> $HOME/sqllib/db2dump/db2cos.rptdb2pd -db $database >> $HOME/sqllib/db2dump/db2cos.rpt;;我们看到,如果捕获到的错误是死锁(DEADLOCK)的话,我们将执行db2pd -db $database获取数据库的所有db2pd输出。