SQL Server阻塞的檢查

来源:https://www.cnblogs.com/xuliuzai/archive/2019/05/08/10832615.html
-Advertisement-
Play Games

1. 阻塞 除了記憶體、CPU、I/O這些系統資源以外,阻塞和死鎖是影響資料庫應用性能的另一大因素。 所謂的「阻塞」,是指當一個資料庫會話中的事務,正在鎖定其他會話事務想要讀取或修改的資源,造成這些會話發出的請求進入等待的狀態。SQL Server 預設會讓被阻塞的請求無限期地一直等待,直到原來的事務 ...


1. 阻塞  

除了記憶體、CPU、I/O這些系統資源以外,阻塞和死鎖是影響資料庫應用性能的另一大因素。

所謂的「阻塞」,是指當一個資料庫會話中的事務,正在鎖定其他會話事務想要讀取或修改的資源,造成這些會話發出的請求進入等待的狀態。SQL Server 預設會讓被阻塞的請求無限期地一直等待,直到原來的事務釋放相關的鎖,或直到它超時、伺服器關閉、進程被殺死。一般的系統中,偶爾有短時間的阻塞是正常且合理的;但若設計不良的程式,就可能導致長時間的阻塞,這樣就不必要地鎖定了資源,而且阻塞了其他會話欲讀取或更新的需求。遇到這種情況,可能就需要手工排除阻塞的狀態。

2.阻塞和死鎖可能帶來的問題

(1)併發用戶少的時候,一切還都正常。但是隨著併發用戶的增加,性能越來越慢。

(2)應用程式運行很慢,但是SQL Server 這個CPU和磁碟利用率很低。

(3)客戶端經常受到以下錯誤。

   Error 1222--Lock request time out period exceeded.

   Error 1205--Your transaction(process ID #XX) was deadlocked on resources with another process and has been chosen as the deadlock victim. Return your transaction.

  超時錯誤--Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

(4)有些查詢能夠進行,但是有些特定的查詢或修改總是不能返回。

(5)重啟SQL Server就能解決。但是有可能跑一段時間以後又會出現問題。

3.阻塞的檢查

3.1 主要的系統表或函數

Sys.SysProcesses 系統表是一個很重要的系統視圖,主要用來定位與解決Sql Server的阻塞和死鎖。主要欄位1.Spid:Sql Servr 會話ID 2.Blocked:正在阻塞求情的會話 ID。如果此列為 Null,則標識請求未被阻塞 3. Program_name:應用程式的名稱,就是 連接字元串中配的 Application Name 4. Hostname:建立鏈接的客戶端工作站的名稱。

sys.dm_exec_requests、sys.dm_exec_sql_text返回指定SPIDer的 SQL 查詢文本。

DBCC INPUTBUFFER 顯示從客戶端發送到 Microsoft SQL Server 實例的最後一個語句。

sp_lock 系統存儲過程,報告有關鎖的信息。

3.2 Check邏輯

對應的存儲為dblockcheck(job為DB_Lockcheck),主要Check邏輯如下:

3.3 保存的數據

所收集的數據保存dblock_information中,主要包含信息如截圖,定期的統計分析可獲得經常被阻塞和引起阻塞SQL語句和Table,這些信息是進行資料庫優化的一個角度。

select top 100* from dblock_information
order by TransDateTime desc 

4.代碼實現

4.1 Table的創建腳本

CREATE TABLE [dbo].[dblock_information](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Message] [nvarchar](300) NULL,
    [LockType] [char](1) NULL,
    [SPID1] [int] NULL,
    [SPID2] [int] NULL,
    [EventType] [nvarchar](100) NULL,
    [Parameters] [nvarchar](10) NULL,
    [EventInfo] [nvarchar](3000) NULL,
    [IndividualQuery] [nvarchar](1000) NULL,
    [TransDateTime] [datetime] NULL CONSTRAINT [DF_dblock_information_TransDateTime]  DEFAULT (getdate()),
    [AppName] [varchar](50) NULL,
    [HostName] [varchar](50) NULL,
 CONSTRAINT [PK_dblock_information] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

4.2 存儲的創建腳本

Create procedure [dbo].[dblockcheck] 
     @AlarmThreshold as tinyint=10
 as
set nocount on
--------------------------------------------------------------------------------------------------------
--*Program*: <dblock check for job>
--*Programer*:<>
--*Date*:<>
--*Description*:<Query SQL Locking Process>
--*Unify*:<UA>
--########## Parameter Description Begin ##########

--########## Parameter Description End # ##########

--##########Update Log Begin ###################
--##########Update Log End # ###################
--------------------------------------------------------------------------------------------------------
declare @SQL as varchar(200)
declare @Subject as varchar(200)
declare @Body as nvarchar(max)
declare @SPName as nvarchar(max)
declare @Message as nvarchar(200)
declare @DBname varchar(15)
declare @IP varchar(20)
declare @CNT as int
declare @cnt2 int
declare @IndividualQuery nvarchar(1000)
declare @HostName varchar(50)
declare @AppName varchar(50)
SET @DBname=DB_NAME()

SELECT @IP='XXX.XXX.XXX.XXX'
----不手動定義IP也可通過以下函數來實現
Declare @ServerIP NVARCHAR(30)='', @SERVERNAME NVARCHAR(60)='' 
    SELECT top 1 @SERVERNAME = @@SERVERNAME ,@ServerIP=LOCAL_NET_ADDRESS
    FROM SYS.DM_EXEC_CONNECTIONS where LOCAL_NET_ADDRESS is not null
--------
begin
    declare @spid int,@bl int,
    @intTransactionCountOnEntry int,
    @intRowcount int,
    @intCountProperties int,
    @intCounter int

create table #tmp_lock_who (
    id int identity(1,1),
    spid smallint,
    bl smallint)

create table #tmp_lock_information (
    id int identity(1,1),
    Message nvarchar(200),
    LockType char(1),
    SPID1 int,
    SPID2 int,
    EventType nvarchar(100),
    Parameters nvarchar(10),
    EventInfo nvarchar(max),
    IndividualQuery nvarchar(1000),
    AppName varchar(50),
    HostName varchar(50)
    )

IF @@ERROR<>0 RETURN @@ERROR
    insert into #tmp_lock_who(spid,bl) 
    select 0 ,blocked
        from (select * from master..sysprocesses where blocked>0 ) a
        where not exists(select * from (select * from master..sysprocesses where blocked>0 ) b
    where a.blocked=spid)
    union 
    select spid,blocked from master..sysprocesses where blocked>0
    IF @@ERROR<>0 RETURN @@ERROR
    -- 找到臨時表的記錄數
        select @intCountProperties = Count(*),@intCounter = 1
            from #tmp_lock_who
    IF @@ERROR<>0 RETURN @@ERROR
        if @intCountProperties=0
            select N'現在沒有阻塞信息!' as message
            -- 迴圈開始
                while @intCounter <= @intCountProperties
                    begin
                    -- 取第一條記錄
                        select @spid = spid,@bl = bl
                            from #tmp_lock_who where Id = @intCounter
                        begin
                            SELECT @IndividualQuery= SUBSTRING (qr.text,qs.statement_start_offset/2, 
                                     (CASE WHEN qs.statement_end_offset = -1 THEN LEN(CONVERT(NVARCHAR(MAX), qr.text)) * 2 
                                           ELSE qs.statement_end_offset END - qs.statement_start_offset)/2)
                            FROM SYS.DM_EXEC_REQUESTS qs OUTER APPLY SYS.DM_EXEC_SQL_TEXT(qs.sql_handle) AS qr
                            WHERE qr.text is not null and qs.session_id=@bl
                            select @HostName=left(HostName,50),@AppName=Left(Program_Name,50) 
                                from master..sysprocesses With(nolock) Where SPID=@bl
                            set @SQL='DBCC INPUTBUFFER ('+cast(@bl as char(20))+')'
                            if @spid =0
                                begin
                                    select @Message=N'引起資料庫阻塞的是: '+ CAST(@bl AS NVARCHAR(100)) + N'進程號,其執行的SQL語法如下'
                                    --set @SQL='DBCC INPUTBUFFER ('+cast(@bl as char(20))+')'
                                    insert into #tmp_lock_information(EventType,Parameters,EventInfo) exec(@sql)
                                    update #tmp_lock_information set LockType='1',SPID1=@bl,SPID2=@bl,IndividualQuery=@IndividualQuery,[Message]=@Message,AppName=@APPName,HostName=@HostName where [Message] is null
                                end
                            else
                                begin
                                    select @Message=N'進程號SPID:'+ CAST(@spid AS NVARCHAR(100))+ N'' + N'進程號SPID:'+ CAST(@bl AS NVARCHAR(10)) +N'阻塞,其當前進程執行的SQL語法如下'
                                    insert into #tmp_lock_information(EventType,Parameters,EventInfo) exec(@sql)
                                    update #tmp_lock_information set LockType='2', SPID1=@spid,SPID2=@bl,IndividualQuery=@IndividualQuery,[Message]=@Message,AppName=@APPName,HostName=@HostName where [Message] is null
                                end 
                        end
                        -- 迴圈指針下移
                        set @intCounter = @intCounter + 1
                    end
            drop table #tmp_lock_who
            if exists(select 0 from #tmp_lock_information)
            Begin

                    Insert into dblock_information(Message,LockType,SPID1,SPID2,EventType,Parameters,EventInfo,IndividualQuery,AppName,HostName) 
                    Select [Message],LockType,SPID1,SPID2,EventType,Parameters,Substring(EventInfo,1,500),IndividualQuery,AppName,HostName from #tmp_lock_information

            End

            drop table #tmp_lock_information
            return 0
end

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在維護項目中,有時會指定都一些條件進行過濾文件,並對該批文件進行操作;這時我們將使用shell命令進行操作;直接上代碼 該程式將會獲得該目錄下忽略子目錄(以2開頭的目錄)的所有2001-01-01 00:00:00到2019-01-01 00:00:00的所有文件,並輸入到grepfiles.txt ...
  • fork操作 fork操作是一個同步操作,若執行較慢會阻塞redis主線程 執行時間與記憶體量相關:記憶體越大,耗時越長;虛擬機較慢,真機較快。 查看fork執行時間,可做監控 info : latest_fork_usec 上一次執行fork的微秒數 優先使用物理機或者高效支持fork操作的虛擬化技術 ...
  • 計算字元串中各個字元出現的次數,當然也可以計算某一字元出現的次數了。 解決這個問題,可以參考這篇《拆分字元串存入表中》https://www.cnblogs.com/insus/p/10836310.html DECLARE @strs NVARCHAR(100) = N'adgtryaserfg' ...
  • MS SQL 處理字元串,可以把字元串拆分為單獨字元,轉存入至一張表中。這樣可以做到很多其它相關處理。 SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- -- Author: Insus.NET -- Create date: 2019-05-0 ...
  • mysql精準模糊查詢使用CONCAT加占位符(下劃線“_”)的使用,直接限定了長度和格式 ...
  • 在SQL Server中,會話的狀態有運行(Running)、睡眠(Sleeping)、休眠(Dormant)、Preconnect 等狀態,有時候你會在資料庫中看到很多會話處於睡眠(Sleeping)狀態,那麼這些睡眠(Sleeping)狀態的會話會消耗CPU、Memory資源嗎?如果消耗資源的話... ...
  • Hibernate 5.3.1 INFO: HHH000206: hibernate.properties not foundException in thread "main" org.hibernate.internal.util.config.ConfigurationException: U ...
  • Oracle中一個表空間可能是多個用戶的預設表空間,下麵語句統計了用戶及其預設表空間情況,如果用戶多個,用戶之間通過逗號分隔。 顯示結果如下: 可以對結果根據用戶創建的時間排序(如果多用戶取第一個用戶創建時間),語句如下: 顯示結果如下: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...