使用 Sqldumper.exe 工具在 SQL Server 生成转储文件

本文提供SQL Server随附的 Sqldumper.exe 工具的一般准则。 此工具用于生成不同类型的转储文件。

原始产品版本:SQL Server 2019、SQL Server 2017、SQL Server 2016、SQL Server 2014、SQL Server 2012、SQL Server 2008、SQL Server 2005
原始 KB 数: 917825

摘要

Sqldumper.exe 工具包含在 Microsoft SQL Server 中。 它生成SQL Server的内存转储文件以及用于调试的相关进程。 本文介绍如何使用 Sqldumper.exe 为 Watson 错误报告或调试任务生成转储文件。

本文还介绍了生成转储文件的其他两种方法:

  • 附加的 PowerShell 脚本 自动执行 SQLDumper.exe 命令行选项。
  • DBCC STACKDUMP Transact-SQL (T-SQL) 命令可用于在 SQL Server 中生成转储文件。

如何手动运行 Sqldumper.exe

在SQL Server最初安装该工具的文件夹的上下文下运行 Sqldumper.exe 工具。

默认情况下,Sqldumper.exe 的安装路径为 <SQLServerInstall Drive>:\Program Files\Microsoft SQL Server\90\Shared\SQLDumper.exe。 请注意,<SQLServerInstall 驱动器>是安装SQL Server的驱动器的占位符。

若要使用 Sqldumper.exe 工具生成转储文件,请执行以下步骤:

  1. 打开 <SQLServerInstall 驱动器>:\Program Files\Microsoft SQL Server\<number>\Shared 文件夹。

    在此文件夹路径中, <number> 是以下项之一的占位符:

    • 2019 SQL Server 150
    • 2017 SQL Server 140
    • 2016 SQL Server 130
    • 2014 SQL Server 120
    • 2012 SQL Server 110
    • 2008 SQL Server 100
    • 2005 SQL Server 90
  2. 确保 Dbghelp.dll 文件位于此文件夹中。

  3. 选择“ 开始>运行”,键入 cmd,然后选择“ 确定”。

  4. 在命令提示符下,键入以下命令,然后按 Enter

    cd <SQLServerInstall Drive>:\Program Files\Microsoft SQL Server\<number>\Shared
    

    注意

    在此文件夹路径中,<number> 是随SQL Server版本更改的占位符,如前所述。

  5. 若要生成特定类型的转储文件,请在命令提示符下键入相应的命令,然后按 Enter

    • 完整转储文件:

      Sqldumper.exe <ProcessID> 0 0x01100
      
    • 微型转储文件:

      Sqldumper.exe <ProcessID> 0 0x0120
      
    • 包含间接引用的内存的微型转储文件 (这是建议的选项,SQL Server在自动生成内存转储文件时也默认使用) :

      Sqldumper.exe <ProcessID> 0 0x0128
      
    • 筛选的转储文件:

      Sqldumper.exe <ProcessID> 0 0x8100
      

    注意

    <ProcessID> 是要为其生成转储文件的 Windows 应用程序的进程标识符的占位符。

如果 Sqldumper.exe 成功运行,该工具将在安装该工具的文件夹中生成转储文件。

Sqldumper.exe 生成的转储文件具有类似于 SQLDmpr<xxxx.mdmp> 的文件名模式。

在此模式中, <xxxx> 是基于同一文件夹中具有类似文件名的其他文件确定的递增数字。 如果文件夹中已有具有指定模式中文件名的文件,则可能需要比较文件的创建日期和时间,以便确定所需的文件。

如何获取 Microsoft Windows 应用程序进程标识符

若要使用 Sqldumper.exe 工具生成转储文件,必须具有要为其生成转储文件的 Windows 应用程序的进程标识符。 下面介绍如何获取进程标识符:

  1. Ctrl+Alt+Delete,然后选择“ 任务管理器”。
  2. “Windows 任务管理器 ”对话框中,选择“ 进程 ”选项卡。
  3. 在“ 视图 ”菜单上,选择“ 选择列”。
  4. “选择列 ”对话框中,选中“ PID (进程标识符) ”复选框,然后选择“ 确定”。
  5. 记下要为其生成转储文件的 Windows 应用程序的进程标识符。 对于SQL Server应用程序,请注意 Sqlservr.exe 进程的进程标识符。
  6. 关闭 任务管理器

或者,使用 SQL Server 错误日志文件获取计算机上运行的 SQL Server 应用程序的进程标识符。 SQL Server错误日志文件的一部分类似于以下示例:

2021-09-15 11:50:32.690 Server       Microsoft SQL Server 2019 (RTM-CU12) (KB5004524) - 15.0.4153.1 (X64)
    Jul 19 2021 15:37:34
    Copyright (C) 2019 Microsoft Corporation
    Enterprise Edition (64-bit) on Windows 10 Pro 10.0 <X64> (Build 19043: ) (Hypervisor)
2021-09-15 11:50:32.690 Server       UTC adjustment: -5:00
2021-09-15 11:50:32.690 Server       (c) Microsoft Corporation.
2021-09-15 11:50:32.690 Server       All rights reserved.
2021-09-15 11:50:32.690 Server       Server process ID is 7028.

后面的 Server process ID 数字是 Sqlservr.exe 进程的进程标识符。

内存转储文件的输出路径

SQLDumper.exe 主要用于为SQL Server进程生成内存转储文件,在这种情况下,需要内存转储来解决特定问题 (,例如异常、断言、无收益计划程序) 。 在这种情况下,SQL Server调用 SQLDumper.exe 以生成其进程的内存转储文件。 默认情况下,内存转储文件存储在 SQL 实例 MSSQL\LOG\ 目录中。

如何更改默认路径

例如,如果转储文件大小太大,可以通过执行以下操作来修改路径:

  1. 打开SQL Server 配置管理器
  2. “SQL Server服务”下,找到正在调查的SQL Server实例。
  3. 右键单击该条目,选择“ 属性”,然后转到“ 高级 ”选项卡。
  4. 将转储目录更改为所需路径,然后选择“ 确定”。
  5. 如果可能) 新设置生效,请重启SQL Server (。

手动使用 Sqldumper.exe 工具为任何 Windows 应用程序生成转储文件时,转储文件的大小可能与 Windows 应用程序当前使用的内存一样大。 请确保 Sqldumper.exe 写入转储文件的驱动器上有足够的磁盘空间。

在命令中指定自定义输出文件夹

可以指定希望 Sqldumper.exe 工具在其中写入转储文件的目录。 在运行 Sqldumper.exe 之前,目录必须已存在。 否则,Sqldumper.exe 将失败。 不要使用 UNC 路径作为转储文件的位置。 下面是如何指定微型转储文件的转储文件位置的示例:

  1. 选择“ 开始>运行”,键入 cmd,然后选择“ 确定”。

  2. 在命令提示符下,键入以下命令,然后按 Enter

    cd <SQLServerInstall Drive>:\Program Files\Microsoft SQL Server\<number>\Shared
    
  3. 在命令提示符下,键入以下命令,然后按 Enter

    Sqldumper.exe ProcessID 0 0x0128 0 <MdumpPath>
    

    注意

    <MdumpPath> 是希望 Sqldumper.exe 工具在其中写入转储文件的目录的占位符。 默认情况下,文件将写入当前文件夹。

如果指定要生成的完整转储文件或筛选的转储文件,Sqldumper.exe 可能需要几分钟时间才能生成转储文件。 所花费的时间取决于以下变量:

  • Sqlservr.exe 当前使用的内存量。
  • 工具写入转储文件的驱动器的速度。

在此期间,Sqldumper.exe 工具不会处理命令。 你会注意到服务器已停止响应。 此外,可能会发生群集故障转移。

权限要求

若要运行 Sqldumper.exe,必须使用以下方法之一登录到 Windows:

  • 使用计算机上管理员组成员的帐户。
  • 使用运行SQL Server服务的同一用户帐户。

若要使 Sqldumper.exe 工具通过远程桌面或终端服务成功工作,必须在控制台模式下启动远程桌面或终端服务。 例如,若要在控制台模式下启动远程桌面,请选择“ 开始>运行”,键入 mstsc /console,然后选择“ 确定”。 如果目标服务器运行 Windows 2000,则以静默方式忽略 /console 选项。 可以通过远程桌面连接到服务器,但不会使用控制台会话。

如果在运行 Sqldumper.exe 后发现当前文件夹中未生成任何转储文件,请查看该工具在命令行中生成的信息,以尝试确定失败的可能原因。 此信息也会记录在当前目录中的 Sqldumper_errorlog.log 文件中。 下面是两条可能的错误消息及其原因:

邮件 原因
“OpenProcess 失败0x57 - 参数不正确” 将无效的进程 ID 传递给 Sqldumper.exe 实用工具。
“线程 ID 的值无效 - <参数> 无效参数错误” 传递给 Sqldumper.exe 实用工具的参数无效。

如果生成了类似于以下内容之一的错误消息,则可以放心地忽略此消息:

  • “最小转储 6 期间未知的回调类型”
  • “最小转储 7 期间的未知回调类型”

转储生成的影响

如果请求用户模式进程的转储文件 (如本文中所述,与操作系统内核转储(在我们的) 范围之外)相反,此处的目标进程 (SQLServer.exe) 在将转储内容序列化到其文件目标所花费的持续时间内被冻结。

Frozen 意味着进程将无法运行任何用户请求或任何内部操作,包括任何资源轮询机制(例如 Windows 群集的 IsAlive 和“看起来处于活动状态”的实现) (请参阅 群集故障转移上的内存转储部分 ,详细了解如何处理这种情况) 。 依赖于挂钟时间的任何超时也可能因冻结而遭到破坏。

正如派生自上一个语句一样,冻结的持续时间因此是此处的关键因素,它由以下因素驱动:

  • 选择 的转储类型
  • 内存中SQL Server进程的大小,对于运行默认参数的单个活动实例,通常接近服务器的总物理 RAM
  • 用作转储目标的磁盘的性能。

此外,应规划磁盘上 转储文件的大小 ,尤其是在可能进行多个转储并且选择了大型非默认转储类型的情况下。 请务必查看 转储类型 以了解预期内容。 默认情况下,某些转储方法会在 SQL Server 实例的 \Log 文件夹中创建转储,在默认的简单配置中,该文件夹也是SQL Server的系统磁盘和数据+日志磁盘。 使磁盘饱和会对SQL Server和/或系统可用性产生严重影响。

管理对群集系统的影响

在转储生成过程中,进程会暂时暂停。 这可能会影响SQL Server服务可用性,并在故障转移群集实例和可用性组) (Always On上下文中触发资源故障转移。 不同进程的转储生成对资源的影响不同。 仔细阅读 转储生成转储类型 的影响部分。

在故障转移群集实例或可用性组 (AG) SQL Server 实例上捕获SQL Server转储时,如果转储时间过长,群集SQL Server或 AG 可能会故障转移到另一个节点。 对于使用大量 RAM 的系统,或者生成经过筛选的或完整的内存转储,这可能尤其存在问题。 若要防止故障转移,请在捕获转储文件之前使用以下设置。 在创建转储文件后,可以还原更改:

  • 对于故障转移群集实例 (FCI) :
    • 在“群集管理员”中右键单击“SQL Server资源”,在“策略”选项卡上选择“如果资源失败,请勿重启”。
    • 在“ 属性 ”选项卡上,增加 “运行状况检查超时”。 例如,将属性值设置为 180 秒或更高。 如果达到此超时,策略“ 如果资源失败,不重启 ”将忽略,并且资源仍将重启。
    • 在“ 属性 ”选项卡上,将 FailureConditionLevel 值更改为零。
  • 对于 AG,应用以下所有设置:
    • 增加会话超时,例如,所有副本的 120 秒。 在SQL Server Management Studio (SSMS) 中,右键单击要配置的副本 (replica) ,然后选择“属性”。 将 “会话超时 (秒) 字段更改为 120 秒。 有关详细信息,请参阅更改可用性副本 (SQL Server) 的 Session-Timeout 周期
    • 将所有副本的自动故障转移更改为手动故障转移。 在 SSMS 中,右键单击“副本 (replica) ”,选择“属性”,并将所有副本的自动故障转移更改为“属性”选项卡上的手动故障转移。有关详细信息,请参阅更改可用性副本的故障转移模式 (SQL Server)
    • ) 将 LeaseTimeout 增加到 60,000 毫秒 (60 秒,) 将 HealthCheckTimeout 更改为 90,000 毫秒 (90 秒。 在 “群集管理员”中,右键单击“AG 资源”,选择“ 属性”,然后切换到“ 属性 ”选项卡以修改这两个设置。 有关详细信息,请参阅 配置 HealthCheckTimeout 属性设置

产品改进,以减少对SQL Server的影响

为最新版本的 SQL Server 添加了四个主要改进,以减小转储文件的大小和/或生成内存转储的时间:

位图筛选机制

SQL Server分配一个位图,用于跟踪要从筛选转储中排除的内存页。 Sqldumper.exe 读取位图并筛选出页面,而无需读取任何其他内存管理器元数据。 当位图被分别启用或禁用时,你将在SQL Server错误日志中看到以下消息:

Page exclusion bitmap is enabled.Page exclusion bitmap is disabled.

  • SQL Server 2016

    从 SQL Server 2016 SP2 CU13 开始,位图筛选默认启用。

  • SQL Server 2017

    • 这在 RTM 到 CU15 中不可用。
    • 在 SQL Server 2017 CU16 中,可以通过 T8089 启用位图筛选,并通过关闭 T8089 来禁用它。
    • 从 SQL Server 2017 CU20 开始,位图筛选默认启用。 跟踪标志 T8089 将不再应用,如果启用,将被忽略。 可以通过 T8095 禁用位图筛选。
  • SQL Server 2019

    在 SQL Server 2019 RTM 中默认启用此功能。 可以通过 T8095 禁用它。

消除同一问题的重复转储

消除针对同一问题的重复内存转储。 使用堆栈签名,SQL 引擎跟踪是否已发生异常,并且不会生成新的内存转储(如果已有)。 这适用于访问冲突、堆栈溢出、断言和索引损坏异常。 这大大减少了内存转储使用的磁盘空间量,并且不会暂时冻结进程以生成转储。 这是在 2019 SQL Server 中添加的。

错误日志中的缩短输出

从单个内存转储在 SQL Server 错误日志中生成的内容不仅可能令人费力,而且由于将所有此信息序列化为错误日志中的文本格式所需的时间,它也会减慢生成内存转储的过程。 在 2019 SQL Server,转储生成时存储在错误日志中的内容已大大减少,如下所示:

DateTimespidS pid    **Dump thread - spid = 0, EC = 0x0000015C7169BF40
DateTimespidS pid    *
DateTimespidS pid    *User initiated stack dump. This is not a server exception dump.
DateTimespidS pid    *
DateTimespidS pid    Stack Signature for the dump is 0x00000000788399E5
DateTimespidS pid    External dump process return code 0x20000001.
External dump process returned no errors.

例如,以前,SQL Server会在用户触发手动转储时打印每个会话或线程的信息。

内存转储的并行压缩

为了更快地生成转储并使其更小,SQL Server 2022 CU8SQL Server 2019 CU23 中引入了压缩内存转储功能。 激活后,Sqldumper.exe 创建多个线程来同时读取进程的内存,对其进行压缩,然后将其保存到转储文件。 这种多线程并行压缩在与完整转储和筛选转储一起使用时,可以减少文件大小并加快转储过程。

可以打开跟踪标志 2610 以启用压缩内存转储:

DBCC TRACEON (2610,-1)
GO
DBCC STACKDUMP with FILTERED_DUMP
GO
DBCC TRACEOFF (2610,-1)

或者,可以将 作为启动参数添加到 -T2610 SQL Server 实例,以便它始终创建压缩的内存转储。

如果手动运行 Sqldumper.exe,则可以使用 -zdmp 参数捕获压缩的内存转储。 例如:

Sqldumper.exe <ProcessID> 0 0x8100 0 d:\temp -zdmp

还可以通过使用 -cpu:X 参数限制 Sqldumper.exe 可用于创建压缩转储的核心数,其中 X 是 CPU 数。 此参数仅在从命令行手动运行 Sqldumper.exe 时才可用:

Sqldumper.exe <ProcessID> 0 0x8100 0 d:\temp -zdmp -cpu:8

阻止或延迟创建内存转储的因素

已知以下因素会导致延迟或阻止创建内存转储。

  • 写入内存转储的 IO 路径性能不佳。 在这种情况下,调查和解决磁盘 I/O 性能是下一个逻辑步骤。
  • 防病毒或其他监视软件正在干扰 SQLDumper.exe。 在某些情况下,第三方软件绕行 ReadProcessMemory 函数。 这可以显著增加转储持续时间。 若要解决其中大多数问题,请禁用干扰软件或将 SQLDumper.exe 添加到排除列表。

转储类型

以下方法可用于生成三种不同类型的转储: 微型转储完整转储筛选转储

具有引用内存的小型转储

这种类型的内存转储是进程 (“线程堆栈”) 的所有活动线程的快照,以及线程堆栈引用的内存的有限提取以及某些其他关键进程或线程数据。 它们的大小通常只有几兆字节,并且快速生成 (,) 不到一秒到几秒。 更大的服务器系统 (数百个 CPU 间接驱动SQL Server进程中的大量线程,) 很少会超过 20-30 MB:小型转储的大小不会随SQL Server进程的大小而增长。 此转储类型是SQL Server在异常、计划程序问题、闩锁问题、数据库损坏、断言时自动生成内存转储时使用的默认类型。

注意

作为内置检测的一部分,SQL Server在某些特定情况下将生成自动“诊断微型转储”。 因此,此操作被视为足够安全,SQL Server可以在需要时自动触发它。

完整转储

内存完全转储是活动目标进程空间的完整副本。 因此,这将包括所有线程状态、所有进程分配的内存以及所有已加载的模块。 因此,完整转储的大小与SQL Server过程大致相同,这反过来可能几乎与总系统 RAM 一样大。 在专用于单个SQL Server实例的大型服务器上,这可能意味着文件数百 GB 或更多。 不用说,这样的文件需要很长时间才能生成,因此会诱发长期冻结。 转储的文件目标的磁盘性能将显著影响冻结时间。 这种类型的转储目前很少用于SQL Server,如以下说明中所述。

筛选的转储

随着运行 SQL Server 的典型服务器的 RAM 大小稳步增加,完整转储变得更加笨重。 因此,将实现筛选的转储。 筛选的转储是完整转储的子集,其中大量SQL Server内存被动态排除,不会写入磁盘。 通常,排除的内存不会为故障排除带来任何附加价值。 示例包括数据/索引页和某些内部缓存,例如 Hekaton 数据页和日志池内存。 此筛选的转储产生的文件比完整转储更小,但转储仍保留其几乎所有有用性。 在微型转储不足的绝大多数情况下,筛选的转储已取代完整转储作为首选选项。 与完整转储相比,大小减小可能会有所不同,但它仍然是一个相当大的文件,通常为SQL Server进程大小的 30-60%。 因此,最好计划一个可能的大小,以完全倾倒作为最差的选择,这留下了良好的安全边际。 在每种情况下,筛选转储的生成速度不一定比完全转储快:与避免的 IO 数相关的增益是否超过实现筛选逻辑所需的时间, (磁盘速度和 CPU/RAM 速度会影响) 。

可以使用以下查询来大致估计筛选的转储大小。 尽管预期大多数数据页或索引页都排除在转储之外,但不会省略专门锁定和正在修改的数据页或索引页。

SELECT SUM(pages_kb)
FROM sys.dm_os_memory_clerks
WHERE type != 'MEMORYCLERK_SQLBUFFERPOOL'

由于可以使用 Sqldumper.exe 根据需要为任何 Microsoft Windows 应用程序生成转储文件,因此可以考虑使用筛选的转储选项。 但是,筛选的转储文件仅在SQL Server上下文中适用且有意义。 你仍然可以成功生成微型转储、完整转储文件或非SQL Server应用程序。

SQL Server进程在内部调用 Sqldumper.exe 工具,以在进程遇到任何异常时生成转储文件。 SQL Server将参数传递给 Sqldumper.exe。 可以使用跟踪标志更改在发生异常或断言时默认SQL Server传递给工具的参数。 这些跟踪标志的范围从 2540 到 2559。 可以使用其中一个跟踪标志来更改默认转储类型 SQLDumper.exe 生成 (默认值是具有引用内存) 的微型转储。 例如:

  • 跟踪标志 2551:生成经过筛选的内存转储。
  • 跟踪标志 2544:生成完整内存转储。
  • 跟踪标志 8026:SQL Server会在生成转储一次后清除转储触发器。

如果两个或更多跟踪标志处于活动状态,则会使用指示最大内存转储的选项。 例如,如果使用跟踪标志 2551 和 2544,SQL Server将创建完整的内存转储。

在群集故障转移时生成内存转储

在群集故障转移方案中,SQL Server资源 DLL 可以在故障转移之前获取转储文件,以帮助进行故障排除。 当SQL Server资源 DLL 确定SQL Server资源已失败时,SQL Server资源 DLL 使用 Sqldumper.exe 实用工具获取SQL Server进程的转储文件。 若要确保 Sqldumper.exe 工具成功生成转储文件,必须将以下三个属性设置为先决条件:

  • SqlDumperDumpTimeOut

    用户指定的超时。资源 DLL 等待转储文件完成,资源 DLL 停止SQL Server服务。

  • SqlDumperDumpPath

    Sqldumper.exe 工具生成转储文件的位置。

  • SqlDumperDumpFlags

    Sqldumper.exe 使用的标志。

如果未设置任一属性,Sqldumper.exe 无法生成转储文件。 每当资源联机时,都会在事件日志和群集日志中记录警告消息。

SQL Server 2012 及更高版本的 SQLDumper 的群集配置

可以使用 ALTER SERVER CONFIGURATION (T-SQL) 命令修改这些属性。 例如:

ALTER SERVER CONFIGURATION SET FAILOVER CLUSTER PROPERTY SqlDumperDumpTimeOut = 0;
ALTER SERVER CONFIGURATION SET FAILOVER CLUSTER PROPERTY SqlDumperDumpPath = 'C:\temp\';
ALTER SERVER CONFIGURATION SET FAILOVER CLUSTER PROPERTY SqlDumperDumpFlags = 296;

或者,可以使用 PowerShell 脚本。 例如,对于命名实例SQL2017AG:

Get-ClusterResource -Name "SQL Server (SQL2017AG)" | Set-ClusterParameter -Name "SqlDumperDumpPath" -Value "C:\temp"
Get-ClusterResource -Name "SQL Server (SQL2017AG)" | Set-ClusterParameter -Name "SqlDumperDumpFlags" -Value 296
Get-ClusterResource -Name "SQL Server (SQL2017AG)" | Set-ClusterParameter -Name "SqlDumperDumpTimeOut" -Value 0

若要验证是否已应用设置,可以运行以下 PowerShell 命令:

Get-ClusterResource -Name "SQL Server (SQL2017AG)" | Get-ClusterParameter

SQL Server 2008/2008 R2 或 Windows 2012 及更早版本上的 SQLDumper 的群集配置

若要使用群集 资源 命令设置群集故障转移的 Sqldumper.exe 实用工具属性,请执行以下步骤:

  1. 选择“ 开始>运行”,键入 cmd,然后选择“ 确定”。
  2. 对于每个属性,请在命令提示符下键入相应的命令,然后按 Enter
    • SqlDumperDumpFlags 属性

      若要为特定类型的转储文件设置 SqlDumperDumpFlags 属性,请在命令提示符处键入相应的命令,然后按 Enter

      • 所有线程完全转储文件

        • 默认实例

          cluster resource "SQL Server" /priv SqlDumperDumpFlags = 0x01100
          
        • 命名实例

          cluster resource "SQL Server (INSTANCE1)" /priv SqlDumperDumpFlags = 0x01100
          
      • 所有线程微型转储文件

        • 默认实例

          cluster resource "SQL Server" /priv SqlDumperDumpFlags = 0x0120
          
        • 命名实例

          cluster resource "SQL Server (INSTANCE1)" /priv SqlDumperDumpFlags = 0x0120
          
      • 已筛选所有线程转储文件

        • 默认实例

          cluster resource "SQL Server" /priv SqlDumperDumpFlags = 0x8100
          
        • 命名实例

          cluster resource "SQL Server  (INSTANCE1)" /priv SqlDumperDumpFlags = 0x8100
          
    • SqlDumperDumpPath 属性

      cluster resource "SQL Server" /priv SqlDumperDumpPath = <DirectoryPath>
      

      注意

      <DirectoryPath> 是将生成转储文件的目录的占位符,应用引号 (“) 指定。

    • SqlDumperDumpTimeOut 属性

      cluster resource "SQL Server" /priv SqlDumperDumpTimeOut = <Timeout>
      

      注意

      <Timeout> 是) 毫秒 (超时的占位符。

该工具生成SQL Server进程的转储文件所需的时间取决于计算机配置。 对于具有大量记忆的计算机,时间可能很大。 若要获取该过程所花费时间的估计值,请使用 Sqldumper.exe 工具手动生成转储文件。 属性的有效值为 SqlDumperDumpTimeOut10,000 毫秒MAXDWORD。MAXDWORD 表示 DWORD 数据类型 (4294967295) 范围内的最大值。

若要验证是否已启用设置,可以运行以下命令:

cluster resource "SQL Server" /priv

删除群集故障转移的 Sqldumper.exe 属性

若要删除群集故障转移的 Sqldumper.exe 工具属性,请执行以下步骤:

  1. 选择“ 开始>运行”,键入 cmd,然后选择“ 确定”。
  2. 对于特定属性,请在命令提示符下键入相应的命令,然后按 Enter
    • SqlDumperDumpFlags 属性

      • 默认实例

          cluster resource "SQL Server" /priv:SqlDumperDumpFlags /usedefault
        
      • 命名实例

          cluster resource "SQL Server (INSTANCE1)" /priv:SqlDumperDumpFlags /usedefault
        
    • SqlDumperDumpPath 属性

      • 默认实例

        cluster resource "SQL Server" /priv:SqlDumperDumpPath /usedefault
        
      • 命名实例

        cluster resource "SQL Server (INSTANCE1)" /priv:SqlDumperDumpPath /usedefault
        
    • SqlDumperDumpTimeOut 属性

      • 默认实例

        cluster resource "SQL Server" /priv:SqlDumperDumpTimeOut /usedefault
        
      • 命名实例

        cluster resource "SQL Server (INSTANCE1)" /priv:SqlDumperDumpTimeOut /usedefault
        

如何使用 DBCC STACKDUMP

命令DBCC STACKDUMP可帮助在 SQL Server 实例安装的 LOG 目录中创建内存转储。 默认情况下,该命令将创建包含所有线程的小型转储,该线程的大小有限,足以反映SQL Server进程的状态。 在 SQL Server 客户端中运行以下命令:

DBCC STACKDUMP

有关 2019 SQL Server 中的 DBCC STACKDUMP 扩展功能,请参阅 2019 SQL Server 中引入的扩展 DBCC STACKDUMP 功能

若要使此方法能够创建筛选的转储,请使用以下命令启用跟踪标志 2551:

DBCC TRACEON(2551, -1)
GO
DBCC STACKDUMP

若要创建完整转储,请使用跟踪标志 2544。

获取转储文件后,应使用 命令DBCC TRACEOFF (<TraceNumber>, -1);禁用跟踪标志,以避免无意中将所有进一步SQL Server自诊断最小转储升级到更大的转储。 在 命令中, <TraceNumber> 是以前启用的跟踪标志,例如 2551 或 2544。 例如:

DBCC TRACEOFF(2551, -1)

如果不确定哪个跟踪标志保持活动状态,请运行以下命令:

DBCC TRACESTATUS(-1)

空结果集指示没有跟踪标志处于活动状态。 相反,如果 2551 仍然处于活动状态,你将看到:

TraceFlag 状态 全球 会话
2551 1 1 0

注意

traceflag启用的 DBCC TRACEON 在服务重启后重置 (删除) 。

SQL Server 2019 中引入的扩展 DBCC STACKDUMP 功能

从 SQL Server 2019 CU2 开始,DBCC STACKDUMP该命令已扩展为支持生成不同类型的转储:微型转储、筛选转储和完全转储。 此命令无需使用跟踪标志。 它还允许限制使用内存转储生成的其他文本文件中的文本输出。 这样做可能会在 SQLDumper.exe 生成内存转储所需的时间内提供明显的性能提升。

DBCC STACKDUMP WITH MINI_DUMP | FILTERED_DUMP | FULL_DUMP [, TEXT_DUMP = LIMITED | DETAILED]

TEXT_DUMP = LIMITED是默认选项。 如果要在 SQLDump000X.txt 文件中接收详细输出,可以使用 TEXT_DUMP = DETAILED

若要在 .txt 文件中生成输出有限的筛选转储,请运行以下命令:

DBCC STACKDUMP WITH FILTERED_DUMP , TEXT_DUMP = LIMITED

如何使用 PowerShell 脚本通过 SQLDumper 生成转储文件

  • 将以下代码另存为 PS1 文件,例如 SQLDumpHelper.ps1

    代码详细信息

    $isInt = $false
    $isIntValDcnt = $false
    $isIntValDelay = $false
    $SqlPidInt = 0
    $NumFoler = ""
    $OneThruFour = ""
    $SqlDumpTypeSelection = ""
    $SSASDumpTypeSelection = ""
    $SSISDumpTypeSelection = ""
    $SQLNumfolder = 0
    $SQLDumperDir = ""
    $OutputFolder = ""
    $DumpType = "0x0120"
    $ValidPid
    $SharedFolderFound = $false
    $YesNo = ""
    $ProductNumber = ""
    $ProductStr = ""
    
    Write-Host ""
    Write-Host "`******************************************************************"
    Write-Host "This script helps you generate one or more SQL Server memory dumps"
    Write-Host "It presents you with choices on:`
                -target SQL Server process (if more than one)
                -type of memory dump
                -count and time interval (if multiple memory dumps)
    You can interrupt this script using CTRL+C"
    Write-Host "***********************************************************************"
    
    # check for administrator rights
    # debugging tools like SQLDumper.exe require Admin privileges to generate a memory dump
    
    if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
    {
        Write-Warning "Administrator rights are required to generate a memory dump!`nPlease re-run this script as an Administrator!"
        return
    }
    
    # what product would you like to generate a memory dump
    while ($true)
    {
        Write-Host "Which product would you like to generate a memory dump of?" -ForegroundColor Yellow
        Write-Host "1) SQL Server"
        Write-Host "2) SSAS (Analysis Services)"
        Write-Host "3) SSIS (Integration Services)"
        Write-Host "4) SSRS (Reporting Services)"
        Write-Host "5) SQL Server Agent"
        Write-Host ""
        $ProductNumber = Read-Host "Enter 1-5>"
    
        if ($ProductNumber -in 1,2,3,4,5)
        {
            break
        }
        Write-Host "`nPlease enter a valid number from list above!`n"
        Start-Sleep -Milliseconds 300
    }
    
    if ($ProductNumber -eq "1")
    {
        $SqlTaskList = Tasklist /SVC /FI "imagename eq sqlservr*" /FO CSV | ConvertFrom-Csv
        $ProductStr = "SQL Server"
    }
    elseif ($ProductNumber -eq "2")
    {
        $SqlTaskList = Tasklist /SVC /FI "imagename eq msmdsrv*" /FO CSV | ConvertFrom-Csv
        $ProductStr = "SSAS (Analysis Services)"
    }
    elseif ($ProductNumber -eq "3")
    {
        $SqlTaskList = Tasklist /SVC /FI "imagename eq msdtssrvr*" /FO CSV | ConvertFrom-Csv
        $ProductStr = "SSIS (Integration Services)"
    }
    elseif ($ProductNumber -eq "4")
    {
        $SqlTaskList = Tasklist /SVC /FI "imagename eq reportingservicesservice*" /FO CSV | ConvertFrom-Csv
        $ProductStr = "SSRS (Reporting Services)"
    }
    elseif ($ProductNumber -eq "5")
    {
        $SqlTaskList = Tasklist /SVC /FI "imagename eq sqlagent*" /FO CSV | ConvertFrom-Csv
        $ProductStr = "SQL Server Agent"
    }
    
    if ($SqlTaskList.Count -eq 0)
    {
        Write-Host "There are currently no running instances of $ProductStr. Exiting..." -ForegroundColor Green
        break
    }
    
    # if multiple SQL Server instances, get the user to input PID for desired SQL Server
    if ($SqlTaskList.Count -gt 1)
    {
        Write-Host "More than one $ProductStr instance found."
    
        $SqlTaskList | Select-Object PID, "Image name", Services | Out-Host
    
        # check input and make sure it is a valid integer
        while ($true)
        {
            Write-Host "Please enter the PID for the desired SQL service from list above" -ForegroundColor Yellow
            $SqlPidStr = Read-Host ">"
    
            if( $SqlPidStr -in $SqlTaskList.PID)
            {
                $SqlPidInt = [int]$SqlPidStr
                break
            }
        }
    
        Write-Host "Using PID=$SqlPidInt for generating a $ProductStr memory dump" -ForegroundColor Green
        Write-Host ""
    
    }
    else # if only one SQL Server/SSAS on the box, go here
    {
        $SqlTaskList | Select-Object PID, "Image name", Services | Out-Host
        $SqlPidInt = [convert]::ToInt32($SqlTaskList.PID)
    
        Write-Host "Using PID=", $SqlPidInt, " for generating a $ProductStr memory dump" -ForegroundColor Green
        Write-Host ""
    }
    
    # dump type
    
    if ($ProductNumber -eq "1")  # SQL Server memory dump
    {
        # ask what type of SQL Server memory dump
        while($true)
        {
            Write-Host "Which type of memory dump would you like to generate?" -ForegroundColor Yellow
            Write-Host "1) Mini-dump"
            Write-Host "2) Mini-dump with referenced memory " -NoNewLine; Write-Host "(Recommended)"
            Write-Host "3) Filtered dump " -NoNewline; Write-Host "(Not Recommended)" -ForegroundColor Red
            Write-Host "4) Full dump  " -NoNewline; Write-Host "(Do Not Use on Production systems!)" -ForegroundColor Red
            Write-Host ""
            $SqlDumpTypeSelection = Read-Host "Enter 1-4>"
    
            if ($SqlDumpTypeSelection -in 1,2,3,4)
            {
                break
            }
            Write-Host "`nPlease enter a valid type of memory dump!`n"
            Start-Sleep -Milliseconds 300
        }
    
        Write-Host ""
    
        switch ($SqlDumpTypeSelection)
        {
            "1" { $DumpType="0x0120"; break }
            "2" { $DumpType="0x0128"; break }
            "3" { $DumpType="0x8100"; break }
            "4" { $DumpType="0x01100"; break }
            default { "0x0120"; break }
        }
    }
    elseif ($ProductNumber -eq "2")  # SSAS dump
    {
        # ask what type of SSAS memory dump
        while($true)
        {
            Write-Host "Which type of memory dump would you like to generate?" -ForegroundColor Yellow
            Write-Host "1) Mini-dump"
            Write-Host "2) Full dump  " -NoNewline; Write-Host "(Do Not Use on Production systems!)" -ForegroundColor Red
            Write-Host ""
            $SSASDumpTypeSelection = Read-Host "Enter 1-2>"
    
            if ($SSASDumpTypeSelection -in 1,2)
            {
                break
            }
            Write-Host "`nPlease enter a valid type of memory dump!`n"
            Start-Sleep -Milliseconds 300
        }
    
        Write-Host ""
    
        switch ($SSASDumpTypeSelection)
        {
            "1" {$DumpType="0x0";break}
            "2" {$DumpType="0x34";break}
            default {"0x0120"; break}
        }
    }
    elseif ($ProductNumber -in 3,4,5)  # SSIS/SSRS/SQL Agent dump
    {
        # ask what type of SSIS memory dump
        while($true)
        {
            Write-Host "Which type of memory dump would you like to generate?" -ForegroundColor Yellow
            Write-Host "1) Mini-dump"
            Write-Host "2) Full dump"
            Write-Host ""
            $SSISDumpTypeSelection = Read-Host "Enter 1-2>"
    
            if ($SSISDumpTypeSelection -in 1,2)
            {
                break
            }
            Write-Host "`nPlease enter a valid type of memory dump!`n"
            Start-Sleep -Milliseconds 300
        }
    
        Write-Host ""
    
        switch ($SSISDumpTypeSelection)
        {
            "1" { $DumpType="0x0"; break }
            "2" { $DumpType="0x34"; break }
            default { "0x0120"; break }
        }
    }
    
    # Sqldumper.exe PID 0 0x0128 0 c:\temp
    # output folder
    while($OutputFolder -eq "" -or !(Test-Path -Path $OutputFolder))
    {
        Write-Host ""
        Write-Host "Where would your like the memory dump stored (output folder)?" -ForegroundColor Yellow
        $OutputFolder = Read-Host "Enter an output folder with no quotes (e.g. C:\MyTempFolder or C:\My Folder)"
        if ($OutputFolder -eq "" -or !(Test-Path -Path $OutputFolder))
        {
            Write-Host "'" $OutputFolder "' is not a valid folder. Please, enter a valid folder location" -ForegroundColor Yellow
        }
    }
    
    # strip the last character of the Output folder if it is a backslash "\". Else Sqldumper.exe will fail
    if ($OutputFolder.Substring($OutputFolder.Length-1) -eq "\")
    {
        $OutputFolder = $OutputFolder.Substring(0, $OutputFolder.Length-1)
        Write-Host "Stripped the last '\' from output folder name. Now folder name is  $OutputFolder"
    }
    
    # find the highest version of SQLDumper.exe on the machine
    $NumFolder = dir "C:\Program Files\Microsoft SQL Server\1*" | Select-Object @{name = "DirNameInt"; expression={[int]($_.Name)}}, Name, Mode | Where-Object Mode -Match "da*" | Sort-Object DirNameInt -Descending
    
    for( $j=0; $j -lt $NumFolder.Count; $j++)
    {
        $SQLNumfolder = $NumFolder.DirNameInt[$j]   # start with the highest value from sorted folder names - latest version of dumper
        $SQLDumperDir = "C:\Program Files\Microsoft SQL Server\" + $SQLNumfolder.ToString() + "\Shared\"
        $TestPathDumperDir = $SQLDumperDir + "sqldumper.exe"
    
        if (Test-Path -Path $SQLDumperDir)
        {
            break
        }
    }
    
    # build the SQLDumper.exe command e.g. (Sqldumper.exe 1096 0 0x0128 0 c:\temp\)
    
    $cmd = "$([char]34)"+$SQLDumperDir + "sqldumper.exe$([char]34)"
    $arglist = $SqlPidInt.ToString() + " 0 " +$DumpType +" 0 $([char]34)" + $OutputFolder + "$([char]34)"
    Write-Host "Command for dump generation: ", $cmd, $arglist -ForegroundColor Green
    
    # do-we-want-multiple-dumps section
    Write-Host ""
    Write-Host "This utility can generate multiple memory dumps, at a certain interval"
    Write-Host "Would you like to collect multiple memory dumps (2 or more)?" -ForegroundColor Yellow
    
    # validate Y/N input
    while ($true)
    {
        $YesNo = Read-Host "Enter Y or N>"
    
        if ($YesNo -in "y","n")
        {
            break
        }
        Write-Host "Not a valid 'Y' or 'N' response"
    }
    
    # get input on how many dumps and at what interval
    if ($YesNo -eq "y")
    {
        [int]$DumpCountInt=0
        while (1 -ge $DumpCountInt)
        {
            Write-Host "How many dumps would you like to generate for this $ProductStr ?" -ForegroundColor Yellow
            $DumpCountStr = Read-Host ">"
    
            if ([int]::TryParse($DumpCountStr, [ref]$DumpCountInt) -and $DumpCountInt -gt 1)
            {
                break
            }
            Write-Host "Please enter a number greater than one." -ForegroundColor Red
        }
    
        [int]$DelayIntervalInt=0
        while ($true)
        {
            Write-Host "How frequently (in seconds) would you like to generate the memory dumps?" -ForegroundColor Yellow
            $DelayIntervalStr = Read-Host ">"
    
            if ([int]::TryParse($DelayIntervalStr, [ref]$DelayIntervalInt) -and $DelayIntervalInt -gt 0)
            {
                break
            }
            Write-Host "Please enter a number greater than zero." -ForegroundColor Red
        }
    
        Write-Host "Generating $DumpCountInt memory dumps at a $DelayIntervalStr-second interval" -ForegroundColor Green
    
        # loop to generate multiple dumps
        $cntr = 0
        while ($true)
        {
            Start-Process -FilePath $cmd -Wait -Verb runAs -ArgumentList $arglist
            $cntr++
    
            Write-Host "Generated $cntr memory dump(s)." -ForegroundColor Green
    
            if ($cntr -ge $DumpCountInt)
            {
                break
            }
            Start-Sleep -S $DelayIntervalInt
        }
    
        # print what files exist in the output folder
        Write-Host ""
        Write-Host "Here are all the memory dumps in the output folder '$OutputFolder'" -ForegroundColor Green
        $MemoryDumps = $OutputFolder + "\SQLDmpr*"
        Get-ChildItem -Path $MemoryDumps
    
        Write-Host ""
        Write-Host "Process complete"
    }
    else # produce just a single dump
    {
        Start-Process -FilePath $cmd -Wait -Verb runAs -ArgumentList $arglist
    
        # print what files exist in the output folder
        Write-Host ""
        Write-Host "Here are all the memory dumps in the output folder '$OutputFolder'" -ForegroundColor Green
        $MemoryDumps = $OutputFolder + "\SQLDmpr*"
        Get-ChildItem -Path $MemoryDumps
    
        Write-Host ""
        Write-Host "Process complete"
    }
    
    Write-Host "For errors and completion status, review SQLDUMPER_ERRORLOG.log created by SQLDumper.exe in the output folder '$OutputFolder'.`nOr if SQLDumper.exe failed, look in the folder from which you are running this script."
    
  • 使用以下命令,以管理员身份从命令提示符运行它:

    Powershell.exe -File SQLDumpHelper.ps1
    
  • 或者从 Windows PowerShell 控制台运行它,并使用以下命令以管理员身份运行:

    .\SQLDumpHelper.ps1
    

注意

如果从未在系统上运行 PowerShell 脚本,可能会收到以下错误消息:

“无法加载文件 ...SQLDumpHelper.ps1,因为在此系统上禁用运行脚本。”

若要启用运行命令的功能,请执行以下步骤:

  1. 使用“以管理员身份运行”选项启动Windows PowerShell控制台。 只有计算机上的管理员组的成员才能更改执行策略。

  2. 通过以下命令启用运行未签名脚本:

    Set-ExecutionPolicy RemoteSigned
    

    注意

    这样,就可以运行在本地计算机上创建的未签名脚本以及从 Internet 签名的脚本。