捕获和分析 SQL Server 中的死锁





5.00/5 (2投票s)
如何在 SQL Server 中捕获和分析死锁。
无论你的代码多么完美,以及你编写的方式多么优化,面临死锁的情况是不可避免的。而且,当你明明知道发生了死锁,却不知道谁是受害者,谁是肇事者时,情况会变得更加复杂。
捕获和分析死锁的方法有几种。我将在本文中解释两种方法
- 启用跟踪标志以将死锁信息捕获/记录到 SQL 日志中
- 使用 SQL Profiler 捕获死锁
启用跟踪标志以将死锁信息捕获/记录到 SQL 日志中
此方法将确保死锁详细信息记录在 SQL 日志文件中(而不是事务日志)。即使通过此方法捕获的详细信息是文本的,它也让你可以在稍后检查详细信息。
首先,你需要使用以下语法启用跟踪标志
DBCC TRACEON (1222, 1204, -1)
之后,我们将模拟死锁:(实际上,如果你正面临这样的问题,则无需这样做)。
首先,创建两个示例表并插入一些记录,我们将使用这些记录来产生死锁。
-- Create a Sample Tables --
CREATE TABLE SampleDeadLock_1(
Item_Code INT
,Item_Desc VARCHAR(100)
,Qty INT
)
CREATE TABLE SampleDeadLock_2(
Item_Code INT
,Item_Desc VARCHAR(100)
,Qty INT
)
-- Insert couple of records to each table --
INSERT INTO dbo.SampleDeadLock_1(
Item_Code
,Item_Desc
,Qty
)
VALUES
(1,'CPU', 10)
,(2, '20 GB - Hard Disk', 20)
INSERT INTO dbo.SampleDeadLock_2(
Item_Code
,Item_Desc
,Qty
)
VALUES
(3,'Monitor', 15)
,(4, 'Keyboard & MOuse', 25)
现在,在 SQL Server Management Studio 中打开两个查询窗口(窗口 1 和窗口 2)并将以下代码粘贴到“窗口 1”
BEGIN TRAN
UPDATE dbo.SampleDeadLock_1 SET Qty = 100 WHERE Item_Code = 1
WAITFOR DELAY '00:00:30'
UPDATE dbo.SampleDeadLock_2 SET Qty = 200 WHERE Item_Code = 3
并将以下代码粘贴到“窗口 2”
BEGIN TRAN
WAITFOR DELAY '00:00:10'
UPDATE dbo.SampleDeadLock_2 SET Qty = 300 WHERE Item_Code = 3
UPDATE dbo.SampleDeadLock_1 SET Qty = 400 WHERE Item_Code = 1
然后,执行窗口 1 中的代码,并立即执行窗口 2 中的代码。几秒钟后(30+),你将在窗口 1 中看到死锁错误消息。
当你检查 *ERRORLOG* 文件时,你将能够找到与死锁相关的相关详细信息。(我用红色突出显示了死锁受害者详细信息,用蓝色突出显示了肇事者详细信息。)
使用 SQL Profiler 捕获死锁(死锁图)
我们在上述方法中遇到的问题之一是,我们需要查看大量文本信息才能提取与死锁相关的详细信息。在本例中,由于我们选择了一个简单的情况,因此更容易一些。但在实际情况下,当进程有点复杂时,事情可能会变得非常困难。
在这种情况下(任何情况),我们可以使用 SQL Profiler 以更友好的方式检测死锁。
** 请注意:此方法的缺点是你需要在死锁发生时运行 profiler。如果需要在生产环境中进行故障排除,这不是最佳方法。
但是,为了便于理解,我们将看看如何实现这一点。
打开 SQL Profiler 并连接到相关的 SQL Server。在“跟踪属性”窗口中,选择“TSQL_Locks”作为模板。
在“事件选择”选项卡中,请选择以下选项
- 死锁图
- Lock:Deadlock
- Lock:Deadlock Chain
在单击运行 profiler 之前,回滚从第一个示例运行的事务(未成为死锁受害者的那个)。
单击“运行”按钮启动 profiler。一旦 profiler 运行,在查询窗口 1 上执行代码,然后执行查询窗口 2 中的代码。
一旦发生死锁,Profiler 将以图形方式显示相关信息。这将包含进行死锁故障排除所需的所有相关详细信息。如果将光标悬停在图中的进程上(显示在椭圆中),则会显示一个工具提示以及已执行的导致死锁发生的语句。
我希望这将帮助你解决死锁问题。