环境:
server 2008 r2
Windows 7 64位
Windbg 64位
我已经知道的
,
问题:
当2个事务死锁( lock_deadlock事件)时,我使用server中的扩展事件创建内存转储。
我正在通过管理工作室手动创建此死锁场景。假设一个死锁的xaction中有两个sql语句。
begin tran
update tabl1 ... -- sql stmt 1
go
update tabl2 .. -- sql stmt 2现在,我在内存转储中找到了这个线程,并且只能找到我的stmt 2,即"update tabl2“。
无论如何,我是否可以查找线程在xaction中执行的所有sql stmt,例如,在我们的示例"update tabl1.“中?
我想知道线程以前在同一个事务中执行了什么。由于这个xaction在转储时还没有提交,所以值应该在线程内存中的某个位置。
如果我在这里说不通的话,请告诉我。我研究这个问题已经有一段时间了,我想知道这是否可能。
附加信息
背景:
我们有性能测试env,其中我们运行12小时的负载测试。第二天早上我们分析并找出一个僵局。应用程序在事务中执行7-8个dml语句(我们使用hibernate )。由于基于sys.dm_exec_sql_text的dml语句只有在缓存中才会产生结果,所以在第二天进行分析时,我们不会得到完整的dml语句集(ps:我甚至没有尝试过,当问题在1天后向我报告时)
我们今天是如何解决这个问题的:
的过去语句。
我以为我能解决这个问题:
系统id included.
对应的线程中查找历史记录。
为什么内存转储:
因为如果我必须在生产上这样做的话,这个设置会产生最小的影响。
发布于 2011-10-05 16:40:44
你对这件事太过份了。我并不声称知道线程内存的所有复杂细节,但是它没有理由将最后一次执行的语句保持在本地,它不需要它来执行事务的回滚,这是在必要时使用事务日志中的日志记录来完成的。找出死锁的原因所需的一切都已包含在死锁图XML中。你绝对不需要一个内存转储来解决这个问题。每个进程的TSQL执行堆栈包含在流程下的元素中。例如:
<process-list>
<process id="process807b6bc8" taskpriority="0" logused="0" waitresource="KEY: 14:72057594038845440 (1a39e6095155)" waittime="4739" ownerId="163539" transactionname="INSERT EXEC" lasttranstarted="2011-10-05T12:29:22.580" XDES="0x82b318b0" lockMode="S" schedulerid="2" kpid="1764" status="suspended" spid="57" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2011-10-05T12:29:04.563" lastbatchcompleted="2011-10-05T12:29:04.563" clientapp="Microsoft SQL Server Management Studio - Query" hostname="SQL2K8R2-IE2" hostpid="3736" loginname="SQLSKILLSDEMOS\administrator" isolationlevel="read committed (2)" xactid="163539" currentdb="14" lockTimeout="4294967295" clientoption1="673187936" clientoption2="390200">
<executionStack>
<frame procname="" line="3" stmtstart="118" stmtend="284" sqlhandle="0x03000e0020c96c7ef2b3cd00739f00000100000000000000" />
<frame procname="" line="3" stmtstart="50" stmtend="146" sqlhandle="0x02000000e00b66366c680fabe2322acbad592a896dcab9cb" />
</executionStack>
<inputbuf>
WHILE (1=1)
BEGIN
INSERT INTO #t1 EXEC BookmarkLookupSelect 4
TRUNCATE TABLE #t1
END
</inputbuf>
</process>
<process id="process807b7288" taskpriority="0" logused="228" waitresource="KEY: 14:72057594038910976 (e5b3d7e750dd)" waittime="4742" ownerId="163545" transactionname="UPDATE" lasttranstarted="2011-10-05T12:29:22.587" XDES="0x82b6f950" lockMode="X" schedulerid="2" kpid="12" status="suspended" spid="58" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2011-10-05T12:29:10.607" lastbatchcompleted="2011-10-05T12:29:10.600" clientapp="Microsoft SQL Server Management Studio - Query" hostname="SQL2K8R2-IE2" hostpid="3736" loginname="SQLSKILLSDEMOS\administrator" isolationlevel="read committed (2)" xactid="163545" currentdb="14" lockTimeout="4294967295" clientoption1="673187936" clientoption2="390200">
<executionStack>
<frame procname="" line="4" stmtstart="120" stmtend="262" sqlhandle="0x03000e0059ed607ff3b3cd00739f00000100000000000000" />
<frame procname="" line="4" stmtstart="82" stmtend="138" sqlhandle="0x020000002a7093322fbd674049d04f1dc0f3257646c4514b" />
</executionStack>
<inputbuf>
SET NOCOUNT ON
WHILE (1=1)
BEGIN
EXEC BookmarkLookupUpdate 4
END
</inputbuf>
</process>
</process-list>您所要做的就是从框架中获取sqlhandle和偏移信息,然后使用sys.dm_exec_sql_text()将TSQL堆栈中的语句返回。如果您试图一次手动执行单个语句来触发死锁,则无法做到这一点,因为每个堆栈中只会有您执行的单个语句。
来自附加信息的更新:
使用带有内部队列激活的事件通知来收集附加信息是完成所需任务的最佳方法,它将比执行内存转储便宜得多。激活存储过程为事件通知执行,以异步收集数据,其中内存转储在扩展事件中的触发线程上同步执行。
https://stackoverflow.com/questions/7663850
复制相似问题