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 |
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 语句,并完成并发性能问题解决方案的第一步。 新闻热点
疑难解答