SQL Server On Linux(16)—— SQL Server On Linux性能(2)——内置特性(2)——内存和Cache管理

本人新书上市,请多多关照:《SQL Server On Linux运维实战 2017版从入门到精通》

在这里插入图片描述

不管是关系数据库、NoSQL还是NewSQL,都是内存消耗型产品,所以内存的使用和管理都非常重要。本章将介绍一下内存和cache的管理

简介

  非常非常多的人问过我或者在其他地方提过,为什么SQL Server这么烂,有多少内存吃多少?其实这是一个很荒唐的论断。数据库本身就是资源密集型的软件,对I/O、CPU、内存的要求都是非常多,如果你有1T的内存,然后里面只有10G的库,你看看不出软硬件bug的话,会不会有多少吃多少?
  这部分不想多说了,说点正事,SQL Server的内存管理其实还是非常完善,不然作为不开源的产品也无法存活到现在,它对数据页的缓存(buffer)和缓冲(cache)T-SQL语句及其执行计划的都有很成熟和稳定的管理。内存的使用通过一个memory clerks的系统来跟踪。
  另外一个SQL Server的强项在于动态内存管理。它基于内存的需求量进行内存占用(memory footprint)的扩展和收缩。在Linux上的SQL Server,安装后并且还未使用时,就会消耗掉大概600MB的内存。当新建数据库,载入数据并运行起来时,内存就会不停增长直到配置限制。SQL Server On Linux在内存方面的配置有两个,前面文章已经提到过,稍后也会再介绍一下。
  在SQL Server引擎中,消耗内存最大的是caches,粗略分为Buffer pool和Plan cache。Buffer Pool通常简称buffer,是缓存数据库数据、索引和系统页的地方,数据库越大(实际大小不是预分配大小),buffer的量也越大。但是SQL Server会在运行时根据实际容量和内存需求进行buffer中数据的清理和重新加载。plan cache和buffer相对独立,它用于缓存查询(包含增删改)的执行计划,以便后续重用。但是并非所有的查询都会被缓存起来。有兴趣深入研究的读者可以看一下官方文档:查询处理体系结构指南

演示

  首先连上实验环境,使用linux的top指令看一下当前服务器的资源情况,关注RES列,可以看到第一次的值是1.2g
在这里插入图片描述
  然后使用systemctl restart mssql-server 重启SQL Server服务并再次使用top来检查,本机结果如下图,RES为1.0G
在这里插入图片描述
  接下来使用下面的T-SQL查看SQL Server引擎占了多少内存:

SELECT counter_name, cntr_value 
FROM sys.dm_os_performance_counters
WHERE object_name = 'SQLServer:Memory Manager'
AND counter_name IN ('Database Cache Memory (KB)', 'Total Server Memory 
(KB)', 'Target Server Memory (KB)')
GO

  这是本机结果:可以看到
在这里插入图片描述

  SQL Server内部有一个dmv:sys.dm_os_performance_counters,用于查询SQL Server引擎的特定性能统计信息。在Windows上它通过查询性能计数器获得数据。而在Linux上,没有性能计数器这个工具,但是这个dmv还是可以直接使用,

select counter_name,cntr_value
from sys.dm_os_performance_counters
where object_name='SQLServer:Memory manager'
and counter_name IN ('Database Cache Memory (KB)','Total Server Memory (KB)','Target Server Memory (KB)')

在这里插入图片描述
  这三个值的大概含义是:
Database Cache Memory (KB):buffer pool的内存总用量。
Target Server Memory (KB):SQL Server所用内存可以增长的上限。
Total Server Memory (KB):SQL Server引擎内部使用的内存数。
  这些值的差异是为什么呢?因为平台原因,Linux上对sqlservr进程有固定的内存分配。造成了Total Server Memory和top指令之间的数值差异。但是随着SQL Server内存使用的增多,这个差异几乎保持不变,即也会随之增加。

  接下来做个大操作——dbcc

USE master
GO
DBCC CHECKDB(WideWorldImporters) WITH TABLOCK
GO

  紧接着用top指令再次检查,这次变成1.5g了。
在这里插入图片描述

  同时执行上面的两个dmv查询:
在这里插入图片描述

在这里插入图片描述

小结

  可以看到随着使用的增加,内存也随之增长。当然,很多人诟病SQL Server吃内存的原因是内存“不释放”,特别是在Windows平台下使用任务管理器来看。在正式环境下,确实没有释放,那内存哪去了?缓存数据和执行计划了。要知道内存的读写速度比磁盘高成千上万倍,如果动不动就从磁盘读写数据,那I/O根本负担不了,服务器之所以配那么大的内存,就是为了尽可能缓存所需的数据和执行计划,最大限度加快操作的反应时间。所以内存会一直接近较满的状态。
  但是不代表内存真的是不释放的,在Windows平台,性能计数器中就有一个Page Life Expectancy 的计数器,用来标识数据页在内存中的驻留时间,如果该值过低,证明服务器内存有压力,SQL Server需要把缓存的数据按照使用频率和其他因素移除不常用的数据,并重新加载所需的数据到内存。
  所以,既然你配了那么多的内存,为什么不用呢?那些任务管理器内存占用率很低的情况除了好看一点之外,根本没有任何实际效果。除非你的库本身就小的可怜。

发布了192 篇原创文章 · 获赞 1268 · 访问量 250万+

猜你喜欢

转载自blog.csdn.net/DBA_Huangzj/article/details/88129061