问题:

  我们可能经常会遇到SQLServer数据库频繁关闭的情况。在分析了内存和CPU使用情况后,我们需要继续调查根源是否在I/O。我们应该如何识别SQLServer是否有I/O相关的瓶颈?

  解决:

  当数据页经常从缓冲池中移进移出的时候,I/O子系统会成为SQLServer性能问题的关键因素之一。事务日志和tempdb同样也会产生重大的I/O压力。因此,你必须确保你的I/O子系统能按照预期运行。否则你将会成为响应时间增长和频繁超时的受害者。在这篇文章中,将描述如何使用内置工具识别I/O相关瓶颈,并提供一些磁盘配置的方法:

  性能计数器(Performance Monitor):

  可以使用性能计数器来检查I/O子系统的负荷。下面的计数器可用于检查磁盘性能:

  PhysicalDisk Object:Avg.DiskQueue Length:计算从物理磁盘中的平均读和写的请求队列。过高的值代表磁盘操作处于等待状态。当这个值在SQLServer峰值时长期超过2,证明需要注意了。如果有多个硬盘,需要把这些数值除以2。比如,有4个硬盘,且队列为10,那么平均值是10/4=2.5,虽然也证明需要关注,但不能使用10这个值。

  Avg.Disk Sec/Read和Avg.Disk Sec/Write:显示从磁盘读或者写入磁盘的平均时间。10ms内是很好的表现,20以下还算能接受。高于此值证明存在问题。

  Physical Disk:%Disk Time:在磁盘忙于读或者写请求的时候持续时间的比率。根据拇指定律,此值应该小于50%。

  Disk Reads/Sec和Disk Writes/Sec计数器显示出在磁盘中读写操作的速率。这两个值应该小于磁盘能力的85%。当超过此值,磁盘的访问时间将以指数方式增长。

  可以通过以下方式来计算逐渐增长的负载的能力。一种方法是使用SQLIO。你应该找到吞吐量比较稳定,但缓慢增长。

  可以使用以下公式来计算RAID配置:

  Raid 0: I/O per disk = (reads + writes) / number ofdisks
  Raid 1: I/O per disk = [reads + (writes*2)] / 2
  Raid 5: I/O per disk = [reads + (writes*4)] / number of disks
  Raid 10: I/O per disk = [reads + (writes*2)] / number of disks

  比如:对于RAID 1,如果得到下面的计数器:

  Disk Reads/sec = 90

  Disk Writes/sec =75

  根据公式:[reads + (writes*2)] / 2 or [90 + (75*2)] / 2 = 120I/Os每个磁盘。

  动态管理视图(DMVs):

  有很多游泳的DMVs可以用于检查I/O瓶颈:

  当一个页面被用于读或者写访问且页面在缓冲池中不存在或不可用时,会引发一个I/O闩锁等待(I/O latch),它会在PAGEIOLATCH_EX/PAGEIOLATCH_SH(具体根据请求类型而定)。这些等待表明一个I/O瓶颈。可以使用sys.dm_os_wait_stats找到闩锁等待的信息。如果你保存了SQLServer正常运行下的waiting_task_counts和wait_time_ms值,并且于此次的值做对比,可以识别出I/O问题:


select *

fromsys.dm_os_wait_stats 

where wait_type like'PAGEIOLATCH%'

order by wait_typeasc