SQL Server On Linux(18)—— SQL Server On Linux性能(4)——針對性能的配置(實例層面)

本人新書上市,請多多關照:《SQL Server On Linux運維實戰 2017版從入門到精通》

在這裏插入圖片描述

配置很多時候直接影響了後續的穩定性和性能,因此很有必要在初期就應該做必要的配置,同時隨着使用的實際情況進行調整。本文以性能爲出發點講解一下關於性能配置方面的問題。

簡介

  從配置來說,Linux上的SQL Server通常使用mssql-conf(Linux命令)、T-SQL命令中的sp_configure和ALTER SERVER CONFIGURATION,通常使用SSMS客戶端來實現。但是要提醒一下,配置通常是全局的,所以影響面非常大,如有可能必須測試和監控。
  接下來的三篇文章將從實例層面、數據庫層面和Linux層面進行介紹。

SQL Server實例配置

  實例層面針對性能的配置通常包括內存、並行執行、處理器掩碼、跟蹤、線程、plan cache和tempdb及用戶數據庫文件的部署幾方面。通常這一層的配置都需要重啓SQL Server服務,也建議通過重啓來檢查效果。

內存

  在Linux層,SQL Server默認只分配OS識別的80%的物理內存,但是對於超大內存的系統比如TB以上,顯然會有點浪費。這個時候可以使用mssql-conf配置memorylimitmb選項。但是也別設置得太厲害,否則會出現oom killer(內存溢出),可以參考一下本人另外一篇文章:如何保護SQL Server免受Linux上的OOM-killer殺掉
  在SQL Server內部,也有自己的內存限制配置選項,使用sp_configure來管理,通常只需要設置max server memory這個值。默認值爲0,也就是80% 物理內存。隨着整套系統的運行,SQL Server會增長使用率直到這個上限,不管是Windows還是Linux平臺,這個SQL Server層的值都是有必要設置的。

  使用下面命令把Linux層面的內存限制打開並設置適當的值。

sudo /opt/mssql/bin/mssql-conf set memory.memorylimitmb 1024
sudo systemctl restart mssql-server

  使用下面命令把SQL Server層面的內存限制打開並設置適當的值。

sp_configure 'show advanced options', 1;  
GO  
RECONFIGURE;  
GO  
sp_configure 'max server memory', 4096;  
GO  
RECONFIGURE;  
GO

  使用下面命令查詢當前內存分配情況。

SELECT 
  physical_memory_in_use_kb/1024 AS sql_physical_memory_in_use_MB, 
    large_page_allocations_kb/1024 AS sql_large_page_allocations_MB, 
    locked_page_allocations_kb/1024 AS sql_locked_page_allocations_MB,
    virtual_address_space_reserved_kb/1024 AS sql_VAS_reserved_MB, 
    virtual_address_space_committed_kb/1024 AS sql_VAS_committed_MB, 
    virtual_address_space_available_kb/1024 AS sql_VAS_available_MB,
    page_fault_count AS sql_page_fault_count,
    memory_utilization_percentage AS sql_memory_utilization_percentage, 
    process_physical_memory_low AS sql_process_physical_memory_low, 
    process_virtual_memory_low AS sql_process_virtual_memory_low
FROM sys.dm_os_process_memory;

並行執行

  在多CPU環境下,達到一定的條件,SQL Server就會把任務拆分成多個子任務來一起執行,這種情況叫並行執行。由於行爲和數據量的不同,對於OLTP系統來說,並行並不是好的選擇,但是對於OLAP/DW類的系統而言,卻可以增加效率和資源利用。在實例層面,這個行爲由兩個配置項來控制:max degree of parallelism和cost threshold for parallelism:

  • max degree of parallelism:用於控制並行任務的最大數量。主要針對索引重建、DBCC CHECKDB、並行插入、聯機列修改、統計信息更新等。默認爲0,即由SQL Server根據可用的CPU數量自己控制。但是長期以來,到底是否需要保持默認配置一直都沒有一個定論。因爲這個數量個實際負載有非常大的關係。根據本人工作經歷,剛入職時一個系統因爲沒有控制這個數量,加上本身語句、索引的不合理,導致一個操作就把所有CPU佔滿,整個系統經常完全卡住。在優化語句、索引及調整最大並行度之後,CPU幾乎沒有出現超過40%的情況。另外對於某些國外專家的經驗,建議對8個CPU以上的系統才修改,這裏有一篇更新到SQL 2012爲止的建議:建議和準則在 SQL Server 中的"最大並行度"配置選項。修改命令如下:
EXEC sp_configure 'show advanced options', 1;  
GO  
RECONFIGURE WITH OVERRIDE;  
GO  
EXEC sp_configure 'max degree of parallelism', 8;  
GO  
RECONFIGURE WITH OVERRIDE;  
GO  
  • cost threshold for parallelism:前面一個是設置“用不用”的問題,如果改成1則爲不用,而這個配置是設置“什麼時候用”,很顯然,只有max degree of parallelism設置不爲1時或因爲SQL Server識別出不少於一個邏輯CPU時,cost threshold for parallelism纔有意義。默認值爲5。但是這個值是在SQL Server 7.0時代經過測試得出的,明顯已經不是非常適合今時今日的情況。很多國外專家建議從25~30作爲起點,本人在實際工作中通常使用25作爲起點,暫時沒有非常明顯的異常。使用下面語句檢查物理CPU和邏輯CPU個數:
SELECT (cpu_count / hyperthread_ratio) AS PhysicalCPUs,   
cpu_count AS logicalCPUs   
FROM sys.dm_os_sys_info

修改該配置的命令如下:

EXEC sp_configure 'show advanced options', 1 ;  
GO  
RECONFIGURE  
GO  
EXEC sp_configure 'cost threshold for parallelism', 10 ;  
GO  
RECONFIGURE  
GO  

處理器掩碼

  前文提到,SQL Server自動從NUMA架構中獲益,但是可能在某些情況或者應用中,需要綁定特定的NUMA節點或者CPU,比如非專用服務器上,爲了確保其他進程也能得到CPU響應。這個時候就需要通過ALTER SERVER CONFIGURATION這個T-SQL命令來修改,注意這個配置只能使用ALTER SERVER CONFIGURATION來修改。我們可以使用類似以下命令,在8個CPU的Linux服務器上,只允許SQL Server使用4~7的CPU(CPU從0開始算起,即最後4個CPU):

ALTER SERVER CONFIGURATION SET PROCESS AFFINITY CPU = 4 TO 7
GO

  如果想讓SQL Server使用所有可用的CPU,可以使用下面語句實現:

ALTER SERVER CONFIGURATION SET PROCESS AFFINITY CPU = AUTO
GO

  爲了獲取最大性能,建議針對所有NUMA都要設置最少一個CPU關聯。或者由SQL Server自動配置(即設置爲AUTO)。

跟蹤

  雖然跟蹤(SQL Trace)今時今日已經不再是什麼推薦功能,但是其最重要的一個“default trace”依舊是很多系統的救命稻草,畢竟不是每個系統都有完整的監控體系。default trace會自動配置和跟蹤一些基礎信息,當初剛接手一個系統的時候,也是通過檢查default trace發現數據庫的LDF文件設置太小頻繁增長導致頻繁卡頓(trace文件記錄了增長的時間點,通過與卡頓時間對比,發現重疊,然後進行LDF文件配置的檢查,果然發現配置爲1MB/次,修改成128MB/次之後,現象解除)。不過如果發現default trace已經明顯影響到I/O性能,那也可以進行關閉,使用sp_configure 配置default trace enabled選項即可。後期可以配置擴展事件來實現同樣的功能。

線程

  線程(threads)用來服務如登錄、查詢等任務。爲了避免無限制的線程導致資源,SQL Server會設置線程池的最大數量。默認情況下SQL Server會使用在Linux上能偵測到的CPU數量,可以從sys.dm_os_sys_info中的max_workers_count列中獲取實際數量。在優化不足的高併發系統中,可能因爲線程被佔用過久,導致其他任務無法得到CPU資源從而形成等待,最終影響性能。如果一開始配置的數量不多,但是又出現了相關等待,可以使用sp_configure 修改max worker threads配置來提高數量。但是這個配置需要重啓SQL Server。具體建議可以參閱官方文檔:配置 max worker threads 服務器配置選項

Plan cache

  plna cache的目的是減少同樣的語句每次都進行編譯並生成執行計劃的開銷。但是很多系統,會存在偶發性的查詢,也就是說通常只會執行一次,這種查詢如果都生成執行計劃並緩存,那很容易出現內存佔用,比如在troubleshooting時,經常會select count(1) from 表 where xxx這類執行,看看是否存在與另外一個系統(特別是數據倉庫同步過程)相同數量的數據。這種實際上是沒有必要緩存執行計劃的。這個時候,optimize for ad hoc workloads配置就能起到作用。使用sp_configure來開啓之後,會在第二次執行相同sql_handle的語句纔會開始緩存。這就減少了很多即席查詢帶來的內存壓力。當然如果你的服務器內存非常充足,也可以不開啓,畢竟這個選項是針對所有ad hoc的,也就是說那些後續需要頻繁執行的語句只能在第三次執行的時候才能得到提升。

TempDB 及用戶數據庫文件

  TempDB是實例級別共享的數據庫,SQL Server用戶應該很熟悉。也或多或少聽過TempDB經常會出現性能問題。即使你不明確使用臨時表/表變量,一些大數據量關聯、order by都會藉助TempDB來實現。雖然SQL 2017開始的Windows 版在安裝過程就會提醒你可以配置多個數據文件(注意配置日誌文件是沒有性能提升的),但是Linux版是沒有這個選擇的。所以在Linux版本中,需要後續配置。國外專家在github中提供了一個腳本來實現TempDB文件拆分,可訪問TempDB文件拆分(SQL Server on Linux)。而至於拆分多少個及每個多大,可以參考下面的兩篇文章:

  1. tempdb 數據庫:https://docs.microsoft.com/zh-cn/sql/relational-databases/databases/tempdb-database?view=sql-server-2017
  2. 建議以減少 SQL Server tempdb 數據庫中的分配爭用:https://support.microsoft.com/zh-cn/help/2154845/recommendations-to-reduce-allocation-contention-in-sql-server-tempdb-d

  對於大型系統而言,用戶數據庫的文件拆分也是有必要的,這個在下一篇講解,這裏只是順帶提一下而已。

總結

  本文以綱要的形式提及實例層面針對Linux上的SQL Server的配置內容。這些通常是在SQL Server安裝之後就要進行配置的,可以作爲一些checklist來使用。

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