在接下来的几个专题中,我将会介绍一些工具,Microsoft 产品支持服务使用这些工具来排除故障并解决与 SQL Server 相关的复杂问题。这些工具最近已发布到网上,客户可以在支持事件环境以外使用它们。本月的专题主要是介绍 PSSDiag,它是一个用于 SQL Server 的诊断信息收集工具。在以后的专题中,我将会论述关于 Read80Trace 和 OStress 的内容,另外可能还会谈及其他一两个方面的内容。
PSSDiagPSSDiag 供 Microsoft 产品支持服务 (PSS) 用来收集诊断数据。它有两种主要类型:内部版本,通常发送给支持事件环境内的客户;外部版本,最近可从 Microsoft 网站上下载。两种版本都使用相同的代码生成,但是在外部功能、默认选项、预期使用等方面稍有不同。因为您可以免费下载外部版本,所以在本专题中我将主要论述外部版本的有关内容。
PSSDiag 由两个主要组件组成:配置应用程序 DiagConfig.exe 和收集服务程序 PSSDiag.exe。DiagConfig.exe 是一个托管代码应用程序,它用于创建配置文件或注册表项;PSSDiag.exe 是一个本机代码服务应用程序,它将读取 DiagConfig.exe 创建的内容来确定要收集的诊断信息并确定从哪个(些)计算机中收集信息。PSSDiag.exe 可收集所要求的信息并将其记录到指定的输出文件夹中,在此进程中可以将信息进行压缩(可选操作)。此输出结果随后可以上传给 Microsoft 或者由客户用于监控他们的服务器运行状况并排除服务器故障。
尽管此工具实际上可以被配置为收集各种类型的计算机中的诊断信息,但是默认情况下它被配置为收集与 SQL Server 相关的诊断信息。要从其他类型的计算机中收集诊断信息只需为收集程序提供一个特殊的启动参数即可,我将会在下一节中进行论述。
DiagConfig
DiagConfig 开始时会提示输入目标计算机和诊断信息收集服务程序,如图 1 所示。
图 1:DiagConfig 连接对话框
目标计算机就是您要收集其诊断信息的计算机。它可以不是本地计算机,但必须安装了 PSSDiag 收集服务程序(通常会自动安装此程序;有关如何手动安装此程序的说明,请参阅安装或卸载收集服务程序一节)。
“诊断信息收集服务程序”项用于指定目标计算机上的收集服务程序名称。其默认设置为 PSSDIAG,但可以修改此设置(您可以在同一计算机上安装多个收集服务程序实例)。设置多个收集服务程序实例会非常有用,例如,可以设置一种连续运行的收集程序用于收集影响甚微的诊断信息;设置另一种专门在解决特定问题时运行的收集程序用于收集更具破坏性的诊断信息。您在此处指定的名称必须已在目标计算机上注册为收集服务程序,除非您连接的是本地计算机上的默认实例。同样,请参阅安装或卸载收集服务程序一节以获得详细信息。
由于具有从远程计算机上控制和配置收集服务程序的功能,因此您可以在单台计算机上对跨企业的多个服务器中的诊断信息收集进行集中管理。您甚至还可以在 DiagConfig 命令行指定目标计算机名称和收集服务程序名称(这些参数与位置相关,且不需要命令行开关;目标计算机名称在前,目标服务程序名称在后),从而越过“目标计算机”对话框,自动运行连接进程。这样使您可以在 Windows 资源管理器中创建到达目标计算机的快捷方式,并且仅通过单击相应的快捷方式就可以自动连接到这些计算机。
在提供了所需的连接信息后,DiagConfig 就会显示出主配置屏幕。如图 2 所示:
图 2:DiagConfig 主配置屏幕
主配置界面分为四个部分:连接信息、计算机范围内的诊断信息、特定于实例的诊断信息以及说明/输出。以下将分别对每个部分进行说明。
连接信息
Connection Info(连接信息)部分使您可以进一步详细说明指定给计算机上特定的 SQL Server 实例的目标计算机。此信息默认为一个星号 (*),它将指示收集服务程序清点安装在目标计算机上的 SQL Server 实例,并同时从这些实例中收集信息。如果需要,您可以将此信息更改为目标计算机上的特定实例。还可以指定连接到目标计算机时使用的验证类型和使用 SQL Server 验证时的可选用户名。
计算机范围内的诊断信息
顾名思义,“计算机范围内的诊断信息”部分使您可以对计算机范围内包括的诊断信息收集进行配置,这些信息并非特定的 SQL Server 实例特有的。这些信息包括目标计算机的事件日志(系统、应用程序和安全)以及 Perfmon/Sysmon 日志。
您可以控制是否在收集程序启动和/或关闭时收集事件日志。而对于 Perfmon 日志,您可以配置收集的对象和计数器(树视图中的带有阴影的计数器对象表示它下面的部分而非全部 Perfmon 计数器被选中)、翻转文件大小以及采样间隔。此处显示的计数器列表实际是从一个 XML 文档中加载的(请参阅 PerfmonTemplates 子文件夹),您可以自定义此列表以满足需要。
关于 Perfmon 计数器,在此需要说明一点,即 PSSDiag 支持实例计数器的概念。这些计数器就是您要为计算机上的所有 SQL Server 实例收集的 Perfmon 计数器。这些计数器的文本中将会包含一个 %s 标记。此标记将由收集服务程序填充,并替换为目标计算机上的每个 SQL Server 实例的名称。它将使收集程序的操作就像您为各个 SQL Server 实例要求了相同的计数器一样。
另外要说明的一点是,PSSDiag 支持在 Perfmon 对象实例中使用通配符。这些计数器中包含星号 (*),用来代替计数器文本中的特定对象实例。这使您可以执行诸如为目标框中的所有进程收集给定的计数器或计数器集合等操作,而无需预先了解这些进程的内容。
特定于实例的诊断信息
“特定于实例的诊断信息”就是关于特定 SQL Server 实例的诊断信息。这些信息包括 SQLDIAG 报告、阻断故障排除输出以及事件探查器跟踪。
SQLDIAG 是 SQL Server 附带的一个实用程序(请查看 Binn 文件夹),它可以拍摄特定于 SQL Server 实例的不同系统配置和故障排除信息(例如错误日志、sp_configure 值等)的快照。与事件日志相同,PSSDiag 可以被配置为在收集程序启动和/或关闭时收集 SQLDIAG 报告。
PSSDiag 还可以自动运行,并循环进行 Microsoft 用于分析阻断问题的标准存储过程(请参阅 How to monitor SQL Server 2000 blocking)。您可以配置传入此过程的参数和应用的采样间隔。
在 DiagConfig 主屏幕中可以配置的最后一种特定于实例的诊断信息为事件探查器跟踪。它显示出了 SQL 事件探查器界面的简化版本,使您可以选择要收集的跟踪事件(带有阴影的跟踪事件表示它下面的部分而非全部跟踪事件被选中)、要使用的跟踪模板(这些模板是位于 TraceTemplates 子文件夹中的可自定义的 XML 文档)以及要采用的翻转文件大小。
说明/输出
主配置屏幕的最后一部分由两部分组成:一组基本说明,用于说明如何开始使用此工具;一个输出窗口,一旦启动该窗口,它就会显示收集服务程序的控制台输出结果。此窗口实际上就是目标计算机的事件日志视图,事件日志经过滤从而只显示出那些与收集服务程序直接相关的事件,以及该程序自开始收集数据以来写入日志的输出结果。
开始收集
配置完要收集的诊断信息后,请单击 Start(开始)开始进行收集。然后,DiagConfig 将会显示出一个启动参数对话框,您可以使用此对话框针对您要启动的诊断信息收集来提供参数。如图 3 所示:
图 3:DiagConfig 启动参数对话框
您可以在此为收集服务程序指定许多启动参数。以下将对它们分别进行说明。
模式
Mode(模式)设置使您可以指定是从已安装 SQL Server(并且您可以与其连接)的计算机上进行收集,还是从未安装 SQL Server 的计算机上进行收集。如果选择了 SQL Server 模式,只要确定收集程序可以与目标 SQL Server 实例连接并且是该实例内的 sysadmin 组成员,收集程序就会启动。如果这些检查中的任一项失败,则将忽略此实例,而不对其进行诊断信息收集。这意味着如果您接受默认目标实例名称 *(如上所述,它会使收集程序清点安装在目标计算机上的 SQL Server 实例),将不会从收集时没有运行的或存在其他连接问题的任何实例中收集诊断信息。
如果设置为 Generic(普通)模式,将不会进行 SQL Server 连接检查。如果您选择了特定于 SQL Server 的诊断信息(例如事件探查器跟踪),收集服务程序仍然会尝试连接这些信息,但是如果在试图到达服务器时发生了连接问题,或者您缺乏对服务器的足够权限,那么就可能无法连接。如果从非 SQL Server 计算机中收集诊断信息,此模式显然非常有用。它还可以用于从存在安装问题或连接问题的 SQL Server 计算机(例如,您可能需要从某台计算机上收集 Perfmon 日志,而该计算机由于某种原因使您无法连接到 SQL Server)中收集有限的诊断信息。
输出文件夹
我想您一定猜到了,Output Folder(输出文件夹)用于指定收集程序将其所有诊断信息输出到其中的文件夹。此文件夹必须已存在于目标计算机上,或者可以创建(这意味着如果它是一个子文件夹,那么其父文件夹必须已经存在)。如果未指定此文件夹,它就默认为收集程序启动目录下名为 OUTPUT 的子文件夹。此文件夹所在的驱动器应当有足够的空间,最好不由 SQL Server 使用,无论以何种方式(例如用于数据或日志文件)。由于具体需要多少空间取决于您所收集的诊断信息和目标计算机上正在发生的活动数量,因此此工具无法预先了解您是否有足够的空间。
您还可以控制收集服务程序在启动时如何管理现有的输出文件夹。您可以指示程序完全覆盖该文件夹的内容(默认设置),也可以在开始新的收集之前清除或重命名该文件夹。重命名的输出文件夹的格式为 Output_00001、Output_00002 等,数字最大的文件夹就是最近重命名的文件夹。
压缩
Compression(压缩)设置控制着收集服务程序是否压缩收集到的诊断信息文件,或者在收集时压缩 (NTFS),或者在关闭时压缩 (ZIP)。如果您选择 NTFS 压缩,那么收集服务程序就会启动一个低优先级后台线程,此线程将使用 NTFS 压缩(假设输出驱动器为 NTFS 分区)来压缩收集到的诊断信息文件。此线程每隔 30 秒唤醒一次,并检查是否存在尚未压缩的新文件。如果您选择 ZIP 压缩,那么收集程序就会在关闭时将输出文件夹中的文件压缩到单个 Zip 文件中(默认设置为 PSSDiag.Zip)。程序会先将所有内部诊断信息文件(这些文件是特定于 PSSDiag 的,而非您所要求的那些文件,它们具有 ## 前缀)添加到一个名为 PSSDiagInternal.Zip 的 Zip 文件中,然后将此 Zip 文件连同您所要求的诊断信息的所有输出文件,一起添加到一个名为 PSSDiag.Zip 的文件中(此文件的名称取决于收集服务程序的名称,如上所述,此文件名可以被更改)。
日程安排
Scheduling(日程安排)部分使您可以安排收集服务程序如何以及何时运行和关闭。您可以配置 Start Date/Time(开始日期/时间)和 End Date/Time(结束日期/时间),以及收集服务程序是否应当自动重新启动和/或仅收集数据的快照并自动关闭。您所指定的时间可以是相对时间也可以是绝对时间,还可以将两者结合使用(例如,您可以将启动时间设置为绝对时间,而将关闭时间设置为相对时间)。相对结束时间总是相对于开始时间而非当前时间,而相对开始时间总是相对于当前时间。如果您指定一个已过去的绝对日期/时间,收集程序会自动调整其日期,以使该程序在将来发生。根据指定的时间和当前时间,程序将会在今天或明天的指定时间发生。
在开始收集数据之前,收集程序在给定的时间或时段内等待传递数据时绝对不会占用主机上的 CPU 资源。它会通知 Windows 需要唤醒它的时间,然后开始休眠,直到 Windows 唤醒它。到达开始时间时,Windows 会发信号通知收集程序开始收集数据的时间到了,收集程序就会照常开始收集诊断信息。
选择 Run Continuously(不间断运行)选项将在收集程序由于到达结束时间而关闭时通知其自动重新启动。这可以用于每日运行特定的诊断信息收集程序。由于您可以指定相对时间和没有指定日期的时间,因此这一功能就使您可以在每天的一段时间内(如早上 9 点到下午 5 点之间)收集相同的诊断数据。下午 5 点关闭后,收集服务程序将会自动重新启动,并等到第二天的早上 9 点再次开始收集数据。
其他
尽管在默认情况下 PSSDiag 会运行一个存储过程来收集 SQLDIAG 报告,但是用户仍然可以根据需要改为使用 SQLDIAG.exe。需要注意的一个特殊情况是,PSSDiag 默认使用的存储过程收集的数据与 SQLDIAG.exe(实际上是一个数据父集)收集的数据完全相同,并且数据的格式也相同。两者之间唯一显著的区别是 SQLDIAG.exe 还会收集 MSInfo32/WinMsd 报告,而 PSSDiag 使用的存储过程则不会。这是由于 PSSDiag 可以被配置为通过其自定义的诊断功能来单独收集 MSInfo32/WinMsd,我们将会在下面对此进行论述。通过单独收集 MSInfo32/WinMsd 的功能,可以将该报告与 SQLDIAG 报告的存储过程一同收集。这样将会提高整体性能并缩短收集报告所需的时间。考虑到收集 MSInfo32/WinMsd 需要大量时间,因此保留默认设置要比使用 SQLDIAG.exe 收集该报告具有明显的优势。
一旦您单击了 OK(确定),您所指定的配置信息和启动参数就会被写入目标计算机的注册表(XML 格式),收集服务程序也将被启动。如果从正在运行配置应用程序的计算机上进行收集,DiagConfig 还会在尝试启动收集服务之前自动为您注册此服务。
当收集服务程序启动后,DiagConfig 将会在 GUI 说明/输出部分的 Output(输出)页显示出其输出结果。如图 4 所示:
图 4:DiagConfig 显示 PSSDiag 收集服务程序的输出结果。
此输出结果显示会每隔 5 秒更新一次,并且所显示的目标计算机的应用程序事件日志,只限于收集服务程序在该次运行过程中收集的部分。您也可以使用 Windows 事件查看器工具来查看相同的信息,但是您将会发现使用 DiagConfig 来查看会容易得多。
当收集服务程序正在运行时,您将无法更改任何配置或启动参数。如果您希望变更要收集的诊断信息,请停止并重新启动收集服务程序。
请记住,在收集服务程序运行时您可以将 DiagConfig 最小化甚至完全退出它。DiagConfig 会创建一个任务栏图标,这样您就可以根据需要通过任务栏来控制收集服务程序。
请注意,您并不一定要使用 DiagConfig 来启动和停止收集服务程序。您还可以使用 Windows 的服务控制管理器应用程序或收集程序附带的 DiagControl 命令文件。如果您通过 DiagConfig 启动收集服务程序,然后通过其他某种机制来停止该程序,DiagConfig 将会检测到这一情况,并在其显示出的用户界面中反映出相应的状态和输出结果。由于某些原因(在此不深入探究),您不应当使用服务控制管理器应用程序来停止收集服务程序。而应当使用 DiagConfig 或 DiagControl 命令文件。
在这一节中,我将会详细论述收集服务程序的有关内容,包括其工作方式和使用方法。如果您使用 DiagConfig 来控制和配置收集服务程序,通常您将不需要直接与收集服务程序进行交互,但仍然需要理解其工作方式。
收集服务程序是一个本机代码应用程序,它可以作为控制台应用程序或服务程序来运行。DiagConfig 总是将其作为服务程序来运行。这就使该程序可以在远程计算机上进行配置和控制,并使得用户可以从主机中注销而不会停止诊断信息的收集(用户注销时所有非服务应用程序都会被停止)。
无论收集程序是如何启动的,它总会将重要的状态信息写入主机的应用程序事件日志,每个日志记录中的 Source(来源)列都会被设置为收集服务程序的名称 - 默认设置为“PSSDIAG”。如果作为控制台应用程序启动,它也会将此信息写入系统控制台。任何错误或其他重要消息都会以红色显示。
另外,所有状态信息和内部诊断信息都会被写入收集程序的日志文件,默认文件为 ##PSSDiag.log。此文件将会包含一个写入控制台和应用程序日志的状态信息父集,通常被 Microsoft 产品支持服务用来解决与 PSSDiag 本身相关的问题。
如果没有另外进行重定向,从收集服务程序产生的子进程得到的输出结果(例如自定义诊断信息)将被捕获到一个名为 ##console.log 的文件中。因为 Windows 命令处理器默认进行 ANSI 输出,所以此文件是一个 ANSI 文件,即使 PSSDiag 本身为 Unicode 应用程序。
配置文件
一旦收集程序启动,它将会读取传递给它的配置信息和启动参数。如果是作为一个服务程序运行,它会从注册表中获取其启动参数。如果是作为一个控制台应用程序运行,它会从命令行获取其启动参数。
PSSDiag 支持从三种不同的来源读取其配置信息:INI 文件、XML 文档或注册表(您可以通过 /I 启动参数来指定一个配置文件)。如果没有在启动参数中指定配置文件,那么收集程序会首先检查 PSSDiag.ini 文件,如果此文件存在将加载它。INI 格式是一个简单的名称-值对文件,该格式类似以下示例:
[.] SetupVer=3.0.0.5 CaseNumber= SSVer=8 Instance=* WindowsAuth=1 Username= SQLDiag=0 SQLDiagStartup=0 SQLDiagShutdown=1 EventLogs=0 EventLogsStartup=0 EventLogsShutdown=1 Profiler=1 ProfilerEvents=76,75,92,94,93,95,16,22,21,33,67,55,80,61,69,25,59,60, 27,58,14,15,81,17,10,11,35,36,37,19,50,12,13 ...
此格式非常易懂:每个布尔开关的值均被指定为 1 或 0;具有多个值的设置要么是多个单独的 INI 关键值,要么以逗号分隔等。
INI 中的节标题([.] 以上)代表目标计算机名称,您可以设置具有多台目标计算机的单个文件,每台计算机在 INI 中都有属于自己的一节。这项强大的功能使您可以使用单个 PSSDiag 实例非常方便地从多台计算机中收集诊断信息。收集程序启动后,它将会清点配置文件中列出的计算机并同时从这些计算机中收集信息。
DiagConfig 将只使用 XML 配置文件和注册表;它不会对 INI 配置文件进行读写。通常只有 Microsoft 产品支持服务工程师才会对 INI 配置文件进行读写。由于 PSSDiag.ini 是默认的配置文件名称,这就为 Microsoft 产品支持服务提供了一种方便的机制来暂时替代它需要收集程序收集的那些诊断信息,而不会影响任何您可能已经配置的诊断信息。一旦支持事件结束,您就可以安全地删除此 INI 文件,以便收集服务程序读取 DiagConfig 存储在注册表中的配置值。
如果 PSSDiag.ini 不存在,收集程序接下来将会查找 PSSDiag.xml。PSSDiag XML 配置文件格式在语义上与其 INI 格式等同,该格式类似以下示例:
...
XML 架构 pssdiag_schema.xsd 用来确保该格式符合收集程序的期望。如果您使用 XML 编辑器来编辑 PSSDiag XML 配置文件,此架构将会保护该文件,使其不发生会扰乱或打断收集程序的改变。
XML 格式与 INI 格式相比的主要优点在于,使用 XML 格式您可以为安装在给定计算机上的不同 SQL Server 实例收集不同的诊断信息。而使用 INI 格式,您必须从特定计算机上的所有目标实例中收集相同的诊断信息。您可以选择是从单个实例还是全部实例中收集信息,但必须从选定的所有实例中收集相同的诊断信息。XML 格式则不是这样。因为每个实例在 XML 文档中都有属于自己的一节,所以每个实例都可以具有不同的诊断信息配置。
如上所述,DiagConfig 将只使用 XML 配置文件和注册表配置。通常情况下,除非您已使用 Microsoft 产品支持服务来帮助解决问题,否则,在与收集服务程序进行交互时您只能使用 XML 配置信息。
如果 PSSDiag.xml 不存在,收集程序接下来将会检查注册表以获得配置信息。DiagConfig 会将您在其中指定的配置信息以 XML 格式存储到注册表项 HKLM\Software\Microsoft\SQLDiagEx\PSSDiag 之下。注册表配置设置的格式规则与 XML 配置文件的格式规则相配,未经 Microsoft 允许您不应直接修改此信息。如果您需要修改收集程序的配置信息,请使用 DiagConfig。
因为 DiagConfig 总是将配置信息写入注册表,并且 INI 或 XML 配置文件优先于注册表中的配置信息,所以在使用 DiagConfig 对数据收集进行配置时,您会希望确保不存在 XML 或 INI 配置文件。如上所述,最简便的方法是一旦支持事件结束,就删除您从 Microsoft 产品支持服务工程师那里接收的任何配置文件。
多计算机收集
和使用 INI 配置文件一样,您可以使用 XML 配置格式配置为同时从多台计算机中收集诊断信息。这就相当于在 XML 文档中设置多个 <Machine> 标记并提供必要的子元素和属性。最简便的方法是复制并粘贴一台计算机对应的 <Machine> 节点节,以便创建多个计算机节。
对于此主题,另外需要在此说明的一点是,您也可以使用单个收集程序实例来收集多台计算机中的诊断信息,而不用设置多个配置文件节。收集程序支持使用星号 (*) 作为计算机名称,在收集过程中会根据收集程序的运行模式对星号进行不同的评估。
从以上论述中您可以记起,模式开关控制着 PSSDiag 是否启用特定的 SQL Server 专用连接以及权限检查。它还会影响指定 * 作为目标计算机名称时星号的评估方式。在 SQL Server 模式中,* 会使收集程序清点当前域中所有可见的 SQL Server。这些服务器必须作为 SQL Server 来运行和广播它们自己。在 Generic(普通)模式下,使用 * 作为计算机名称将会使收集程序清点当前域中所有可见的服务器,而不管它们是否正在运行 SQL Server,并试图收集这些服务器中的诊断信息。因此,您可以方便地使用此功能从每个 SQL Server 中,甚至从收集程序主域上的每台计算机中收集相同的诊断信息。
从多台计算机中收集相同诊断信息的另一种方法是使用计算机列表文件(使用 /M 启动参数表示列表文件,并在文件名前面添加 @,例如 /M @myservers.txt)。计算机列表文件仅仅是一个文本文件,其中各行列出了您要从中收集诊断信息的计算机。指定计算机列表文件将会使配置文件中指定的计算机名称被列表文件中指定的计算机名称替代,并将同时从所有这些计算机中收集诊断信息。如果您想用单个计算机名称来替代配置文件中指定的计算机名称,只需通过 /M 启动参数指定该名称(例如 /Mmymachine)。
群集
收集服务程序功能还特别支持从 Windows 群集中收集诊断信息。当在群集节点上运行,并且指定 .(默认值)作为计算机名称时,收集服务程序将会检测到它运行在群集上,并且如果是在 SQL Server 模式【与 Generic(普通)模式相对】下,将会检索安装在群集上的虚拟 SQL Server 并同时从它们中收集信息。这意味着如果只存在一个虚拟 SQL Server,您不需要执行任何操作就可以使收集程序识别它并从中收集合适的诊断信息。如果您想只从同一计算机上多个虚拟 SQL Server 中的一个中收集信息,请指定该虚拟 SQL Server 作为目标计算机名称。
收集进程
一旦完成了对配置信息的处理,收集服务程序就会开始收集您所要求的诊断信息。对于配置信息中的每个计算机节,收集程序都会启动一个单独的工作线程,并同时从所有计算机中收集信息。一台特定计算机中的所有诊断信息仅需使用一个工作线程来收集。这意味着如果您只从单个计算机中收集诊断信息(默认情况),收集程序就会只创建一个工作线程来收集所要求的数据。这种设计使 PSSDiag 几乎可以按线性方式衡量,并以有效方式同时从多台计算机中收集数据。
请注意,这种设计并不表示一台特定计算机中的所有诊断信息必须以串行、同步的方式来收集。正相反,大部分诊断信息是以并行方式收集的。既然我们为每台计算机只使用了一个工作线程,那么这是如何实现的呢?这是因为除了 Perfmon 日志以外的所有诊断信息都是通过其他程序来收集的。这通常是 SQL Server OSQL 实用程序 (SQL Server 2005 中的 SQLCMD),但有时也会是 Windows 命令处理器或某些其他可执行程序。通过让这些工具来承担诊断信息收集的大部分工作,收集程序就更多地担任了管理角色,只需为每台计算机使用一个工作线程即可。收集程序将监控其产生的进程并根据情况等待它们完成,通常会同时等待几个进程。
在收集进程中,您所要求的每个诊断信息都会按照指定要求进行收集,并且会将其输出结果传送到输出文件夹中。唯一的例外可能就是事件探查器跟踪。如果您在一台计算机上运行收集服务程序而要从另一台计算机中收集事件探查器跟踪,那么事件探查器跟踪将会被写入远程计算机。这是由于收集程序使用 SQL Server sp_trace_* 扩展存储过程来收集事件探查器跟踪,并且这些过程总是在主机 SQL Server 环境内运行。这意味着您指定的输出文件夹在正运行收集程序的计算机和远程 SQL Server 计算机上都必须存在。因此,如果您将输出文件夹设置为“C:\PSSDiag\Output”,它必须在两台计算机上都存在。在关闭进程中,收集程序将会尝试使用远程系统上的管理共享将跟踪文件复制到本地计算机上的输出文件夹中,以便使所有诊断输出都位于同一个位置,并且如果您启用了 ZIP 压缩还可以将输出结果压缩到单个文件中。
请注意,虽然收集程序支持从远程计算机中收集数据,但这并不是它的默认工作方式,除非确实需要,否则不应使用此功能。从远程计算机中收集数据还有一个更简便的方法,那就是在每台远程计算机上都安装收集服务程序,然后使用 DiagConfig 来管理您与每台计算机的交互。DiagConfig 不直接支持从没有安装收集服务程序的计算机中收集诊断信息。
关闭进程
一旦收集服务程序启动了数据收集,它就会持续进行下去,直到您关闭该程序或者它碰到了关闭条件(例如,它到达了先前指定的某个结束日期/时间或者由于您只要求诊断信息快照而自动停止等)。当作为服务程序运行时,停止收集程序的最佳方法是单击 DiagConfig 中的 Stop(停止)。您也可以运行收集程序的启动文件夹中的 DiagControl STOP 或使用服务控制管理器来停止它。由于某些原因(在此不深入探究),您应当如上所述尽量使用 DiagConfig 或 DiagControl 而不是 Windows 服务控制管理器。
收集程序关闭后,将会停止它启动的所有诊断信息收集。这意味着它会停止先前启动的所有事件探查器跟踪,取消当前运行的所有 T-SQL 脚本,并终止产生的所有子进程(包括子进程产生的所有子进程)。一旦所有诊断信息都被停止,如果您事先要求,收集程序会将其输出结果压缩到一个 Zip 文件中,然后退出。
如果您指定了 Run Continuously(不间断运行)启动参数,假设收集程序由于到达了指定的结束时间而停止,它会在退出前重新启动。其运行方式就像手动重新启动一样。如上所述,这将使您可以方便地每日收集给定的诊断信息集合,而不用手动启动和停止收集程序。
安装或卸载收集服务程序通常情况下,您不需要手动安装收集服务程序。如果您使用 DiagConfig 来管理本地计算机上的收集服务程序,它将会根据需要注册收集服务程序。但是在有些情况下,您可能会希望手动进行注册,因此我将会提供一些有关如何手动注册的说明。例如,如果您打算在多台计算机上安装收集服务程序,并且使用 DiagConfig 通过单台计算机来管理所有这些计算机。此时您就可能会希望手动进行注册。如果您需要在没有安装 .NET Framework 的服务器上安装收集程序,您也可能会需要手动注册收集服务程序。由于 DiagConfig 是一个托管代码应用程序,因此您必须在运行它之前安装 .NET Framework,或者不使用 DiagConfig 注册收集服务程序和与其交互。
首先,可执行的收集程序 PSSDiag.Exe 可以通过 /R 命令行参数将自身注册为一个服务程序(/U 用于撤销注册)。您注册时在命令行上指定的任何参数都会被保留以便将来运行服务程序。撤销注册服务程序不但会删除服务程序,还会删除特定于 PSSDiag 的注册表项,而无需使用卸载应用程序。PSSDiag 卸载进程实际上就是撤销注册服务程序并删除包含二进制和支持文件的目录。
其次,您可以通过 /A 命令行参数来控制收集服务程序的名称。使用此选项可以在单台计算机上安装多个 PSSDiag 实例。如果不指定此选项,默认的服务程序名称将是 PSSDiag,但是您可以根据要求使用其他任何名称。所有输出文件和消息等都将会与您所用的名称相符合。这使您可以拥有多个收集服务程序实例,例如,一个连续运行用于收集影响甚微的诊断信息集合的实例,一个根据需要运行用于收集更具有破坏性的诊断信息集合的实例。如果您选择在同一计算机上安装多个收集服务程序实例,最佳做法是将 PSSDiag 二进制和支持文件复制到每个实例单独的文件夹中,并且根据您打算使用的实例名称来命名每个文件夹。这样就不必担心忘记为每个实例指定不同的输出文件夹(因为默认输出文件夹为服务程序启动目录下的 OUTPUT 子文件夹),并且帮助防止发生其他类型的潜在的文件访问冲突。
既然已经内置了这么多的功能,下一步当然就是支持自定义诊断信息的收集,以便您可以收集所需要的诊断信息,而不仅仅是直接内置在收集服务程序中的那些诊断信息。幸运的是,收集程序提供了内容丰富的自定义诊断信息工具,实际上,一些内置的诊断信息就是使用此工具收集的。
DiagConfig 配置应用程序目前不支持创建包含自定义诊断信息的配置信息,但是 INI 和 XML 配置格式都支持自定义诊断信息,并且 DiagConfig 将会保存其读取的您在 XML 配置文件中配置的自定义诊断信息。我将会对此以及如何快速向 DiagConfig 写入注册表的配置信息中添加自定义诊断信息进行详细说明。
由于通常您只会用到 XML 配置文件,因此我将会向您展示 XML 格式的自定义诊断信息的结构,然后说明每个部分表示的意思:
<Collector type="customdiagnostic" point="startup" groupname="Cluster Diag" taskname="Get PSTAT" customdiagtype="utility" wait="yes" cmd="`PSTAT50.exe > "%OUTPUT_PATH%%COMPUTERNAME%_PSTAT.TXT"`" />
以上自定义诊断信息节点用于将一个名为“Get PSTAT”的自定义诊断信息添加到一个名为“Cluster Diag”的诊断信息组中。诊断信息组只用于提供信息,它与诊断信息实际的收集方式和收集时间无关。
point 属性用于在收集自定义诊断信息的收集进程中及时对点进行配置。以上自定义诊断信息将被配置为在收集程序启动时进行收集,但是也可以将其配置为在收集程序关闭时进行收集。
这种特定的诊断信息具有实用程序 customdiagtype。有以下几种类型可供选择:
表 1:自定义诊断信息类型 类型 用途实用程序
可执行文件、.BAT 文件或 .CMD 文件
TSQL_Script
Transact-SQL 脚本
TSQL_Command
Transact-SQL 命令或存储过程(例如 sp_who)
Reg_Query
注册表查询,将返回注册表中某一项的值
Reg_Save
将特定的注册表项保存为 .HIV 文件
Copy_File
将目标系统上的文件复制到输出文件夹中
Type_File
列出目标系统上的某个文件,可以选择将其重定向到输出文件夹中的某个文件
Tail_File
将文件的最后 n 字节转储到输出文件夹中的某个文件
VB_Script
ActiveX 脚本
wait 属性可指示收集服务程序是否会等待任务完成才继续收集其他诊断信息。该属性可以具有以下三个值之一:Yes、No 和 OnlyOnShutdown。前两个值不用解释;而 OnlyOnShutdown 用于通知收集程序在任务首次开始执行时不要等待任务完成,但是如果收集程序关闭时此任务仍在运行,则要等待该任务完成。这使您可以将持续时间较长的自定义诊断信息收集任务与收集进程的其余部分同步运行,并在收集程序停止后等待这些任务完成。
cmd 属性的用途根据自定义诊断信息类型的不同而不同。它通常不仅仅是一个文件名或注册表路径,它通常由用于相关自定义诊断信息的一个完整的命令行组成(例如,命令行开关、重定向和管线等)。表 2 总结出了 cmd 属性的各种用途:
表 2:cmd 属性对于每个自定义诊断信息类型的重要性 类型 cmd 属性的意义实用程序
可执行文件、.BAT 文件或 .CMD 文件的名称(如上所述,通过重定向指定输出文件名)
TSQL_Script
Transact-SQL 脚本的名称。如果此文件具有 .TEM 扩展名,那么 PSSDiag 会在运行嵌入的元变量之前将其转换。输出文件名将取决于脚本名称
TSQL_Command
Transact-SQL 命令或存储过程(例如 sp_who)。输出名称将取决于组名、任务名、目标服务器【及实例(如果存在)】和命令的执行点(启动或关闭)。
Reg_Query
要返回的注册表值(通过重定向指定输出文件名)
Reg_Save
要保存的注册表项(通过重定向指定输出文件名)
Copy_File
源文件和目标文件的名称(用双引号将包含空格的文件名引起来)
Type_File
要列出的文件的名称(通过重定向指定输出文件名)
Tail_File
要列出的文件的名称(通过重定向指定输出文件名)
VB_Script
ActiveX 脚本的名称(通过重定向指定输出文件名)
正如此表所指出的,您可以使用重定向捕获多种自定义诊断信息的输出结果。您可以使用 %output_name% 元变量(下面将说明)来轻松地执行此操作:
<Collector type="customdiagnostic" point="startup" groupname="Cluster Diag" taskname="Get PSTAT" customdiagtype="utility" wait="yes" cmd="`PSTAT50.exe > "%OUTPUT_NAME%.txt"`" />
cmd 属性要用右引号(或者重音标记,即 ` 字符)来分隔,以便它可以包含其他类型的引号。由于是 XML 属性,因此它还要用双引号引起来。很明显,INI 格式不需要(甚至不允许)使用这些外部双引号。
如果您使用了包含空格(或可能包含空格)的文件名或路径,请确保用双引号将其引起来,如上所述。由于 Windows 命令处理器经常会收到您指定保持原样的文件名、路径或命令,因此遵守 Windows 的文件路径规则是很重要的。
支持文件
在不明显的情况下,您的自定义诊断信息需要的任何文件(在此例中为 PSTAT50.exe)都应当位于系统路径中或者被复制到收集程序的启动文件夹中。从 Microsoft 产品支持服务那里收到的任何 PSSDiag 软件包都会包含收集所要求的诊断信息需要的所有文件。
变量
如果您仔细观察以上示例,您就会注意到类似 %OUTPUT_PATH% 和 %COMPUTER_NAME% 环境变量的用途。实际上,只有第二个,即 %COMPUTER_NAME% 才是真正的环境变量。%OUTPUT_PATH% 将由收集程序内部转换为输出文件夹的完整路径,结尾包括一个反斜杠。在 PSSDiag 的用语中,这两个变量是元变量,即由收集程序内部转换的伪环境变量。收集程序中内置了多个此类变量:
表 3:内置的元变量 变量 转换为%output_path%
输出文件夹的完整路径,结尾包括一个反斜杠
%server%
目标计算机名
%instance%
目标 SQL Server 实例名,此变量将会扩展到为特定计算机配置的所有实例
%server_instance%
目标计算机和 SQL Server 实例,此变量将会扩展到为特定计算机配置的所有实例
%startup_path%
收集服务程序的启动文件夹的完整路径,结尾包括一个反斜杠
%ssuser%
用于连接到 SQL Server 的用户名
%sspwd%
在使用 SQL Server 验证的情况下用于连接到 SQL Server 的密码。【出于安全考虑,请不要将此密码存储在磁盘上或以任何形式保存。此密码专门在命令行上使用,在使用 SQL Server 验证的情况下用于需要连接到 SQL Server(例如 OSQL)的工具。】
%sspath%
指向 SQL Server 的根安装文件夹的完整路径,结尾包括一个反斜杠
%ssregroot%
SQL Server 的根注册表项
%authmode%
1 或 0,指示是否使用 Windows 验证用于连接到 SQL Server
%ssver%
指定在配置文件中的 SQL Server 的目标版本
%output_name%
合成输出文件名,由诊断信息组和任务名称、目标计算机和 SQL Server(如果有)以及用于指示诊断信息收集时间的一个字符串组成
%internal_output_name%
合成内部(前缀为 ## )输出文件名,由诊断信息组和任务名称、目标计算机和 SQL Server(如果有)以及用于指示诊断信息收集时间的一个字符串组成
%ssbatchrunner%
用于运行 T-SQL 脚本的可执行文件名(OSQL.exe 或 SQLCMD.exe,取决于 SQL Server 的版本)
%quietmode%
1 或 0,指示是否在收集程序的启动参数中传递了静音状态开关 (/Q)
%forceremotemode%
1 或 0,指示是否使用存储过程代替 SQLDIAG.exe 来收集 SQLDIAG 报告
%compressionmode%
一个整数,指示选择的是非压缩、NTFS 压缩还是 ZIP 压缩
%genericmode%
1 或 0,指示是否在收集程序的启动参数中传递了 Generic(普通)模式开关 (/G)
蕇enumber%
字符串,指示与收集相关联的产品支持服务案例号
%starttime%
字符串,指示所指定的收集开始日期/时间
%endtime%
字符串,指示所指定的收集结束日期/时间
%comspec%
指向 Windows 命令解释器的完整路径(cmd.exe 或 command.com,取决于版本)
蟝file%
配置文件的完整路径
%outputfoldermode%
一个整数,指示收集服务程序启动时应当清除、覆盖还是重命名现有的输出文件夹
您可以在您创建的自定义任务中使用这些变量中的任何一个,以及系统上的任何环境变量。它们的语法都相同:只是用百分号 (%) 标记对变量名进行了分隔,如上所述。
自定义元变量
您还可以定义自定义元变量。您可以以名称-值对格式指定这些变量,并用分号将它们与 cmd 主要文本(以及它们相互之间)进行分隔。下面是一个示例:
<Collector type="customdiagnostic" point="startup" groupname="MergeReplication" taskname="GeneralMergeAnalysis" customdiagtype="tsql_script" wait="yes" cmd="`merge_analysis.TEM; %pubdb%=Northwind `" />
在此示例中,我们配置了一个要执行的自定义 T-SQL 脚本模板 merge_analysis_.te.。正如表 2 中所述,具有扩展名 .tem 的脚本将被视为模板,收集程序会在运行该模板之前自动转换模板中包含的任何嵌入元变量(包括系统环境变量)。此进程将会产生一个文件,它在执行前被重写为 .SQL 脚本。在以上的示例中有一个单独的自定义变量 %pubdb%,它的值被定义为 Northwind。这会使收集程序在执行该脚本模板之前将脚本模板中出现的每一处 %pubdb% 替换为 Northwind。
您可以通过用分号进行分隔来设置多个自定义元变量:
<Collector type="customdiagnostic" point="startup" groupname="MergeReplication" taskname="GeneralMergeAnalysis" customdiagtype="tsql_script" wait="yes" cmd="`merge_analysis.TEM; %pubdb%=Northwind; %distdb%=distribution `" />
在此,我们定义了两个自定义变量:%pubdb% 和 %distdb%。每个变量每次在模板脚本中出现时,都会被替换为相应的值。
在一个自定义诊断信息任务中定义的元变量可以在随后的任务中重复使用。因此,例如,如果您在自定义任务 #1 中定义了 %pubdb%,随后您就可以在自定义任务 #2 中重复使用此变量(而无需为它赋值)。这表示,例如脚本模板任务可以引用在前面的任务中定义的自定义变量,就像是在该自定义任务定义中为这些变量赋予了值一样。
您还可以重定义自定义变量。后续的自定义任务将会使用最近赋予的值。
提示输入变量
您可以不为元变量赋予固定的值,而是指示收集程序控制台应用程序(而不是服务程序)在运行时提示输入元变量的值。为了使诊断信息配置更加通用并且方便重新使用,有时您可能会希望推迟到收集程序实际运行时才为变量赋值。您可以在自定义诊断信息内通过元变量定义中的特殊标记来进行此设置:
<Collector type="customdiagnostic" point="startup" groupname="MergeReplication" taskname="GeneralMergeAnalysis" customdiagtype="tsql_script" wait="yes" cmd="`merge_analysis.TEM; %pubdb%=?!"pubdb","Please supply the name of the published database","string",""!? `" />
正如您所看到的,提示详细信息被包含在 ?! 和 !? 标记内。它们标记出了定义提示的字段的开始位置和结束位置。正如您所看到的,提示赋值由四个子字段组成,它们按 CSV 格式分隔。这些字段的第一个是变量名。此字段不是由收集程序使用(而是由其他内部 Microsoft 工具使用),但是它必须与元变量赋值语句左侧所使用的名称相匹配。第二个字段是提示输入变量时收集程序所显示的提示信息。第三个字段是变量的数据类型。此字段目前未使用(所有变量都被视为字符串),但是以后可能会有所改变。最后一个字段是字段的默认值。收集程序将会根据提示输入变量的时间将其显示在圆括号中,如果提示输入值时您按了 Enter 而没有输入新值,此默认值就会被赋予变量。
显然,只有当收集程序作为控制台应用程序运行时,它才能够提示输入元变量。服务程序无法方便地与 Windows 桌面进行交互,因此如果收集程序作为服务程序运行,就没有使收集程序提示输入的有效方法。实际上,当收集程序作为服务程序运行时,它就像是指定了静音状态开关 (/Q) 一样,并且会跳过它作为控制台应用程序时会显示的任何输入提示。这意味着它会为您在配置信息中设置的元变量提示赋予默认值。
多值变量
您还可以定义具有多个值的变量。您可以通过设置要运行的子进程并将该进程的输出结果(多大 2GB)赋予某个变量来定义多值变量。随后可以在后续的自定义诊断信息收集中使用该变量,并且针对变量中存储的每个输出行收集一次自定义诊断信息。
此功能与 Windows 的 for 命令相似。它提供了与此命令相同的功能而无需编写批处理文件代码。
与提示输入变量相似,将另一个进程的输出结果赋予变量是通过使用元变量赋值中的特殊标记和子字段来实现的。下面是一个示例:
<Collector type="customdiagnostic" point="startup" groupname="GeneralUtilities" taskname="ListFiles" customdiagtype="utility" wait="yes" cmd="`echo %file% >>"%output_name%.TXT"; %file%=!!dir /b *.txt!! `" />
正如您所看到的,多值赋值中使用的特殊分隔标记为 !!。在此示例中,我们运行了操作系统命令 dir /b *.txt 并且将其返回的输出结果赋予了 %file% 变量。这一特定命令仅列出了与指定掩码相匹配的文件名,而不显示其他目录标题或详细信息。这些文件名随后将被赋予 %file% 自定义元变量。然后,当收集程序为收集自定义诊断信息运行指定的 echo %file% 命令时,它会针对列表中的每个文件名收集一次自定义诊断信息,并将 %file% 替换为列表中每次迭代得出的每个连续名称。
如上所述,此功能提供了与操作系统的 for 命令相似的的功能,在此特定示例中,未提供通过更多简单机制也无法实现的功能。但是,将此功能内置于收集程序使最终用户无需熟悉那些不常用的批处理文件结构的细微差别(例如 for),并使您可以按照为普通元变量赋值的方式来为多值元变量赋值。
向 DiagConfig 中添加自定义诊断信息
由于 DiagConfig 不直接支持将这些信息添加到收集程序的配置信息中,因此您可能想知道如何配置收集程序才能收集自定义诊断信息。这实际上非常简单。DiagConfig 在启动时会检查系统注册表中是否存在收集程序配置信息,如果存在将加载该信息。如果注册表中不存在配置信息,它就会加载一个包含默认配置的 XML 文档(Pristine 子文件夹中的 _Default.xml)。通过修改此文档,您可以添加 GUI 启动收集服务程序时将写入注册表的自定义诊断信息。(要删除已经写入注册表的配置信息,您只需如上所述撤销注册收集服务程序即可)。
要向此文档中添加自定义诊断信息,请将类似以上显示出的节点的“收集程序”节点添加到 _Default.xml 文件中的 ...\Instance\Collectors 一节中。虽然您将无法看到 GUI 中显示出的自定义诊断信息,但是它确实存在,并且稍后将配置信息传送到目标计算机上的注册表中时会保存自定义诊断信息。当收集程序启动时,它会将您的自定义诊断信息与配置信息的其余内容一同读取,并将为您收集自定义诊断信息。
结论如果使用得当,PSSDiag 就会显示出一个稳定、强大、直观并且可扩展的诊断信息收集框架。它可以显著减少解决与 SQL Server 相关以及与 SQL Server 不相关的复杂问题所需的时间,并且可以用作对实际各类计算机进行长期监控的有效解决方案。
SQL Server for Developers
Ken Henderson 与爱妻和孩子一同居住在得克萨斯州达拉斯的郊区。他先后编著了八本书,内容涉及各种技术相关的主题,包括最近发行的“The Guru's Guide to SQL Server Architecture and Internals”(Addison-Wesley, 2003)。Ken 是达拉斯小牛队的忠实球迷,业余时间喜欢运动、园艺和照看孩子。