SQL Server 使用的资源受到操作系统的调度,同时,SQL Server在内部实现了一套调度算法,用于管理从操作系统获取的资源,主要是对内存和CPU资源的调度。一个好的数据库系统,必定在内存中缓存足够多的信息,以减少从物理硬盘中读取数据的次数;如果内存是系统瓶颈,那么SQL Server一定会运行的非常慢。监控SQL Server的内存压力,需要从Widnows级别上,对内存使用的整体使用情况进行监控:从SQL Server级别上,监控SQL Server对内存资源的使用情况。
一,从Windows级别来监控内存资源的使用
操作系统能够调度的内存,有两个来源:物理内存和虚拟内存。物理内存是内存硬件提供的高速访问设备,虚拟内存是物理内存的扩展,操作系统开辟一块物理Disk空间,作为内存空间使用,用于存储缓存数据的文件,叫作缓存文件(Paging File),路径名是C:\pagefile.sys,默认是隐藏的。操作系统透明地使用Paging File来存储数据,Application是无法控制和感知数据是存储在物理内存还是在虚拟内存中,即,操作系统决定使用物理内存,或Paging file来存储缓存数据。一般,通过Performance Monitor来监控Windows级别的内存资源使用情况。
1,监控物理内存
常用的系统级别的内存计数器跟硬缺页中断有关:
- Memory:Page Faults/sec :每秒发生的Page Fault的数量,Page Fault包括Hard Fault 和 Soft Fault,Hard fault表示需要从Disk中读取数据页,Soft fault表示需要从Physical Memory中读取数据页,Soft Fault不会影响性能,由于Hard Fault需要访问Disk,会产生显著的延迟。
- Memory:Pages Input/sec:每秒发生的Hard Fault的数量,用于计算Hard Fault的百分比: Pages Input / Page Faults = % Hard Page Faults,如果百分比经常大于40%,说明系统需要经常访问Disk获取数据,在一定程度上说明系统存在内存压力。
- Memory:Pages/sec:每秒从Disk读取或写入Disk的Page数量,表示内存和Disk交互的Page的数量:将Page存储到Disk或从Disk读取数据到内存的Page的数量。
如下图,Page Faults/sec的数量,均值在6000/s左右,Pages Input/sec波动明显,时高时低,持续的时间很短,均值在50/s左右,两者的比例关系均值低于1%,低于40%,可以认为内存压力较小。Pages/sec 和 Pages Input/sec几乎完全重合,说明,操作系统当时在进行大量的物理读操作。
2,监控虚拟内存
操作系统会同时消耗物理内存和虚拟内存,虚拟内存计数器主要有两个:
- Paging File:% Usage 用于监控Paging file实例的使用比例
- Process: Paging File Bytes 用于监控虚拟内存的大小
存储在虚拟内存中的数据越多,说明物理内存数量和实际需求量的差距越大,比值 % Usage 仅仅作为参考值,如果长时间接近100%,那么系统很可能出现异常。
二,从SQL Server级别上,监控SQL Server对内存资源的使用情况
1,从Buffer Pool计数器监控服务器内存总体使用情况
由于Buffer Pool是SQL Server内存最活跃,使用最多的部分,所以也是最容易出现性能瓶颈的部分,计数值尤其重要:
- Lazy Writes/sec:被LazyWriter刷新的buffer数量,如果是脏页,那么将buffer写入到Disk,并将buffer空间标记为Free,如果不是脏页,那么该buffer空间也被标记为Free,LazyWriter的作用是维护一定数量的Free buffer,SQL Server使用Free buffer来加载新的数据页。
- Page Life Expectancy:PLE,数据页驻留在内存中的时间。如果SQL Server没有新的内存需求,或有空闲的内存来完成新的内存需求,那么Lazy Writer不会被处罚,Page会一直驻留在Buffer Pool中,那么Page Life Expectancy会维持在一个比较高的水平;如果Page Life总是高高低低,表明SQL Server存在内存压力。PLE的参考数值是:Max Server Memory/4GB*300s,如果PLE值长期低于参考值,内存可能存在瓶颈。
- Page Reads/sec:每秒从Disk读取的数据页数,即物理读的次数,如果用户访问的数据都缓存在内存中,那么SQL Server不需要从物理Disk上读取页面。由于物理IO的开销大,Page Reads操作一定会影响SQL Server的性能。
- Free list stalls/sec:等待一个Free Page的请求数量,SQL Server申请从Disk加载一个Page到内存中,必须在内存中分配一个Buffer,Buffer Manager负责维护Free Buffer List,如果Free List没有任何Free Buffer,那么请求必须等待,直到有空闲的Buffer使用,才能将Disk中的Page加载到内存中。
根据图表数据分析,SQL Server执行大量的物理读操作,导致PLE大幅降低;从Free List Stall和 Lazy Write的测量值推断,SQL Server内存压力较小:
- PLE:大幅度降低,从50Ks降低到均值2Ks左右,说明内存数据页被大量替换;
- Free List Stalls/sec: 波动明显,总体数值很小,说明系统中的Free Buffer能够满足SQL Server的需求;
- Lazy Write/sec:均值在4/sec,比较小;
- Page Reads/sec:均值在4000/sec,说明SQL Server在进行大量的物理读操作
BCHR(Buffer cache hit ratio)表示:SQL Server 直接从内存中读取数据的百分比,跟预读有很大的关系。一次命中意味着在SQL Server读取数据时,数据存在于内存中,跟数据驻留在内存中的时间长短,以及内存是否有压力关系不大,仅供参考。
逻辑读是指直接从内存中读取数据,物理读是指从物理Disk文件中加载数据到内存,从SQL Server角度来看,BCHR=逻辑读/(逻辑读+物理读)。
如果数据缓存在内存中,那么SQL Server从内存中直接读取数据,而不需要从物理Disk加载到内存。物理Disk能够执行预读操作,操作系统将物理Disk上的数据预先加载到内存中,在SQL Server进程访问数据时,该数据已经存在于内存中了。虽然SQL Server申请了物理读操作,但是,BCHR的测量值没有体现物理读操作,这是因为,在SQL Server读取数据时,数据是存在于内存中的,SQL Server执行的是逻辑读操作。
推荐阅读《Great SQL Server Debates: Buffer Cache Hit Ratio》:
BCHR only responds to significant memory pressure in conjunction with I/O subsystem pressure, or possibly fragmentation i.e. under conditions that impedes page read-ahead to the point that SQL Server becomes much less effective at populating the data cache with the required pages, before the query processor actually requires them for use.
2,从Memory Manager计数器监控服务器内存总体使用情况
在一个非常繁忙的系统中,Lock内存和授予内存是常用的计数器:
- Total Server Memory (KB):SQL Server当前使用的内存总量
- Target Server Memory (KB):SQL Server能够使用的内存总量
- Lock Memory (KB):SQL Server用于锁的内存总量
- Grant Workspace Memory (KB):授予内存,SQL Server用于执行hash,排序和创建Index操作而消耗的内存总量
- Memory Grants Pending (KB):等待内存授予的进程数量,如果进程不能获得指定数量的内存,那么进程将不会开始执行
分析图表,除了Grant Workspace Memory 有变化之外,其余4个计数值都没有变化,说明SQL Server执行的操作需要授予内存,而Memory Grants Pending 计数值很小,几乎为0,说明SQL Server 不存在内存压力。
结论:内存是数据库系统最重要的资源,操作系统和SQL Server对其的管理比较复杂,根据以上计数器的测量值,基本上能够推断出SQL Server是否存在内存压力,可以结合其他测量值进行佐证,例如,Committed Memory,Stolen Memory,Working Set,Paged Pool,Nonpaged Pool等,这里就不展开了。
拓展阅读:
Process:Page File Bytes is the current amount of virtual memory, in bytes, that this process has reserved for use in the paging file(s). Paging files are used to store pages of memory used by the process that are not contained in other files. Paging files are shared by all processes, and the lack of space in paging files can prevent other processes from allocating memory. If there is no paging file, this counter reflects the current amount of virtual memory that the process has reserved for use in physical memor
参考doc:
Windows Performance Counters Explained
Buffer cache hit ratio性能计数器真的可以作为内存瓶颈的判断指标吗?
Great SQL Server Debates: Buffer Cache Hit Ratio
SQL Server memory performance metrics – Part 1 – Memory pages/sec and Memory page faults/sec