SQL server內(nèi)存問題排查方案
前言
由于昨晚線上服務(wù)器數(shù)據(jù)庫突然訪問數(shù)據(jù)緩慢,任務(wù)管理里面SQL server進程爆滿等等,重大事故的排查擬寫解決方案。
整體思路
- 查詢數(shù)據(jù)庫請求連接:排查連接池是否占滿
- 查詢數(shù)據(jù)庫請求量:排查數(shù)據(jù)是否存在反復(fù)查詢
- 查詢數(shù)據(jù)庫阻塞語句以及執(zhí)行語句:排查數(shù)據(jù)庫是否存在歷史SQL語句阻塞以及當(dāng)前執(zhí)行的SQL語句是否存在問題
- 查詢數(shù)據(jù)庫語句執(zhí)行時間:排查數(shù)據(jù)庫是否因為數(shù)據(jù)量過大導(dǎo)致的
- 定位到問題指定位置
查詢數(shù)據(jù)庫請求連接
SELECT DB_NAME(dbid) AS DatabaseName, COUNT(*) AS ConnectionCount FROM sys.sysprocesses WHERE dbid > 0 GROUP BY dbid;
查看連接池比較正常,除了master主數(shù)據(jù)庫存在大量連接,其他業(yè)務(wù)數(shù)據(jù)庫正常,猜測應(yīng)該是排查人員的連接池,不太確定具體原因,但是排除連接池超量的問題。
查詢數(shù)據(jù)庫請求量
SELECT client_net_address AS '客戶端IP', COUNT(*) AS '請求次數(shù)' FROM sys.dm_exec_connections GROUP BY client_net_address ORDER BY COUNT(*) DESC;
通過SQL語句排查是否存在大量重復(fù)數(shù)據(jù)請求量,顯然并不是請求次數(shù)的問題,也就是說沒有頻繁的請求量,因此排除數(shù)據(jù)請求頻繁的問題。
查詢數(shù)據(jù)庫阻塞語句以及執(zhí)行語句
SELECT TOP 100 dest.[text] AS 'sql語句',session_id,status,start_time FROM sys.[dm_exec_requests] AS der CROSS APPLY sys.[dm_exec_sql_text](der.[sql_handle]) AS dest ORDER BY [cpu_time] DESC
查詢到數(shù)據(jù)庫正在執(zhí)行的SQL語句并不存在阻塞的SQL語句,發(fā)現(xiàn)當(dāng)前在執(zhí)行的SQL語句比較正常,單獨執(zhí)行這些SQL語句并不存在大量數(shù)據(jù)訪問,最多六千條數(shù)據(jù)量,這個量很小,因此無法確定,但是可以確定數(shù)據(jù)庫不存在問題,SQL語句也比較正常。
查詢數(shù)據(jù)庫語句執(zhí)行時間
SELECT --TOP 20 total_worker_time / 1000 AS [自編譯以來執(zhí)行所用的CPU時間總量(ms)], total_elapsed_time/1000 as [完成執(zhí)行此計劃所用的總時間], total_elapsed_time / execution_count/1000 as [平均完成執(zhí)行此計劃所用時間], execution_count as [上次編譯以來所執(zhí)行的次數(shù)], creation_time as [編譯計劃的時間], deqs.total_worker_time / deqs.execution_count / 1000 AS [平均使用CPU時間(ms)], last_execution_time AS [上次開始執(zhí)行計劃的時間], total_physical_reads [編譯后在執(zhí)行期間所執(zhí)行的物理讀取總次數(shù)], total_logical_reads/execution_count [平均邏輯讀次數(shù)], min_worker_time /1000 AS [單次執(zhí)行期間所用的最小CPU時間(ms)], max_worker_time / 1000 AS [單次執(zhí)行期間所用的最大 CPU 時間(ms)], SUBSTRING(dest.text, deqs.statement_start_offset / 2 + 1, (CASE WHEN deqs.statement_end_offset = -1 THEN DATALENGTH(dest.text) ELSE deqs.statement_end_offset END - deqs.statement_start_offset ) / 2 + 1) AS [執(zhí)行SQL], dest.text as [完整SQL], db_name(dest.dbid) as [數(shù)據(jù)庫名稱], object_name(dest.objectid, dest.dbid) as [對象名稱] ,deqs.plan_handle [查詢所屬的已編譯計劃] FROM sys.dm_exec_query_stats deqs WITH(NOLOCK) CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest WHERE (max_worker_time / 1000)>100 --完成執(zhí)行此計劃所用的總時間降序 ORDER BY total_elapsed_time/1000 DESC
從SQL語句執(zhí)行時間分析出(后補的圖忽略第一個刪除的操作),整體分析下來是 tb_SN 和 tb_SNs 兩張表耗時嚴重,接下來只需使用查詢語句查詢兩張表數(shù)量即可。
問題分析與定位
查詢序列號表 tb_SN
SELECT COUNT(*) FROM tb_SN 243779 條
排查不是序列號表的問題,那么就只有序列號流水表的問題啦
查詢序列號流水表 tb_SNs
SELECT COUNT(*) FROM tb_SNs
使用該命令果然執(zhí)行時間緩慢,因此可以判斷是數(shù)據(jù)量太大導(dǎo)致的。
使用壓縮存儲快速查看數(shù)據(jù)量
點擊 tb_SNs 流水表 【右鍵】【存儲】【管理壓縮】【下一步】
流水表五千萬條數(shù)據(jù),因此可以確定序列號流水表存在數(shù)據(jù)量過多導(dǎo)致的,整個和序列號流水相關(guān)的程序出現(xiàn)訪問緩慢的問題。
竟然知道問題了,和相關(guān)領(lǐng)導(dǎo)咨詢是否可以刪除數(shù)據(jù),并確定刪除的時限范圍,確定刪除 2023 年以前的所有數(shù)據(jù),釋放數(shù)據(jù)量。
首先我們備份整個數(shù)據(jù)庫防止誤操作,然后復(fù)制并創(chuàng)建與 tb_SNs 的數(shù)據(jù)結(jié)構(gòu)相同的表,接下來將 2023 年以前的所有數(shù)據(jù)拷貝到該表上,最后在刪除 tb_SNs 的 2023 年以前的所有數(shù)據(jù)。
如此操作下,我們發(fā)現(xiàn)刪除的數(shù)據(jù)量只有十萬條,顯然這是不對的,總共三年不到,不可能只有怎么點數(shù)據(jù),因此判斷是不是某個時間點插入大量數(shù)據(jù),然后我們根據(jù)去年年份查詢?nèi)ツ甑臄?shù)據(jù)量:
SELECT TOP 10 COUNT(*) FROM tb_SNs WHERE CreationDate < '2024-01-01' 571638
五十萬條顯然是今年數(shù)據(jù)量突然增加的,因此開始查詢月時間節(jié)點產(chǎn)生的數(shù)據(jù),發(fā)現(xiàn)三月以前都正常,數(shù)據(jù)出現(xiàn)在三月份,接下來開始查詢每日的數(shù)據(jù)量,三月五號正常,三月六號出現(xiàn)五千萬數(shù)據(jù),因此問題出現(xiàn)在昨天的時候。
解析問題
接下來問題就好解決啦,首先根據(jù)主要數(shù)據(jù)查詢事故發(fā)生節(jié)點,再通過事故發(fā)生節(jié)點咨詢是否出現(xiàn)錯誤操作。
- 查詢負責(zé)人該節(jié)點人員工作安排
- 根據(jù)業(yè)務(wù)確定程序是否存在邏輯判斷插入問題
- 判斷數(shù)據(jù)是否可以刪除
以上就是SQL server內(nèi)存問題排查方案的詳細內(nèi)容,更多關(guān)于SQL server內(nèi)存問題的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
sql server 復(fù)制表從一個數(shù)據(jù)庫到另一個數(shù)據(jù)庫
本文將詳細介紹SQL server 數(shù)據(jù)庫如何把一張表復(fù)制到另一個數(shù)據(jù)庫表中,需要了解更多的朋友可以參考下2012-11-11MSSQL 數(shù)據(jù)庫備份和還原的幾種方法 圖文教程
MSSQL 數(shù)據(jù)庫備份和還原的幾種方法小結(jié),配有圖文,大家看了就知道了。2009-12-12Sql Server 如何去掉內(nèi)容里面的Html標簽
這篇文章主要介紹了Sql Server 去掉內(nèi)容里邊的Html標簽的實現(xiàn)方法,代碼超簡單,具有一定的參考借鑒價值,需要的朋友可以參考下2018-05-05SQL Server誤區(qū)30日談 第4天 DDL觸發(fā)器就是INSTEAD OF觸發(fā)器
DDL觸發(fā)器的實現(xiàn)原理其實就是一個AFTER觸發(fā)器。這個意思是先發(fā)生DDL操作,然后觸發(fā)器再捕捉操作(當(dāng)然如果你在觸發(fā)器內(nèi)寫了Rollback,則也可能回滾)2013-01-01sqlserver isnull在數(shù)據(jù)庫查詢中的應(yīng)用
isnull在數(shù)據(jù)庫查詢中的應(yīng)用,特別是再語句連接的時候需要用到2011-11-11