集中化监控SQL Server数据库
英文原文地址:https://www.simple-talk.com/sql/database-administration/centralize-your-database-monitoring-process/
名词解释:
CMS -- 中央管理服务器(Central Management Server)
MDW -- 管理数据仓库(Management Data Warehouse)
尽管微软提供了数据收集器来监控SQL Server实例和创建基线,维护和管理数百SQL Server实例的数据收集器配置并不容易,因此让那个我们看看如何使用CMS解决这个问题。
CMS可以在一个SQL Server实例集合上运行脚本。我们可以配置CMS在我们的SQL Server实例上运行脚本,并在所有的实例上配置数据收集器。因为数据库存储在SQL Server实例上,可以被作为一组资源访问;组内所有DBA都可以访问它。
数据收集器允许我们从SQL Server实例收集信息。我们创建和管理收集集合,指定收集的信息。所有的信息发送到一个中央数据库叫做MDW。数据收集器提供给我们一些内置收集集合和报表,我们可以按需定制。
本文的旨在告诉你如何使用CMS以相对容易的方式在大量的服务器中配置数据收集器。
CMS的配置用于注册一个服务器作为CMS,管理脚本的执行。我们可以使用相同的服务器实例来完成这两项任务,同时作为CMS和MDW数据库。
为了达成目标,需要如下步骤:
配置MDW数据库。
配置CMS。
通过CMS配置数据收集器。
查询服务器环境的状态。
通过CMS配置收集集合。
收集信息。
检查MDW报表。
检查是否收集任务正在运行。
在我的测试环境中描述该系统,我有四个SQL Server实例,一个默认实例和三个命名实例SQL2、SQL3和SQL4。我们将使用默认实例作为CMS服务器,并作为MDW数据库的主机。
我们可以使用SQL Server Management Studio(SSMS)界面配置MDW数据库。在对象浏览器窗口,我们首先连接到服务器。然后点击“Management”,右键“Data Collector”并点击“Configure Management DataWarehouse”。我们将跟着向导的指引去配置。
配置MDW向导
在向导执行完成,不仅创建了新的数据库,而且还有一个新的作业名为“mdw_purge_data_[yourdatabasename]”。对于每个SQL Server实例,该作业遵循配置在每个收集集合的过期规则,负责从MDW数据库删除过期的信息。
可以在SSMS(从SQL2008起)的“Rgeistered Servers”窗口完成CMS配置:右击“Central Management Servers”目录,并单击“Register Central Management Server...”命令。
在注册了CMS后,然后右击该CMS注册,你会发现“Register Server...”选项,在我们的示例中,有三个已注册的实例会列出来。
注册服务器时考量安全性是非常重要的。CMS只以集成安全性工作,因此你的登录帐号需要访问所有的服务器。你可以使用单个域,可信的多个域,或者在所有服务器中有相同用户名和密码的独立服务器,关键点是用户管理服务器的登录帐号需要访问所有的服务器。
在所有的服务器注册后,你可以右击CMS注册,并使用“New Query”命令来打开一个查询窗口。通常在一个查询窗口的左下角会显示该查询窗口已连接的服务器数量。
你在该窗口中运行的所有查询将对所有已连接的服务器执行。查询结果每一行将产生额外的服务器名列。请注意CMS服务器绝不会包含在多服务器查询的执行中。
你也可以针对一些服务器而不是所有服务器执行查询。为了完成该任务,你需要在CMS注册下创建服务器组,并在服务器组内注册服务器。你也可以要么从CMS服务器打开查询窗口,对所有服务器运行查询,要么只针对一个服务器组目录内的服务器运行查询。
有时使用CMS需要将服务器从一个组移动到另一个,你可以通过右键点击服务器然后选择“move to...”。
配置数据收集器需要设置三个参数:MDW数据库所在实例(存储数据的地方),MDW数据库名和缓存目录。
缓存目录被用于存储收集的信息而不直接上传到MDW数据库。可以对任何收集集合指定异步上传,因此你可以使用不同的计划任务来收集数据并上传信息到MDW。这对于一些需要在几秒内收集的信息非常重要,而可以在几分钟或几小时内上传。
为了对所有了SQL Server实例使用相同的脚本,我们需要对缓存目录指定路径,并对所有的服务器使用相同的路径。然而,当相同的物理主机有不止一个实例时,将会暴露一个问题。
问题的解决方案是在路径中使用“@@servername”变量。配置数据收集器的脚本如下:
/* 1st - create cache dir */ declare @cmd varchar(100) select @cmd='C:\DCCache\' + replace(@@servername,'\','_') exec xp_create_Subdir @cmd /* 2nd - configure data collector */ use MSDB EXEC sp_syscollector_set_warehouse_instance_name N'winsql2014'; EXEC sp_syscollector_set_warehouse_database_name N'MDW'; EXEC sp_syscollector_set_cache_directory @cmd; /* 3rd - enable data collector */ EXEC dbo.sp_syscollector_enable_collector;
这个脚本是第一个数据收集器的配置。有时你禁用了数据收集器并想启用它,你可以将脚本分成三个部分。牢记:
第一次你只需要创建缓存目录,如果你想修改配置或者禁用、重新启用数据收集器,你需要截取部分脚本。
除非你真的想修改配置文件,否则你只需要第一次配置数据收集器。你可以禁用、重新启用数据收集器而不用修改配置文件。
第三部分是主要的;你每次需要使用存储过程来启用数据收集器。
注意,我并没有检查路径是否已经存在,脚本说明了“@@servername”目录不存在而“c:\DCCACHE”存在。
你需要针对你的环境调整脚本。来看看你可以使用的一些选项:
你可以用一个存在于所有服务器上的路径来替代“DCCache”。
你可以在上面的脚本之前,运行使用xp_create_Subdir创建“DCCache”目录的脚本。这需要在物理服务器上运行一次,而不是在实例上。有很多方法,像PowerShell。
你可以修改以上脚本,来检查是否“DCCache”已经存在,如果不存在就创建“DCCache”。在上面的脚本之前的额外步骤,像这样:
Declare @dir table ( Directory varchar(200) ) INSERT INTO @dir EXEC master.dbo.xp_subdirs 'c:\' if not exists(select 1 from @dir where directory='DCCACHE') begin exec xp_create_Subdir 'c:\dccache' end
查询环境的状态
到这里,我们已经配置和启用了数据收集器,而我们也需要操作下收集集合。
数据收集器有四个系统收集集合:Disk Usage(磁盘使用)、Query Statistics(查询统计)、Server Activity(服务器活动)和Utility Information(实用工具信息)。
“Utility Information”收集集合被用于实用工具控制点属性,超出了本文的范围。在SQL Server 2014中,我们会发现另外另个收集集合:“表使用分析”和“存储过程使用分析”,它们都用户SQL Server 2014中的基于内存属性,也超出了本文的范围。
首先,我们需要在之前的脚本执行后,检查是否数据收集器在所有的实例上是启用的。
对于该任务,我们需要查询MSDB库中的“syscollector_config_store”表。查询语句像这样:
select * from msdb.dbo.syscollector_config_store where parameter_name='CollectorEnabled'
现在我们知道所有三个数据收集器启用了,我们想知道哪个收集集合被启用。
我们需要查询MSDB库中的“syscollector_collection_sets”表,来检查“is_running”列,并识别哪个收集集合正在运行。查询语句像这样:
select collection_Set_id,collection_Set_uid,name,is_running from msdb.dbo.syscollector_collection_sets
下一步是控制每个收集集合的配置。每个可以被配置为缓存或非缓存。非缓存收集集合立即上传信息到MDW数据库,而缓存收集集合存储信息在缓存目录,并以不同的调度计划上传。
问题是:配置是否正确?调度计划是否正确?
这些问题的答案只需要一个查询,你只需对之前的查询做一些修改:
select collection_set_id,a.name,is_running, case collection_mode when 1 then 'non-cached' when 0 then 'cached' end collection_mode, days_until_expiration, b.name Schedule_Name from msdb.dbo.syscollector_collection_sets a, msdb.dbo.sysschedules b where a.schedule_uid=b.schedule_uid
现在我们已经有了需要的信息,让我们理解配置,看看如何定制它。
我们可以使用两个存储过程来启用或禁用任意收集集合:
“sp_syscollector_start_collection_set”和“sp_syscollector_start_collection_set”,位于MSDB数据库。
我们只需要提供参数collection_set_id来执行这些存储过程,来启用或禁用任何收集集合,随着CMS的使用,我们可以只执行一次,而对所有的服务器操作。
集合模式直接与收集集合的调度计划有关。如果调度间隔非常小,秒级别,你需要选择缓存模式,然后以不同的调度计划收集和上传信息。
换句话说,如果调度间隔不是很小,你可以使用非缓存模式以相同的调度计划用于收集数据和上传数据到服务器。当调度间隔不是很小,没有必要两个调度计划。
“Schedule_name”列包含正被收集集合使用的调度计划(SQL代理调度计划)的名字,根据收集模式配置会有不同的意思。
如果“collection_mode”列是“non-cached”,调度计划用于收集信息并上传信息到MDW数据库。换句话说,如果“collection_mode”列是“cached”,调度计划只用于上传,而不收集。事实上,我们没有在之前的查询中看到缓存的收集集合的收集调度计划。
每个收集集合有些收集条目,而每个收集条目有它自己的调度计划配置(不是SQL代理调度计划)。当收集集合是非缓存的,配置被忽略,但当收集集合是缓存的,该收集条目的调度计划用于收集信息。
让我们检查下缓存收集集合的每个收集条目的调度计划:
select a.collection_set_id,b.name Collection_set, a.name Item, collection_item_id, frequency from msdb.dbo.syscollector_collection_items a, msdb.dbo.syscollector_collection_sets b where a.collection_set_id=b.collection_set_id and b.collection_mode=0 and b.is_running=1
“frequency”列以秒为单位。
就像该列名所描述的那样,“Days_until_expiration”包含保留在MDW数据库中的信息的天数。
一旦你理解了所有的配置选项,该决定是否需要修改。“days_until_expiration”、“frequency”和“schedule_name”之间的关系对MDW数据库的大小有直接的影响。你真的会使用所有的信息?你是否应该减少days_until_expiration?增加“frequency”?
大多数时候,减少“days_until_expiration”是一个好的选择。查询和服务器活动保留十四天、磁盘使用保留一年以上都太多了。
“frequency”列影响了服务器性能,但是如果你增加太多,该信息会失去意义;而关键点是:你实际上要使用什么?大多数会使用“Query Statistics”收集集合,例如,如果你增加“frequency”列,将不会修改。
你将会使用MSDB数据库中的sp_syscollector_update_collection_set存储过程来修改收集集合配置。
这里是存储过程的简单语法:
sp_syscollector_update_collection_set [ [ @collection_set_id = ] collection_set_id ] , [ [ @collection_mode = ] collection_mode ] , [ [ @days_until_expiration = ] days_until_expiration ] ,[ [ @schedule_uid = ] 'schedule_uid' ]
你可以使用该存储过程来修改收集模式,过期日期和调度计划。对于调度计划,你可以使用如下查询来识别哪些调度计划可以用:
select schedule_uid,name from msdb.dbo.sysschedules where name like 'collector%'
你可以创建自己的调度计划。这是一个简单的SQL Server代理调度计划,但本文中不会包含该选项的详细信息。
让我们看看一个示例,如何修改“query statistics”收集集合的配置:
use msdb exec sp_syscollector_update_collection_set @collection_set_id = 3 , @days_until_expiration = 7 ,@schedule_uid = '4B24F341-0D27-45EA-8596-EB6642DF37B1'
现在我们需要修改收集条目的频率。为此我们将会使用存储过程sp_syscollector_update_collection_item:
use msdb exec sp_syscollector_update_collection_item @collection_item_id = 5 , @frequency = 30
收集信息
有时你会强制收集信息,而不等待收集调度计划:
在初始化配置之后特别对,因为你需要强制收集以便于测试每一样。
有两个挑战:
我们需要对每个收集集合收集信息。
根据收集集合的配置执行收集的过程是不同的。
下面的示例脚本只对一个收集集合执行作业(collection_set_id=1):
declare @cmode int select @cmode=collection_mode from msdb.dbo.syscollector_collection_sets where collection_set_id=1 if @cmode=0 begin EXEC [msdb].[dbo].[sp_syscollector_upload_collection_set] @collection_set_id=1 end else begin EXEC [msdb].[dbo].[sp_syscollector_run_collection_set] @collection_set_id=1 end
我们可以对每个收集集合执行这个脚本,修改collection_set_id,或者创建一个新的脚本对所有活动收集集合执行该工作。让我们看看新的脚本:
declare @qtd int declare @cid int declare @cnt int declare @cmode int /* Number of active collection set's */ select @qtd=count(*) from msdb.dbo.syscollector_collection_sets where is_running=1 while @cnt <@qtd Begin select @cid=collection_set_id from msdb.dbo.syscollector_collection_sets where is_running=1 order by collection_set_id offset @cnt rows fetch next 1 rows only select @cmode=collection_mode from msdb.dbo.syscollector_collection_sets where collection_set_id=@cid if @cmode=0 begin EXEC [msdb].[dbo].[sp_syscollector_upload_collection_set] @collection_set_id=@cid end else begin EXEC [msdb].[dbo].[sp_syscollector_run_collection_set] @collection_set_id=@cid end select @cnt=@cnt +1 end;
使用offset/fetch,我们对所有活动(is_running=1)连接集合执行循环,检查“collection_mode”并执行正确的过程来做收集。每次你想手工收集信息时你可以通过CMS运行该脚本。你只需要检查数据收集器报表来查看结果。
数据收集器报表安装在MDW数据库。我们可以右击MDW数据库检查收集集合的报表。尽管报表只能通过SSMS界面使用,因为数据在数据库中,我们可以用多种方式来查询。
为了检查收集进程是否正在运行,我们需要查询MSDB数据中的syscollector_execution_log表。我们需要对每个收集集合找到最后的(最新的)日志状态。
查询如下:
use msdb select a.collection_Set_id,b.name, case status when 2 then 'failed' else 'OK' end status ,failure_message from syscollector_execution_log a, syscollector_collection_sets b where a.collection_set_id=b.collection_set_id and log_id in ( select max(log_id) from syscollector_execution_log where parent_log_id=0 group by collection_set_id )
你需要确保SQL Server代理正在运行,因为如果它没有运行,状态将不会显示问题。
这只是开始。有更多细节将会帮助创建一个更好的数据收集器环境。总结如下:
你应该根据需要创建定制的收集集合。你不仅可以收集服务器的数据库信息,而且也可以收集业务进程。一个示例:每个商店的总销售额。
SQL Profiler可以转换它的跟踪到数据收集器,创建定制收集集合来以从服务器获取信息。在SQL Profiler菜单,使用“File”->“Export”->“SQL Trace Definition”->“For SQL Trace Collection Set”
你需要控制MDW数据库的大小。检查mdw_purge_data作业的执行。如果数据库增长太多,而作业无法解决这个问题,你可以定制这个作业。
通常我推荐将复杂查询转换为存储过程或函数,但在本文中所有的查询用于CMS,因此在你的环境中创建存储过程和函数,你需要在所有的SQL Server实例上创建和管理。
限制只能在SSMS界面查看报表不好。Bill Ramos通过重新创建报表服务器的报表来解决了该问题,因此我们可以安装这些报表,从任何地方访问它们。他开发了一个用于查询哈希状态的服务器活动报表。你可以看看它的六个系列文章中的第一个:MDW概览用于数据收集器报表--MDW报表系列第一部分
没有创建查询统计的报表,Bill Ramos创建了一个用于查询哈希统计的报表,一个基于查询指纹属性定制的收集集合。你可以在这篇文章看到详细信息--SQL Server查询哈希统计--但对于查询哈希统计收集集合的下载链接坏了。通过研究和联系后我得到了文件,从本文开头可以获得。
总结
数据收集器和管理数据仓库提供了,收集工作数据库的行为的大量数据的方法,但是管理该进程是非常困难的。因为进程的配置是在每个被监控的数据库所在的服务器上完成。通过使用中央管理服务器,配置和控制数据收集器数以百计的SQL Server实例变得相对快捷和容易,因此对于大范围的服务器环境集中化处理信息。