文章编号: 832524 - 最后修改: 2007年4月25日 - 修订: 1.6 SQL Server 技术公告-如何解决死锁本页SQL Server 技术公告主题介绍此问题: 如何解决死锁目标若要标识、 疑难解答,和建议用于解决死锁的解决方案。 简介本文检查死锁情况,并提供有关步骤,用于解决死锁。 每个死锁可能会有所不同,并且可以由几个不同的环境变量引起。 本文中提供的信息可以帮助您识别并解决死锁。 案例研究在一个的案例研究中,我们将分析 911 有六个运算符的系统。 在活动高峰期期间他们使用的在 Microsoft Visual Basic 前端应用程序遇到已中断的连接。 由于已中断的连接的运算符必须 re-input 数据。 对于 911 系统操作一天 24 小时,七天一周,此行为是不可接受。 死锁是什么?当两个时,会发生死锁系统服务器进程 id (spid) 等待资源和两个进程可以换片,因为其他进程正防止它获取该资源。 锁管理器已经线程检查为死锁。 当锁管理器已经死锁检测算法检测到死锁时,锁管理器可选择该 spid 之一为牺牲品。 锁管理器将启动一个 1205年的错误消息,发送到该客户的和锁管理器删除该 SPID。 取消该 SPID 释放资源,并允许其他 SPID 以继续。 取消已死锁牺牲品的 SPID 是什么导致可视化的基本前端应用程序遇到该断开的连接。 在设计良好的应用程序前端应用程序应 1205年错误的补漏白、 重新连接到 SQL Server,然后重新提交该事务。 尽管可以最小化死锁,它们不能被完全避免。 这就是前端应用程序应设计为处理死锁的原因。 如何识别死锁第 1 步 若要打算死锁,您首先必须获得日志信息。 如果您怀疑死锁,您必须收集有关 (spid) 和死锁中涉及的资源的信息。 若要执行此操作将添加-T1204 和到 SQL Server-T3605 启动参数。 若要将这些两个启动参数,请按照下列步骤操作:
启动参数将 SQL Server 是停止,然后开始重新启动时生效。 -T1204 启动参数收集有关该过程的信息和资源死锁检测算法遇到死锁时。 -T3605 启动参数将此信息写入 SQL Server 错误日志。 -T1205 启动参数收集信息死锁算法检查一个死锁时遇到了死锁时,不为每个时间。 您没有使用-T1205 启动参数。 如果您使用-T1205 启动参数下面是 SQL Server 错误日志中将输出的示例: 2003-05-14 11:46:26.76 spid4 Starting deadlock search 1 2003-05-14 11:46:26.76 spid4 Target Resource Owner: 2003-05-14 11:46:26.76 spid4 ResType:LockOwner Stype:'OR' Mode: S SPID:55 ECID:0 Ec:(0x43CAB580) Value:0x42bdf340 2003-05-14 11:46:26.76 spid4 Node:1 ResType:LockOwner Stype:'OR' Mode: S SPID:55 ECID:0 Ec:(0x43CAB580) Value:0x42bdf340 2003-05-14 11:46:26.76 spid4 2003-05-14 11:46:26.76 spid4 End deadlock search 1 ... a deadlock was not found. 2003-05-14 11:46:26.76 spid4 ---------------------------------- 2003-05-14 11:46:31.76 spid4 ---------------------------------- 2003-05-14 11:46:31.76 spid4 Starting deadlock search 2 有时,您可能不能停止并重新启动 SQL Server。 在这种情况下可以使用查询分析器运行以下命令来启用死锁跟踪标志。 注意 这种方式可以立即收集有关该死锁的信息。 "-1"表示所有的 spid。 步骤 2 接下来,您必须收集 SQL 事件探查器跟踪。 濡傛您鎵撳紑死锁跟踪标记将获取大多数所需的信息,但并非总是如此。 渚嬪案例研究中跟踪标志输出标识 sp_cursoropen 系统存储过程和一个"UPDATE tblQueuedEvents 设置 notifyid = 3,ResynchDate"死锁中涉及语句。 遗憾的是,您不知道 sp_cursoropen 系统存储过程的定义。 您还没有完成 UPDATE 语句因为它已被截断。 SQL 事件探查器可以获得除了该执行计划的语句的完整的语句。 SQL 事件探查器跟踪还具有一个锁事件为"死锁"和"死锁的链。 对应于-T1204 标志的"死锁"和"死锁的链"对应于-T1205 标志。 死锁跟踪标记打开和运行期间出现的死锁的 SQL 事件探查器跟踪应该提供您解决死锁所必需的数据。 在这种情况下,在其他,运行 SQL 事件探查器更改执行不足以避免死锁的计时。 因此,您通常将捕获死锁信息与跟踪标志,然后运行 SQL 事件探查器。 鐤戦毦瑙 g 瓟死锁发生死锁后,您可以通过使用 sqldiag 实用工具,以及通过使用 SQL 事件探查器收集有关死锁的信息。 SQLDiag.txt 的文件的在输出中查找"等待为图形"条目。 A"等待-为图形"条目指示遇到了死锁。 下面是一个示例使用时可能会看到 SQL Server 错误日志中将输出-T1205 启动参数。 2003-05-05 15:11:50.80 spid4 Wait-for graph 2003-05-05 15:11:50.80 spid4 Node:1 2003-05-05 15:11:50.80 spid4 ResType:LockOwner Stype:'OR' Mode: S SPID:55 ECID:0 Ec:(0x33AE1538) Value:0x193 2003-05-05 15:11:50.80 spid4 Victim Resource Owner: 2003-05-05 15:11:50.80 spid4 ResType:LockOwner Stype:'OR' Mode: X SPID:60 ECID:0 Ec:(0x1F1BB5B0) Value:0x193 2003-05-05 15:11:50.80 spid4 Requested By: 2003-05-05 15:11:50.80 spid4 Input Buf: RPC Event: sp_cursoropen;1 2003-05-05 15:11:50.80 spid4 SPID: 55 ECID: 0 Statement Type: EXECUTE Line #: 1 2003-05-05 15:11:50.80 spid4 Owner:0x1937f2a0 Mode: S Flg:0x0 Ref:1 Life:00000000 SPID:55 ECID:0 2003-05-05 15:11:50.80 spid4 Grant List 0:: 2003-05-05 15:11:50.80 spid4 KEY: 8:1653632984:2 (da00ce043a9e) CleanCnt:1 Mode: U Fl ags: 0x0 2003-05-05 15:11:50.80 spid4 Node:2 2003-05-05 15:11:50.80 spid4 ResType:LockOwner Stype:'OR' Mode: S SPID:55 ECID:0 Ec:(0x33AE1538) Value:0x193 2003-05-05 15:11:50.80 spid4 Requested By: 2003-05-05 15:11:50.80 spid4 Input Buf: Language Event: Update tblQueuedEvents Set NotifyID = 2, ResynchDate 2003-05-05 15:11:50.80 spid4 SPID: 60 ECID: 0 Statement Type: UPDATE Line #: 1 2003-05-05 15:11:50.80 spid4 Owner:0x1936e420 Mode: X Flg:0x0 Ref:0 Life:02000000 SPID:60 ECID:0 2003-05-05 15:11:50.80 spid4 Grant List 0:: 2003-05-05 15:11:50.80 spid4 KEY: 8:1653632984:1 (2d018af70d80) CleanCnt:1 Mode: X Flags: 0x0 在"等待为图形"项中有节点 1 和节点 2。 每个节点中具有授予部分和请求部分。 授予部分是"允许列表",和请求部分是在"请求者"。 每个节点中,您可以识别以下:
渚嬪节点 1 授予列表中 SPID 55 了授予权限更新锁模式: U 上资源 KEY: 8:1653632984:2。 8 = DBID,1653632984 = ObjectID,和 2 = Indid。 若要获取数据库标识号,运行 sp_helpdb 存储过程。 若要获取表,运行下面的代码: 要获得索引,运行下面的代码: 等于 2 IndexId 是否知道该索引是聚集索引。 SPID 55 正在执行该命令为 sp_cursoropen 存储过程。 节点 2 授予列表中 SPID 60 已授予的排它锁模式: X 上资源 KEY: 8:1653632984:1。 8 = DBID,1653632984 = ObjectID,1 = Indid。 这是在同一个表,但 1 的索引是聚集的索引。 SPID 60 正在执行该命令为: 等于 1 的 IndexId 是聚集的索引。 等于 2 一个 IndexId 是一个非聚集索引。 注意 死锁是很敏感的时间。 接下来,在节点 1 请求者 SPID 55 请求共享的锁模式: S,IndexId 上 = 1。 在节点 2 中请求者,SPID 60 请求一个独占锁模式: X 上 IndexId = 2。 因为这些锁请求发生在同一时间,则会发生死锁。 每个 SPID 授予锁正在阻止请求的锁然后继续。 下表显示了锁兼容性图表。 有关锁兼容性的详细信息请参阅 SQL Server 2000 丛书联机中的"锁定兼容性"主题。 锁兼容性图表 收起该表格
接下来,通过查看输出标识为 tblQueuedEvents 表 ObjectId 1653632984,并获得 sp_help 存储过程输出表。 在表上没有两个索引。 两个索引了 ix_tblQueuedEvents 和 PK_tblQueuedEvent。 ix_tblQueuedEvents 是在 ResynchDate,上的一个聚集的索引,PK_tblQueuedEvent 是一个主关键字上 EventSID 的唯一非聚集索引。 SQL 事件探查器跟踪未捕获死锁匹配项。 记住的死锁是很从属的时间。 SQL 事件探查器的系统开销可能添加到一个进程的执行的一些时间并的妨碍 SQL 事件探查器在死锁情况中获取。 但是,它未提供可用来排查此问题的信息。 找到完全更新 tblQueuedEvents 语句,以与以下类似: 下面是执行计划。 注意 阅读此特定的执行计划从右到左和底部到顶部。 StmtText
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
Update tblQueuedEvents Set NotifyID = 2, ResynchDate = '5/7/2003 10:44:16'
where eventSID = 73023
|--Clustered Index
Update(OBJECT:([SOTS].[dbo].[tblQueuedEvents].[ix_tblQueuedEvents ]),
SET:([tblQueuedEvents].[NotifyID]=[@1],
[tblQueuedEvents].[ResynchDate]=[Expr1004]))
|--Top(1)
|--Compute Scalar(DEFINE:([Expr1004]=Convert([@2])))
|--Index
Seek(OBJECT:([SOTS].[dbo].[tblQueuedEvents].[PK_tblQueuedEvents]),
SEEK:([tblQueuedEvents].[EventSID]=[@3])
建议解决方案以解决死锁请注意 UPDATE 语句的执行聚集索引上的"聚集的索引更新"。 因此,非聚集索引和聚集的索引必须同时更新。 聚集的索引是 ix_tblQueuedEvents 和非聚集的索引是 PK_tblQueuedEvents。 若要进行了更新 UPDATE 语句必须获得两个索引上的排它锁。 这些两个的索引是死锁中涉及的索引。 从审查 SQL 事件探查器跟踪,您做不到在 WHERE 子句中使用该 ResynchDate 的任何查询。 所有语句非常特定并且 WHERE 子句中使用它们在 EventSID。 聚集索引的更好的选择将为 EventSID。 使用此信息和与客户讨论,我们找到 ResynchDate 索引被旧,并没有必要。 我们建议客户放在 ResynchDate,上的 ix_tblQueuedEvents 索引和它们使 PK_tblQueuedEvent 聚集的索引。 这解析死锁情况。 这是涉及锁的死锁事例的一个示例。 死锁也可以涉及并行度和涉及线程。 它们可以涉及一个、 二、 三,或多个 spid 和资源。 与任何死锁案例中,您必须获取 –T1204 启动参数输出和 SQL 事件探查器跟踪识别疑难解答,和解决死锁。 不同的进程和资源,则将涉及死锁情况。 因此,解决方案将大小写情况而异。 您可以使用解决死锁的典型方法包括:
其他阅读有关死锁的详细信息请访问以下 Microsoft 网站: http://msdn2.microsoft.com/en-us/library/Aa213040 (http://msdn2.microsoft.com/en-us/library/Aa213040) http://msdn2.microsoft.com/en-us/library/aa213042(SQL.80).aspx (http://msdn2.microsoft.com/en-us/library/aa213042(SQL.80).aspx) http://msdn2.microsoft.com/en-us/library/aa213028(SQL.80).aspx (http://msdn2.microsoft.com/en-us/library/aa213028(SQL.80).aspx) http://msdn2.microsoft.com/en-us/library/aa937573(SQL.80).aspx (http://msdn2.microsoft.com/en-us/library/aa937573(SQL.80).aspx) http://msdn2.microsoft.com/en-us/library/aa213041(SQL.80).aspx (http://msdn2.microsoft.com/en-us/library/aa213041(SQL.80).aspx) 机器翻译注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。 点击这里察看该文章的英文版: 832524?
(http://support.microsoft.com/kb/832524/en-us/
)
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。 | 文章翻译
|


回到顶端
