查看: 187|回复: 0

[SQLServer] Timeout occurred while waiting for latch: class 'ACCESS_METHODS_DATASET_

发表于 6 天前

前些天某个SQL Server数据库的错误日志爆出如下错误:

  1. Timeout occurred while waiting for latch: class 'ACCESS_METHODS_DATASET_PARENT', id 00000009A5670C58, type 4, Task 0x0000000B655BC508 : 188, waittime 300, <br>flags 0x1a, owning task 0x00000000170DC748. Continuing to wait.
复制代码

第一感觉是并行查询的问题,于是翻笔记查看'ACCESS_METHODS_DATABASE_PARENT'到底是什么LATCH,可以参考sys.dm_os_latch_stats的官网解释来了解一二。

ACCESS_METHODS_DATASET_PARENT -- Used to synchronize child dataset access to the parent dataset during parallel operations.

官网的解释比较含糊,于是写SQL来抓取引发问题的业务SQL,为方便起见创建为sp存储过程。

  1. USE [master]
  2. GO
  3. SET QUOTED_IDENTIFIER ON
  4. GO
  5. CREATE procedure [dbo].[sp_findtask](@parent_task_address varbinary(8))
  6. as
  7. BEGIN
  8. SELECT
  9. t.spid,t.lastwaittype,t.open_tran,t.status,t.hostname,t.program_name,t.loginame,dc.text
  10. FROM master.sys.sysprocesses t cross apply master.sys.dm_exec_sql_text(t.sql_handle) dc
  11. WHERE spid in (select distinct session_id from sys.dm_os_tasks where parent_task_address=@parent_task_address)
  12. END
  13. GO
复制代码

涉及到的几个视图:sys.sysprocesses,sys.dm_os_tasks都可以通过官网查到相关列的说明,这里不再详述。对于SQLOS任务调度涉及的概念参考:SQLOS任务调度算法

这样下次出现问题,只要能从错误日志中快速找到owning task的address(就是sys.dm_os_tasks中的parent_task_address列),就可以得到问题SQL的详细信息了。

在本例中我们先去找由于latch timeout生成的系统转储文件,然后再用windbg进行分析即可。由于SQL Server只会在第一次报出latch timeout时生成转储文件,我们可以设置838trace来使每次报错都生成dump,以便获取更准确和完整的信息。

  1. dbcc traceon(838,-1)
复制代码



回复

使用道具 举报