SQL?Server數(shù)據(jù)庫服務(wù)器內(nèi)存問題排查及解決方案
前言
最近我公眾號小伙伴反饋數(shù)據(jù)庫服務(wù)器爆滿如何處理!接下來我詳細(xì)解答一下處理方案和預(yù)防方案。
SQL Server數(shù)據(jù)庫服務(wù)器內(nèi)存占用高是普遍情況,不用過于緊張,因為幾乎所有涉及的數(shù)據(jù)庫為了加快數(shù)據(jù)庫的執(zhí)行效率都會緩存一部分?jǐn)?shù)據(jù)到內(nèi)存,如果服務(wù)器還有剩余內(nèi)存,通常不用慌。如果經(jīng)常內(nèi)存爆滿導(dǎo)致服務(wù)器異常那就另當(dāng)別論了。
一、 立刻處理(快速釋放、恢復(fù))
清除緩存(謹(jǐn)慎使用,僅在緊急時)這會清空緩存,可能導(dǎo)致瞬間性能波動,業(yè)務(wù)低峰期操作。
DBCC FREESYSTEMCACHE ('ALL');
DBCC FREEPROCCACHE; 殺掉阻塞/耗時查詢先找出耗資源的會話,手動 Kill。
-- 查看耗時且占用高的會話(為啥限制大于50是因為2005之前系統(tǒng)會話ID都小于等于50) SELECT session_id, status, command, wait_type FROM sys.dm_exec_requests WHERE session_id > 50; -- 殺掉會話(替換 SPID)注意一定不要誤殺 有些屬于系統(tǒng)會話(比如寫日志、清理) KILL 56;
二、 根源排查
確認(rèn)內(nèi)存使用情況
-- 查看數(shù)據(jù)庫內(nèi)存使用
SELECT
(physical_memory_in_use_kb / 1024) AS SQL_Server_Used_Memory_MB,
(locked_page_allocations_kb / 1024) AS SQL_Server_Locked_Pages_MB,
(total_virtual_address_space_kb / 1024) AS Total_Virtual_Address_Space_MB,
process_physical_memory_low,
process_virtual_memory_low
FROM sys.dm_os_process_memory;
--查看服務(wù)器內(nèi)存使用
SELECT
(total_physical_memory_kb / 1024) AS Total_OS_Memory_MB,
(available_physical_memory_kb / 1024) AS Available_OS_Memory_MB,
system_memory_state_desc
FROM sys.dm_os_sys_memory;結(jié)論:如果 Available_OS_Memory_MB 還很大,說明這只是SQL占滿了緩沖池,是正常現(xiàn)象;如果可用內(nèi)存極少,服務(wù)器甚至Swap分區(qū)爆滿,才需要緊急優(yōu)化。*
順便提一下,不要使用任務(wù)管理器來查看 SQL Server 的內(nèi)存使用情況,它顯示的值往往不準(zhǔn)確。這是因為如果 SQL Server 啟用了“鎖定內(nèi)存頁”權(quán)限,大部分內(nèi)存分配會通過 AWE API 進(jìn)行,這部分內(nèi)存不會在任務(wù)管理器的“進(jìn)程私有字節(jié)”中顯示,從而導(dǎo)致你看不到真實的內(nèi)存占用。使用上述 DMV 查詢才能獲得準(zhǔn)確的數(shù)據(jù)。
定位是誰在“吃內(nèi)存”
-- 按數(shù)據(jù)庫統(tǒng)計內(nèi)存占用
SELECT
DB_NAME(database_id) AS DatabaseName,
COUNT(*) * 8/1024 AS CacheSize_MB
FROM sys.dm_os_buffer_descriptors
GROUP BY DB_NAME(database_id)
ORDER BY CacheSize_MB DESC;
GO三、 永久優(yōu)化方案(穩(wěn)定運行)
配置最大內(nèi)存(關(guān)鍵?。?/strong>防止SQL Server搶光系統(tǒng)內(nèi)存導(dǎo)致Windows或其他服務(wù)掛掉。
sp_configure 'show advanced options', 1; RECONFIGURE; sp_configure 'max server memory (MB)', 32768; -- 假設(shè)機(jī)器64G,留32G給系統(tǒng)和其他程序 RECONFIGURE;
索引與查詢優(yōu)化內(nèi)存高大多是因為全表查詢、缺失表索引、濫用函數(shù)、查詢大字段數(shù)據(jù)導(dǎo)致的。
-- 檢查碎片
DBCC SHOWCONTIG ('表名');
-- 重組(碎片<30%)或重建(碎片>30%)
ALTER INDEX ALL ON 表名 REBUILD;重建/重組索引:
清理執(zhí)行計劃緩存:解決參數(shù)嗅聽問題。
DBCC FREEPROCCACHE;
四、 監(jiān)控預(yù)警建議
建議在服務(wù)器上建個作業(yè),每天自動檢查內(nèi)存,超了發(fā)郵件/短信提醒:
-- 簡單的內(nèi)存告警檢查腳本
DECLARE @UsedMB INT;
SELECT @UsedMB = (physical_memory_in_use_kb/1024) FROM sys.dm_os_process_memory;
IF @UsedMB > 40000 -- 閾值,根據(jù)你機(jī)器配置調(diào)整
BEGIN
-- 這里可以調(diào)用存儲過程發(fā)送郵件通知
PRINT '警告:SQL Server內(nèi)存占用已超過閾值!當(dāng)前使用:' + CAST(@UsedMB AS VARCHAR) + ' MB';
END;?? 核心思路:SQL Server吃內(nèi)存是為了快。只要不導(dǎo)致服務(wù)器卡頓、不報錯,高內(nèi)存利用率反而是服務(wù)器配置在物盡其用。
到此這篇關(guān)于SQL Server數(shù)據(jù)庫服務(wù)器內(nèi)存問題排查的文章就介紹到這了,更多相關(guān)SQL Server服務(wù)器內(nèi)存問題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 騰訊云Windows云服務(wù)器自建Sql?Server限制內(nèi)存的操作步驟
- SQL?server數(shù)據(jù)庫log日志過大占用內(nèi)存大的解決辦法
- SQL?Server內(nèi)存機(jī)制詳解
- SQL Server 2008 R2占用cpu、內(nèi)存越來越大的兩種解決方法
- SQL語句實現(xiàn)查詢SQL Server內(nèi)存使用狀況
- 揭秘SQL Server 2014有哪些新特性(1)-內(nèi)存數(shù)據(jù)庫
- 淺談SQL Server 對于內(nèi)存的管理[圖文]
- SQL Server 數(shù)據(jù)頁緩沖區(qū)的內(nèi)存瓶頸分析
- 優(yōu)化SQL Server的內(nèi)存占用之執(zhí)行緩存
- 解決SQL Server虛擬內(nèi)存不足情況
相關(guān)文章
sqlserver 觸發(fā)器學(xué)習(xí)(實現(xiàn)自動編號)
前段時間需要用觸發(fā)器做個實現(xiàn)數(shù)據(jù)插入表時自動編號的功能,于是再學(xué)習(xí)下觸發(fā)器,硬件備份共享于此,以供討論,以免遺忘2012-08-08
如何恢復(fù)數(shù)據(jù)庫備份到一個已存在的正在使用的數(shù)據(jù)庫上
如何恢復(fù)數(shù)據(jù)庫備份到一個已存在的正在使用的數(shù)據(jù)庫上...2007-01-01
sql復(fù)制表結(jié)構(gòu)和數(shù)據(jù)的實現(xiàn)方法
這篇文章主要介紹了sql復(fù)制表結(jié)構(gòu)和數(shù)據(jù)的實現(xiàn)方法,需要的朋友可以參考下2010-06-06
SQL Server中使用Linkserver連接Oracle的方法
SQL Server提供了Linkserver來連接不同數(shù)據(jù)庫上的同構(gòu)或異構(gòu)數(shù)據(jù)源。下面以圖示介紹一下連接Oracle的方式2012-07-07

