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需要把緩存的數據按照使用頻率和其他因素移除不常用的數據,並重新加載所需的數據到內存。
  所以,既然你配了那麼多的內存,爲什麼不用呢?那些任務管理器內存佔用率很低的情況除了好看一點之外,根本沒有任何實際效果。除非你的庫本身就小的可憐。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章