如何通过sql server远程收集windows性能计数器

Posted

技术标签:

【中文标题】如何通过sql server远程收集windows性能计数器【英文标题】:How to remotely collect windows performance counters through sql server 【发布时间】:2012-01-13 16:31:19 【问题描述】:

我希望我的应用程序(已部署到数千个位置)能够监控自己的环境,尤其是 sql server 框。当 SQL Server 在本地时,这很容易做到,因为我可以使用 System.Diagnostics 库并通过它收集 Windows 性能计数器。当 SQL 服务器是远程的但是我有一个问题,因为我不能保证我的 c# 应用程序(在这种情况下是一个 Windows 服务)可以访问远程 sql 服务器机器,除了我知道它可以访问 SQL Server 的事实。

关于如何通过 SQL 从该机器收集 Windows 性能计数器的任何想法?

我想到的一种方法是使用 SQL CLR,但它似乎需要 UNSAFE 访问,我很确定我不想要。

谢谢

【问题讨论】:

为了澄清,您希望您的数据库能够收集运行您的应用程序的机器的性能计数器统计信息,对吗? MS-SQL CLR 有一个安全模式,我相信你可以根据你的要求使用它 - 请参阅 msdn.microsoft.com/en-us/library/ms345101.aspx @M.Babcock 我希望我的应用程序或 SQL Server 收集运行 SQL Server 的机器的性能计数器统计信息。 @ron tornambe 我知道它具有安全模式,但 System.performance 计数器似乎需要雇用特权而不是根据我的测试。我相信这是因为通过 System.Diagnostics 获取性能计数器需要注册表访问权限。我不知道 WMI 是否更好,或者是否需要相同级别的访问权限 @Mark - 从您的 C# 应用程序中,您可以调用 PerformanceCounter 构造函数的 this 重载以连接到远程计数器。诀窍在于确定它需要从哪台 PC 收集统计信息并保证它具有正确的权限。 【参考方案1】:

按照您在 cmets 中的说明进行标记

“我不能保证我将拥有适当的特权”

您必须在安装程序中编写某种功能,以确保您拥有远程性能的适当权限(可能没有管理员设置权限就无法安装)。计数器访问。

您没有准确说明您要监控的内容,但是,我建议您使用内置的 SQL Server 动态管理视图 (DMV)

MSDNGood Articles VideosVery Useful Examples

这些在最近的 SQL Server 版本中变得非常强大,并允许您监控您将在 perfmon 中使用的大多数统计信息(CPU、IO、MEMORY 等等)。也许粒度不如 perfmon,但通常我发现它们比现在的 perfmon 更有用,可以快速获取相关数据。只要您的连接字符串用户具有管理员权限,您就不必担心服务器权限。而且这个功能已经内置在 sql-server 中了 看看看看。


编辑 ... @Mark 以下是我用来获取数据库 IO 时间的一些 DMV 脚本,虽然不如 PerfMon 精确,但它允许您专注于特定的数据库文件。

查看“dm_io_virtual_file_stats”DMV

select
read_stall_ms = case when num_of_reads = 0 then 0 else (io_stall_read_ms/num_of_reads) end,
write_stall_ms = case when io_stall_write_ms = 0 then 0 else (io_stall_write_ms/num_of_writes) end,
total_stall_ms = case when (num_of_reads = 0 and num_of_writes = 0) then 0 else (io_stall/(num_of_reads + num_of_writes)) end,
db = db_name(vfs.database_id),
mf.physical_name,
vfs.*
from sys.dm_io_virtual_file_stats(null, null) as vfs
join sys.master_files as mf on vfs.database_id = mf.database_id and vfs.file_id = mf.file_id
order by total_stall_ms desc

select m.database_id,
db_name(m.database_id) as database_name,
m.file_id,
m.name as file_name, 
m.physical_name, 
m.type_desc,
fs.num_of_reads, 
fs.num_of_bytes_read, 
fs.io_stall_read_ms, 
fs.num_of_writes, 
fs.num_of_bytes_written, 
fs.io_stall_write_ms
from sys.dm_io_virtual_file_stats(NULL, NULL) fs
join sys.master_files m on fs.database_id = m.database_id and fs.file_id = m.file_id

有点花哨的东西......

select db_name(d.database_id) as database_name, 
quotename(object_schema_name(d.object_id, d.database_id)) + N'.' + quotename(object_name(d.object_id, d.database_id)) as object_name,
d.database_id,
d.object_id,
d.page_io_latch_wait_count,
d.page_io_latch_wait_in_ms,
d.range_scans,
d.index_lookups,
case when mid.database_id is null then 'N' else 'Y' end as missing_index_identified
from (select 
        database_id,
        object_id,
        row_number() over (partition by database_id order by sum(page_io_latch_wait_in_ms) desc) as row_number,
        sum(page_io_latch_wait_count) as page_io_latch_wait_count,
        sum(page_io_latch_wait_in_ms) as page_io_latch_wait_in_ms,
        sum(range_scan_count) as range_scans,
        sum(singleton_lookup_count) as index_lookups
    from sys.dm_db_index_operational_stats(NULL, NULL, NULL, NULL)
    where page_io_latch_wait_count > 0
    group by database_id, object_id ) as d
left join (select distinct database_id, object_id from sys.dm_db_missing_index_details) as mid on mid.database_id = d.database_id and mid.object_id = d.object_id

【讨论】:

我认为这是最好的方法。不幸的是,我正在尝试收集我在 DMV 中找不到的物理磁盘 - Ave Disk sec / read。 @Mark 查看 I/O 的“dm_io_virtual_file_stats”,还有一些其他的 DMV 用于 IO,请参阅编辑示例【参考方案2】:

如果您签署您的程序集,您可以从程序集创建登录,授予它运行不安全程序集的服务器级权限,并从 dll 创建程序集。这允许您运行不安全的程序集,而不必打开数据库上的可信赖标志。

【讨论】:

听起来很有希望,但“从程序集创建登录”是什么意思? 从可执行文件创建非对称密钥 [ArbitraryKeyName] = 'path to dll';从非对称密钥 [ArbitraryKeyName] 创建登录 [ArbitraryLoginName]【参考方案3】:

我认为您需要比自卷 SQL CLR 更强大的东西。 MS 有一个专门用于此的工具,称为 SCOM。

我在 50 台服务器的环境中取得了非常好的结果。

您使用内置的时间点报告、数据仓库和警报收集大量可配置数据。

good wikipedia article

technet

【讨论】:

如问题中所述,此应用程序已部署到数千个位置。我真的不可能将 SCOM 部署到数千个位置,只是为了从一台机器上收集一些性能计数器。

以上是关于如何通过sql server远程收集windows性能计数器的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server2008如何连接远程的服务器

如何通过 Jetbrains DataGrip 连接到远程 MS SQL Server 数据库?

如何配置sqlserver 以允许远程连接

如何破解windows server 2008r2远程连接数2个的限制

如何在连接到局域网的其他电脑上使用SQL Server数据库运行桌面应用程序?

SQL Server 2012允许远程连接(Windows Server 2016)