问题
我们可能经常会遇到SQLServer数据库频繁关闭的情况在分析了内存和CPU使用情况后我们需要继续调查根源是否在I/O我们应该如何识别SQLServer是否有I/O相关的瓶颈?
解决
当数据页经常从缓沖池中移进移出的时候I/O子系统就会成为SQLServer性能问题的关键因素之一事务日志和tempdb同样也会产生重大的I/O压力因此你必须确保你的I/O子系统能按照预期运行否则你将会成为响应时间增长和频繁超时的受害者在这篇文章中将描述如何使用内置工具识别I/O相关瓶颈并提供一些磁盘配置的方法
性能计数器(Performance Monitor)
可以使用性能计数器来检查I/O子系统的负荷下面的计数器可用于检查磁盘性能
PhysicalDisk Object:AvgDiskQueue Length:计算从物理磁盘中的平均读和写的请求队列过高的值代表磁盘操作处于等待状态当这个值在SQLServer峰值时长期超过证明需要注意了如果有多个硬盘就需要把这些数值除以比如有个硬盘且队列为那么平均值就是/=虽然也证明需要关注但不能使用这个值
AvgDisk Sec/Read和AvgDisk Sec/Write:显示从磁盘读或者写入磁盘的平均时间ms内是很好的表现以下还算能接受高于此值证明存在问题
Physical Disk:%Disk Time:在磁盘忙于读或者写请求的时候持续时间的比率根据拇指定律此值应该小于%
Disk Reads/Sec和Disk Writes/Sec计数器显示出在磁盘中读写操作的速率这两个值应该小于磁盘能力的%当超过此值磁盘的访问时间将以指数方式增长
可以通过以下方式来计算逐渐增长的负载的能力一种方法是使用SQLIO你应该找到吞吐量比较稳定但缓慢增长
可以使用以下公式来计算RAID配置
Raid : I/O per disk = (reads + writes) / number ofdisks
Raid : I/O per disk = [reads + (writes*)] /
Raid : I/O per disk = [reads + (writes*)] / number of disks
Raid : I/O per disk = [reads + (writes*)] / number of disks
比如对于RAID 如果得到下面的计数器
Disk Reads/sec =
Disk Writes/sec =
根据公式[reads + (writes*)] / or [ + (*)] / = I/Os每个磁盘
动态管理视图(DMVs)
有很多游泳的DMVs可以用于检查I/O瓶颈
当一个页面被用于读或者写访问且页面在缓沖池中不存在或不可用时会引发一个I/O闩锁等待(I/O latch)它会在PAGEIOLATCH_EX/PAGEIOLATCH_SH(具体根据请求类型而定)这些等待表明一个I/O瓶颈可以使用sysdm_os_wait_stats找到闩锁等待的信息如果你保存了SQLServer正常运行下的waiting_task_counts和wait_time_ms值并且于此次的值做对比可以识别出I/O问题
select *
fromsysdm_os_wait_stats
where wait_type likePAGEIOLATCH%
order by wait_typeasc
挂起的I/O请求可以在下面查询中查到并且用于识别那个磁盘负责的这个瓶颈
select database_id
file_id
io_stall
io_pending_ms_ticks
scheduler_address
from sysdm_io_virtual_file_stats(NULL NULL) iovfs
sysdm_io_pending_io_requests as iopior
where iovfsfile_handle = iopiorio_handle
磁盘碎片(Disk Fragmentation)
建议你检查磁盘碎片和配置用于SQLServer实例的磁盘在NTFS文件系统中的碎片会产生严重的性能影响磁盘需要经常整理碎片并且指定整理碎片计划研究表明一些情况下SAN在整理碎片后性能更差因此SAN必须根据实际情况对待
NTFS上的索引碎片同样能引起高I/O好用但是这和在SANs中的效果是不一样的
磁盘配置/最佳实践
常规情况你应该把日志文件和数据文件分开存放以获得更好的性能对于重负载的数据文件(包括tempdb)的I/O特性是随机读取对于日志文件是顺序访问的除非事务需要回滚
对于内置磁盘仅仅可以用于数据库日志文件因为它们对顺序I/O有很好的性能但是对随机I/O性能低下
数据库的数据和日志文件应该放在对应专用的磁盘中确保良好的性能建议日志文件放在两个内置磁盘并配置为RAID 数据文件驻留在仅用于给SQLServer访问的SAN系统中并只被查询和报表控制特殊访问应该被禁止
写缓沖在可能的情况下应该被允许并保证断电也能使用
为了尽可能保证对于OLTP系统的I/O瓶颈影响最小化不应该把OLAP和OLTP环境混合并且保证你的代码优化及有合适的索引来避免不必要的I/O