电脑技术学习

DB2 for z/OS Web 应用程序死锁分析

dn001
  本文阐述了开发人员和测试人员如何确定 DB2 for z/OS 环境下复杂 Web 应用程序中的死锁原因。  简介  在任何数据库环境中,死锁检测对于应用程序并发性都是很重要的。就像其他应用程序一样,在复杂 Web 环境中也需要能够确定任何死锁的起因。本文解释了如何配置 DB2 for os/390 的死锁跟踪设置,以启用死锁分析。先阐述了如何指定相关的 DB2 for z/OS 跟踪以获取足够信息,然后说明如何分析这些跟踪报告,并指出引起 DB2 for z/OS 环境中运行的复杂 Web 应用程序出现死锁的不良 SQL 语句。本文假定读者熟悉基本的 z/OS 操作。  使用 DB2 Performance Monitor 来配置跟踪  Locking 跟踪  若要启用 Locking 跟踪,首先打开 IBM DB2 Performance Monitor 应用程序。然后执行下面步骤:  配置 Collect Task A 以收集死锁跟踪。设置 Trigger by 4=Immediate Start 以立即激活任务。  选择 Locking, Data Type, IFICD, Requesting Location, Plan name and Authid,然后按 Enter。  图 1. 配置 Collect Task A    选择数据类型 Lockout,然后按 Enter。  在 IFCID Selection 面板中,选择下面的 IFICD,然后按 Enter。105  DBID/OBID for database and tablespace translation 
107  Data set open/close information          
172  Deadlock
  在 Trace Qualification 面板中,填入 DB 用户名(在本例中为 TUSER03)和 DB 模式(在本例中为 TGUSER03),然后按 Enter。  图 2. Trace qualification 面板    在 Trigger Immediately 面板中,填入 DB2 跟踪数据的输出数据集(例如,TGUSER03.DB2PM.TRACE01)。设置 Disposition 为 Overwrite。  注重:可以使用其他方法来配置 DB2 跟踪停止触发器(例如,经过一段时间后)。  图 3. Trigger immediately 面板    按 Enter,完成 Locking 跟踪配置。  假如 Web 应用程序运行期间有死锁,则激活 Collect Task A 来收集死锁信息。  SQL Activity 跟踪  按照下面步骤来配置 SQL Activity 跟踪:  配置 Collect Task B 以收集 SQL Activity 跟踪。设置 Trigger by 4=Immediate Start 来立即激活任务。  选择 SQL Activity, Data Type, IFCID, Requesting Location, Plan name and Authid,然后按 Enter。  选择全部收集数据类型,然后按 Enter。  在 IFCID Selection 面板中,选择下面的 IFCID,然后按 Enter:16  Start of the first insert
20  Lock summary 
53  Describe, SQL commit/rollback or error before SQL analyzed
58  End of SQL statement execution  
59  Start of FETCH         
60  start of SELECT
61  Start of INSERT, UPDATE or DELETE
63  SQL statement to be parsed 
64  start of PREPARE  
65  start of OPEN CURSOR for static or dynamic SQL 
66  Start of CLOSE CURSOR for static or dynamic SQL 
68  Start of ROLLBACK                
69  End of ROLLBACK                 
70  Start of COMMIT phase 2             
71  End of COMMIT phase 2              
88  start of synchronous request (commit phase 1)
89  End of synchronous request (commit phase 1) 
105  DBID/OBID for database and tablespace translation
  在 Trace Qualification 面板中,填入 DB 用户名(例如,TUSER03)和 DB 模式(例如,TGUSER03),然后按 Enter。  在 Trigger Immediately 面板中,填入 DB2 跟踪数据的输出数据集(例如,TGUSER03.DB2PM.TRACE02)。设置 Disposition 为 Overwrite。  注重:可以使用其他方法来配置 DB2 跟踪停止触发器(例如,经过一段时间后)。  按 Enter 完成 SQL Activity 配置。  在 Web 应用程序运行期间,激活 Collect Task B 来收集 SQL 语句。  分析跟踪报告以确定不良 SQL 语句  Web 应用程序中 DB2 锁的原理  通常 Web 应用程序有页锁和行锁。根据创建数据库所使用的数据定义语言 (DDL) 模式文件,可以确定正在使用的锁类型。行锁有三种模式:S(Share)、U(Update) 和 X(Exclusive)。要尽量避免的锁影响是挂起、超时和死锁。  当两个或两个以上应用程序进程均持有对资源(该资源是其他进程所需,且没有该资源时进程无法继续进行)的锁时,会发生死锁。下面是关于发生死锁情况的具体解释:  JobOne 和 JobTwo 是两个事务。JobOne 访问表 M,并持有页 B 的 X (exclusive) 锁,包含记录 000300。  JobTwo 访问表 N,并持有页 A 的 X (exclusive) 锁,包含记录 000010。  JobOne 请求表 N 页 A 的锁,同时仍持有表 M 页 B 的锁。因为 JobTwo 持有页 A 的 X 锁,所以作业被挂起。  JobTwo 请求表 M 页 B 的锁,同时仍持有表 N 页 A 的锁。因为 JobOne 持有页 B 的 X 锁,所以作业被挂起。这种情况就是死锁。  为了改善应用程序的并发性,您需要找到引起死锁的 SQL 语句。然后,优化 SQL 语句以消除死锁。  根据死锁报告来分析锁信息  作为例子,我们假定当多个顾客同时登录并注册一个商店时发生死锁。您已经得到死锁跟踪报告和 SQL 语句报告。  首先,您应检查死锁跟踪报告(在本文中为 TGUSER03.DB2PM.LOCKS)。  下面是跟踪报告中一些要害参数的说明,有助于理解该进程:  图 4. 跟踪参数    分析一下表 USERS(图 5 和图 6)上的第一个死锁。在图 5 中,可以看到死锁涉及到两个资源。分别是 row X'2B'、page X'00004E'、page USERS、DB SW03DB1 和 row X'2B'、page X'00004C'、table USERS、DB SW03DB1。WAITERS =2 表明死锁中有两个等待者(0CC544053119 和 0E26A4053107)。死锁发生在 12/05/05 06:30:09.40。  从图 6 可以看到资源持有者和等待者与图 5 中的相反。等待者(实际上是图 5 中的持有者)正在请求持有者(实际上是图 5 中的等待者)所持有的资源。按照死锁的定义,在这种情况下会发生死锁。  现在,利用图 5 和图 6 来总结一下锁关系。  从图 5 中可以看到 LUW 0CC544053119 所持有的锁是 row X'2B'、page X'00004E'、table USERS、DB SW03DB1 上的行锁,且保持在 X 状态。等待者 LUW 实例 0E26A4053107 正在请求同一个资源上的 S 锁模式。而在图 6 中,LUW 0E26A4053107 所持有的锁是 row X'2B'、page X'00004C'、table USERS、DB SW03DB1 上的行锁,且保持在 X 状态。等待者 LUW 实例 0CC544053119 正在请求同一个资源上的 S 锁模式。因此发生死锁。  最后,请注重图 5 中的 BLOCKER is HOLDER --*VICTIM*,该线程 ("victim") 的作用是回滚以进行其他线程。  图 5. Locking 跟踪 —— 死锁报告    图 6. Locking 跟踪 —— 死锁报告    表 1 总结死锁分析:  表 1. 死锁分析
LUW 实例 持有的资源(X 锁) 请求的资源(S 锁) 死锁时间表
0CC544053119 SW03DB1.USERS.X'00004E'.X'2B' SW03DB1.USERS.X'00004C'.X'2B' 06:30:09.41044991
0E26A4053107 SW03DB1.USERS.X'00004C'.X'2B' SW03DB1.USERS.X'00004E'.X'2B' 06:30:09.41044991
  根据 SQL 活动报告来分析 SQL 信息  打印 SQL ACTIVITY 跟踪(在本文中为 TGUSER03.DB2PM.SQL),使用死锁所涉及的 LUW INSTANCE 数量(0CC544053119 和 0E26A4053107)进行过滤。可以发现最后一次 commit 操作应正好在死锁出现 (06:30:09.41044991) 前完成。接下来,搜索仅在完成最后一次 commit 操作后执行的 SQL 语句。COMMIT processing in SQL ACTIVITY trace for INSTANCE 0CC544053119
COMMIT RECEIVED   06:28:50.72
COMMIT RECEIVED   06:28:50.85
COMMIT RECEIVED   06:28:50.97
COMMIT RECEIVED   06:28:51.04    the latest commit before the deadlock occurred.
COMMIT RECEIVED   06:30:09.61
COMMIT RECEIVED   06:30:09.64
COMMIT RECEIVED   06:30:09.73
COMMIT RECEIVED   06:30:09.77
COMMIT RECEIVED   06:30:09.80
  因此,应该研究那些访问过 SW03DB1.USERS 且在 06:28:51.04 到 06:30:09.41044991 之间执行的 SQL 语句。如图 7 所示。  图 7. SQL 报告    根据锁状态 X 和 S,对于资源 SW03DB1.USERS,在 SELECT 语句之前应是 INSERT 语句。  按照同样的方法,对于 INSTANCE 0E26A4053107,可以找到在出现死锁前进行最后一次 commit 的时间.COMMIT processing in SQL ACTIVITY trace for INSTANCE 0E26A4053107
COMMIT RECEIVED   06:28:50.65    the latest commit before the deadlock occurred.
COMMIT RECEIVED   06:30:49.67
  然后,研究那些访问过 SW03DB1.USERS 且在 06:28:50.65 到 06:30:09.41044991 之间执行的 SQL 语句。如图 8 所示。  图 8. SQL 报告    从图 5 和图 6 中可以看到两个实例 0CC544053119 和 0E26A4053107 正尝试提交 INSTER INTO USERS 和 SELECT FROM USERS SQL 语句。由于 INSERT 和 SELECT 语句之间没有 COMMIT,死锁可能是由表扫描引起的。因此运行并发线程时,出现了死锁。  结束语  本文阐述了如何使用 DB2 Performance Monitor 工具来收集死锁和 SQL Activity 跟踪。另外,给出了一个例子,演示如何通过分析跟踪找到一个死锁情况所涉及的 SQL 语句。使用该方法,开发人员和测试人员都可以发现不良 SQL 语句,并完成并发性能问题解决方案的第一步。