现在很多用户被数据库的慢的问题所困扰,又苦于花钱请一个专业的DBA成本太高。软件维护人员对数据库的了解又不是那么深入,所以导致问题迟迟不能解决,或只能暂时解决不能得到根治。开发人员解决数据问题基本又是搜遍百度各种方法尝试个遍,可能错过诊断问题的最佳时机又可能尝试一堆方法最后无奈放弃。
怎么样让琐事缠身的程序维护人员,用最快的方式解决数据库出现的问题?怎么让我们程序员的痛苦降低到最小...每天喝喝茶水,看看新闻平安度过一天呢?本系列重要通过Expert for sqlserver 工具讲解下数据库遇到的各种问题的表象及导致这样问题的根本原因,让定位问题更准确,解决问题思路更清晰!!
数据库的性能好坏,对于最终用户来说表现为点击的操作是否能够快速响应,那么反应到数据库上就是语句执行时间是否够短!
对用运维人员数据库性能的表现,简单可能看成CPU 、内存、磁盘三巨头指标是否正常,前面讲述了CPU和内存的基本诊断,为了方便阅读给出系列文章的导读链接:
SQL SERVER全面优化-------Expert for SQL Server 诊断系列
本篇我们就讲述最后的一位巨头,看看磁盘能够看出哪些问题!
废话不多说,直接开整-----------------------------------------------------------------------------------------
磁盘也许对部分软件运维人员来说,这东西不归我管!爱咋咋地,速度慢就换SSD,坏了就再买!但是用在数据库上的磁盘你怎么能判断出是,磁盘的问题?不是你数据库其他问题导致的?磁盘坏了...一般的维护人员就哭了。
磁盘配置的建议
这里的配置建议主要针对数据库的磁盘使用,首先我们先明确下物理磁盘和逻辑磁盘的概念。
物理硬盘是硬件实体,即安装在电脑机箱内的硬盘; 逻辑硬盘是指人为在物理上划出分区以方便存取,管理里面的文件。
注:当你感觉到磁盘有压力,并且想用另一块磁盘帮助分担这个压力时,你需要添加的是物理磁盘而不是逻辑磁盘。
SQL SERVER中主要存储在磁盘,并且主要影响你系统的文件主要有:数据文件、日志文件、tempDB数据文件(tempDB日志可以忽略),很多用户的一台服务器上运行这多个数据库或多实例,那么针对你的现有数据库规划好磁盘分配是第一课!
规划磁盘分配的好处:假设你有两个数据库,业务操作都很繁忙,且读/写量都很大对磁盘的压力都很大,那么你自然会想到把他们分散到不同的磁盘上,这样每个库针对自己的磁盘读/写,不会互相影响且压力相当于原来的1/2,从而可以提升磁盘操作的响应时间。
数据库磁盘该怎么划分? 不同系统不同环境可能都不相同,下面给出一些简单建议:
- 按照文件类型划分:数据文件、日志文件、tempDB文件、备份文件,分别放在一个物理磁盘(3块物理磁盘)
- 按照数据库划分:不同的业务数据库(压力大的)分别放在一个物理磁盘,tempDB和备份文件各一个物理磁盘。
上面的两种分法是基本的划分方式,但是根据系统压力系统配置,均有不同情况。
当你的数据库压力较小,或磁盘资源紧张可以做适当的合并。当你的数据库特别大,并且有多个文件组,也可以选择把文件组更进一步细分。
类似于做了分区表,不同分区放在不同磁盘上,当需要多个分区数据时,可以利用IO并行提升效率。
如何区分你的磁盘是物理盘还是逻辑盘?
此例中C:H:是同一物理盘,Y:G:是同一物理盘,Y: 和 Z:都是单分区的物理盘。这次中共有4个物理磁盘
此例中每个都是一个单独的物理磁盘
注:磁盘信息可以通过系统信息(运行-msinfo32)或通过性能计数器等等手段查看。
下面看一个文件划分的例子: (例子使用上面C:D:E:F:J都是单独物理磁盘)
tempDB放在F盘
数据文件(.mdf)放在D盘,日志文件(.ldf)放在E盘
磁盘压力的诊断和分析
磁盘的压力分析,主要使用下面几个性能计数器 (针对单独的物理盘,每个物理磁盘都会有一组):
- Avg. Disk Read Queue Length 读队列(越小越好,理想值 2 以下,队列越高说明一个操作的响应时间越长)
- Avg. Disk Write Queue Length 写队列(越小越好,理想值 2 以下,队列越高说明一个操作的响应时间越长)
- Avg. Disk sec/Read
- Avg. Disk sec/Write
- Disk Read Bytes/sec
- Disk Write Bytes/sec
注:常规判断系统磁盘压力,通过读写队列即可判断,后面4个主要用于磁盘是否自身性能存在问题,本文不介绍。
首先有哪些情况会对磁盘造成压力?
- 内存不足导致需要频繁和磁盘交互 (一般为主因)
- 经常有大量冷数据需要从磁盘读取,或经常有大批量脏页一次写入(checkpoint触发)
- 磁盘读写速度,不能满足业务需要
为什么内存不足会导致磁盘压力大?
上一篇介绍了,内存这三个计数器是如何联动的?
Page life expectancy 不被使用的页在缓存中停留的秒数,如果低说明内存压力
Page Reads/sec 所要读的数据不在内存中需要物理读取
Lazy writes/sec 内存压力时成批的刷新老化缓冲区
磁盘的读写计数器:Avg. Disk Write Queue Length和Avg. Disk Read Queue Length和内存计数器很大程度上也是联动的!
当一个操作需要大量读取数据,且数据页不在缓存中 ——》 那么需要大量从磁盘读取冷数据放入缓存(Page Reads/sec 升高,Avg. Disk Read Queue Length升高) ——》缓存有明显压力的时候Lazy writes/sec就会触发(Lazy writes/sec升高),大批量的将老化的数据或缓存计划等刷出缓存 ——》数据被清出缓存(有脏页需要写入磁盘Avg. Disk Write Queue Length),那么页生命周期就会下降(Page life expectancy)
借用上一篇 Expert 诊断优化系列------------------内存不够用么? 三小时一次内存的例子,我们看看磁盘是什么样的表现
这内规律波动,内存压力很有规律,内存压力不过多介绍请参见上一篇。我们看看磁盘对应时间点的计数器是什么样子的? 你能想想到么?
是不是规律很强?这个例子展示了磁盘压力和内存的联动,也说明当你看到磁盘队列很高的时候,不要轻易定位磁盘的问题,先看看当前系统内存是怎么样的状态吧。
借助上一篇第二个,内存严重不足的例子:
我们来看看这么大内存的压力下,磁盘是什么状态,我想已经不用我说过多了。
高能预警:队列高可能,不那么直观的说明啥,下面我们来看一下这么高队列下的响应时间。每次和磁盘交互就要有1秒以上的磁盘响应时间(正常几毫秒),那么一个语句多次交互会是什么样的效果?
----------------------------------------------------------------------------------
至此我们了解到了,系统磁盘队列高的根本原因是由于内存不足导致的,那么我们抛开内存压力不谈,遇到上面的情况我们怎么缓解磁盘压力呢???
那就是前面提到的用多块磁盘分担这个压力或选用速度更快的。
看一下这个系统的磁盘及数据库文件分布
可以看到这个服务器只配置了一块物理磁盘
数据库1
数据库2
tempDB
2个业务频繁的大数据库,数据文件、日志文件和系统tempDB都在同一个磁盘上!
如果有其他物理磁盘可以分摊压力,读写队列会有降低,读写响应时间也会大幅缩短,但我们不能忽略根本原因是内存的超大压力!
最佳的优化效果,当然即做内存做优化(请参见上一篇 Expert 诊断优化系列------------------内存不够用么? ) 又按照最佳的实践把文件分散到多个磁盘分担压力。
-----------------------------------------------------------------------------------------------------
总结:现在硬件成本越来越低,很多用户都采用SSD或高级存储等,直接以提升硬件的方式对系统做出优化。
但本文主要介绍了磁盘压力的主因是内存不足引起的,内存不足又很大程度是语句写的太差,或明显缺少索引导致。
不要让一个很简单调优就能解决的问题,升级为要花高价换硬件。
不能否认提升硬件效果肯定会有,但是找出系统真正的原因,对症下药更为重要。
----------------------------------------------------------------------------------------------------
注:此文章为原创,欢迎转载,请在文章页面明显位置给出此文链接!
若您觉得这篇文章还不错请点击下右下角的推荐,非常感谢!
引用高大侠的一句话 :“拒绝SQL Server背锅,从我做起!”
为了方便阅读给出系列文章的导读链接: