来自 sql server 的高磁盘 I/O 还是高磁盘 I/O 会减慢 sql server?

Edg*_*gey 19 sql-server perfmon

我一直在与 DBA 和几个硬件人员争论我们 SQL 服务器上的性能问题。通常一切都很好,但是在过去的几周里,我们在 sql server 中遇到了巨大的滞后峰值。很明显,SQL Server 正在等待磁盘 I/O。但是我一直被告知这是因为 SQL Server 要求异常高的 I/O。事实并非如此。从运行中可以看出没有任何异常,所有DBA关心的只是导致阻塞的原因等等,这是无用的。例如,我们看到备份的主要内容是对 ASPState 数据库的操作,我们使用它来管理 Web 服务器上的 ASP 会话状态。这些操作通常不会出现在 Sp_who2 活动结果上,因为它们发生得如此之快。数据库处于简单恢复模式,日志记录很少。然而,在这些延迟高峰期间,我们可以看到数据库上的大量选择和更新操作被阻塞或等待。我确信正在发生的事情是某人或某项工作正在运行导致用于该数据库日志和数据文件的 RAID 阵列上大量磁盘使用的东西。问题是要证明这一点,因为没有人愿意承认他们正在做一些正在扼杀我们网站的事情。

我的问题是什么性能计数器或我可以记录的任何内容将有助于显示 SQL Server 正在等待 I/O,但不是因为它要求比正常情况更多,而是因为磁盘忙于响应来自 sql server 的请求像往常一样快吗?

Rem*_*anu 20

查看以下性能计数器:

驱动大量 IO 请求的 SQL Server 将通过大量扫描、页面查找和页面读取的增加以及高页面 IO 闩锁等待得到证实。值得尝试查看sys.dm_exec_query_stats具有高物理读取计数的条目。他们可以迅速查明罪魁祸首。

一般来说,将问题视为性能故障排除问题,遵循等待和队列之类的方法是正确的方法。您的 DBA 似乎在做正确的事情,所以您应该听他的。


Dan*_*SQL 13

开始使用 Glenn Berry 的诊断查询和 Adam Machanic 的SP_Whoisactive找出真正发生的事情。

首先通过运行这个查询来查看哪些数据库文件的 IO 瓶颈最多(Query by Glenn Berry)

SELECT  DB_NAME(fs.database_id) AS [Database Name] ,
        mf.physical_name ,
        io_stall_read_ms ,
        num_of_reads ,
        CAST(io_stall_read_ms / ( 1.0 + num_of_reads ) AS NUMERIC(10, 1)) AS [avg_read_stall_ms] ,
        io_stall_write_ms ,
        num_of_writes ,
        CAST(io_stall_write_ms / ( 1.0 + num_of_writes ) AS NUMERIC(10, 1)) AS [avg_write_stall_ms] ,
        io_stall_read_ms + io_stall_write_ms AS [io_stalls] ,
        num_of_reads + num_of_writes AS [total_io] ,
        CAST(( io_stall_read_ms + io_stall_write_ms ) / ( 1.0 + num_of_reads
                                                          + num_of_writes ) AS NUMERIC(10,
                                                              1)) AS [avg_io_stall_ms]
FROM    sys.dm_io_virtual_file_stats(NULL, NULL) AS fs
        INNER JOIN sys.master_files AS mf WITH ( NOLOCK ) ON fs.database_id = mf.database_id
                                                             AND fs.[file_id] = mf.[file_id]
ORDER BY avg_io_stall_ms DESC
OPTION  ( RECOMPILE );
Run Code Online (Sandbox Code Playgroud)

然后运行此查询以查看您的服务器正在等待的前十个事件(由Jonathan Kehayias查询)。您还可以从 Glenn Berry 诊断查询中找到类似的查询。

SELECT TOP 10
        wait_type ,
        max_wait_time_ms wait_time_ms ,
        signal_wait_time_ms ,
        wait_time_ms - signal_wait_time_ms AS resource_wait_time_ms ,
        100.0 * wait_time_ms / SUM(wait_time_ms) OVER ( ) AS percent_total_waits ,
        100.0 * signal_wait_time_ms / SUM(signal_wait_time_ms) OVER ( ) AS percent_total_signal_waits ,
        100.0 * ( wait_time_ms - signal_wait_time_ms )
        / SUM(wait_time_ms) OVER ( ) AS percent_total_resource_waits
FROM    sys.dm_os_wait_stats
WHERE   wait_time_ms > 0 -- remove zero wait_time
        AND wait_type NOT IN -- filter out additional irrelevant waits
( 'SLEEP_TASK', 'BROKER_TASK_STOP', 'BROKER_TO_FLUSH', 'SQLTRACE_BUFFER_FLUSH',
  'CLR_AUTO_EVENT', 'CLR_MANUAL_EVENT', 'LAZYWRITER_SLEEP', 'SLEEP_SYSTEMTASK',
  'SLEEP_BPOOL_FLUSH', 'BROKER_EVENTHANDLER', 'XE_DISPATCHER_WAIT',
  'FT_IFTSHC_MUTEX', 'CHECKPOINT_QUEUE', 'FT_IFTS_SCHEDULER_IDLE_WAIT',
  'BROKER_TRANSMITTER', 'FT_IFTSHC_MUTEX', 'KSOURCE_WAKEUP',
  'LAZYWRITER_SLEEP', 'LOGMGR_QUEUE', 'ONDEMAND_TASK_QUEUE',
  'REQUEST_FOR_DEADLOCK_SEARCH', 'XE_TIMER_EVENT', 'BAD_PAGE_PROCESS',
  'DBMIRROR_EVENTS_QUEUE', 'BROKER_RECEIVE_WAITFOR',
  'PREEMPTIVE_OS_GETPROCADDRESS', 'PREEMPTIVE_OS_AUTHENTICATIONOPS', 'WAITFOR',
  'DISPATCHER_QUEUE_SEMAPHORE', 'XE_DISPATCHER_JOIN', 'RESOURCE_QUEUE' )
ORDER BY wait_time_ms DESC
Run Code Online (Sandbox Code Playgroud)

一旦掌握了这些信息,解决问题就会容易得多。