细化解析:如何解决有关死锁的疑难问题
在死锁中,由于多种线程在相互控制或其它线程控制的一套资源中等待,所以无法继续。死锁是循环相关的,最好通过标识相关链和有关资源中的参与者,然后为各种其它线程选择资源上中断死锁的线程来加以解决。
当死锁发生时,用户收到如下错误。
Transaction (Process ID xxx) was deadlocked on (xxx) resources with another process and has been chosen as the deadlock victim. Rerun the transaction. |
错误标识出事务在其上被锁定的资源。该资源可以是锁、并行(或通讯缓冲区)、等待线程或它们之间的组合。
要解决死锁,就必须终止循环中的一个参与者。选取死锁牺牲品时,Microsoft® SQL Server™ 2000 会查看所有的参与线程以及每个线程做了多少工作。通常,SQL Server 会选择工作量最小的参与线程作为死锁牺牲品。
使用 SQL Server 2000,可以确定参与死锁的资源,还可以用 SQL 事件探查器或跟踪标记 1204 解决锁的疑难问题。SQL 事件探查器是在 SQL Server 企业管理器中提供的一种图形工具。SQL 事件探查器提供基本的死锁检测信息。
以下的疑难解答集中在跟踪标记 1204 的使用上,它提供了允许对死锁状态进行详细分析的报告。
使用跟踪标记 1204
处于死锁状态时,跟踪标记 1204 在等待的线程、存在等待线程的资源和控制这些资源的线程间画出相关循环。
跟踪标记 1204 报告中的术语
尽管根据所涉及的资源,跟踪标记 1204 会返回不同信息,但是报告通常会包含如下术语:
节点:x
在死锁的链中表示项目号 (x)。
列表:锁的所有者可能是如下列表中的一部分:授权、转换和等待。
授权列表:列举资源的当前所有者。
转换列表:列举要把锁转换到较高级别的当前所有者。
等待列表:列举当前新锁对资源的请求。
SPID:x ECID:x
在并行进程情况下,标识系统进程 ID 线程。条目 SPID x ECID 0 表示主线程,而 SPID x ECID > 0 表示同一 SPID 的子线程。
语句类型:为 SELECT, INSERT, UPDATE 或 DELETE 语句,线程在这些语句上具有权限。
行号
发生死锁时,列出当前正在执行的批处理语句行。
输入 Buf:列出当前批处理中所有的语句。
模式:为线程请求、授权或等待的特定资源,指定锁的类型。模式可以是 IS(意向共享)、S(共享)、U(更新)、IX(意向独占)、SIX(与意向独占共享)和 X(独占)。
RID:在对锁进行控制或请求的表中,标识单个行。
RID 在跟踪标记 1204 中,表示为 RID:db_id:file_id:page_no:row_no;例如,RID: 1:1:1253:0。
TAB:标识对锁进行控制或请求的表。
TAB 在跟踪标记 1204 中表示为 TAB:db_id:object_id;例如,TAB: 2:2009058193。
KEY:在对锁进行控制或请求的索引内,标识键范围。
KEY 在跟踪标记 1204中表示为 KEY:db_id:object_id:index_id;例如,KEY: 2:1977058079:1。
PAG:标识对锁进行控制或请求的页资源。
PAG 在跟踪标记 1204 中表示为 PAG:db_id:file_id:page_no;例如 PAG: 7:1:168。
EXT:标识扩展盘区结构。
EXT 在跟踪标记 1204 中表示为 EXT:db_id:file_id:extent_no;例如,EXT: 7:1:9。
DB:标识数据库锁。
DB 在跟踪标记 1204 中表示为如下方式之一:
DB:db_idDB:db_id[BULK-OP-DB] 标识了备份数据库占用的数据库锁。DB:db_id[BULK-OP-LOG] 标识了特定数据库的备份日志占用的锁。IND:标识在索引资源上创建的索引占用的锁。 |
IND 在跟踪标记 1204 中表示为如下方式之一:
IND:db_id:object_id:index_idIND:db_id:object_id:index_id[INDEX_ID] 表明锁在索引 ID 上。IND:db_id:object_id:index_id[INDEX_NAME] 表明锁在索引名上。标识应用程序资源占用的锁。APP 在跟踪标记 1204 中表示为APP:lock_resource;例如,APP:Formf370f478。 |
当 SQL Server 选取应用程序资源为死锁牺牲品时,该应用程序资源的所有者将不会得到先前描述的错误信息。相反,当 sp_getapplock 存储过程在该应用程序资源上执行时,应用程序所有者会获得返回代码"-3"。
牺牲资源所有者:将 SQL Server 选择的特殊线程指定为中断死锁循环的牺牲品。选中的线程(以 SPID x ECID 0 标识)和所有现有子线程(以 SPID x ECID > 0 标识)将被终止。
下一个分支:表示来自死锁循环中涉及的相同 SPID 的两个或多个子线程。
当死锁涉及到平行线程时,各种子线程可能会在通讯缓冲区发生阻塞,而且一个线程会在等待别的子线程中结束。只有所有的其它线程都涉及死锁,才会发生死锁状态。下一个分支表示跟踪其它路径的死锁链。 (责任编辑:卢兆林)