資料庫被誰給卡住了

黃家瑞 Jerry Huang

  • 精誠資訊/恆逸教育訓練中心-資深講師
  • 技術分類:資料庫

 

 

在一個多人同時使用資料庫的環境中,IT人員常會有這樣的經驗,使用者電話打來抱怨:

「我的程式查詢按下去跑不出來」
「我的報表跑到逾時終止」
「我平常執行這個程式一下子就跑完了,今天程式執行得特別慢,等好久」


為什麼今天資料庫卡卡的?我的資料庫被誰卡住了?

這要回到資料庫同時處理多個程序的機制。SQL Server 資料庫引擎,是架構在Client/Server環境下的服務,當使用者對資料庫伺服器提出請求要查詢某個資料表的某些資料,資料庫引擎會先檢查目前是否有其他程序正在”使用”這些資料,如果其他程序還在使用中,必須等待其他程序使用完才能使用。有點類似,某天小明到便利超商想使用洗手間,得先看洗手間是否有人使用,如果有其他人正在使用中,必須等洗手間沒有人使用才能進去。可是小明怎麼知道洗手間有沒有人使用? 便利超商的洗手間,門把上有一個牌子,當有人進入洗手間鎖上,外面會看到牌子會變成紅色的”使用中”,其他人就知道洗手間現在有人正在使用,鎖打開後,牌子會變成藍色的”空閒中”,下一位客人才能使用。SQL Server也是使用相同的原理,產生鎖定(Lock)來通知其他使用者,目前資料正在使用中。

這裡利用一個簡易的例子來做說明:

在Microsoft SQL Server Management Studio中,新增查詢執行以下的SQL語法(SQLQuery1)

    -- 移除資料庫db01
    USE master;
    DROP DATABASE IF EXISTS db01;
    GO

    -- 建立資料庫db01
    CREATE DATABASE db01;
    GO

    USE db01;

    -- 建立測試資料表 dbo.Test
    CREATE TABLE dbo.Test
    (
    id int PRIMARY KEY
    );

新增查詢,執行以下語法(SQLQuery2)

    USE db01;

    BEGIN TRAN

    INSERT INTO dbo.Test(id) VALUES(1);

再新增一個查詢,執行以下語法(SQLQuery3)

    USE db01;

    SELECT * FROM dbo.Test;

這時候,(SQL-2)的語法會處於一個等待中的狀態,在Object Explored,Server上右鍵 => Activity Monitor




列表中Session ID = 56 的狀態為 SUSPENDED(暫止中),等待Session 55的Lock被釋放。
Session ID=55, Header Blocker欄位的值為1 ,表示這一個Session為阻擋執行的元凶。




在這個Session上右鍵=>Kill Process就可以讓其他Process的障礙被移除,但也要注意到,此時被Kill的Process的動作就會被取消了,交易就失敗了。



也可以利用SQL語法找出目前正在執行的程序

    EXEC sp_who2;



可以看到 Session 56 被 Session 55給擋住了(Blocked By)



以下的DMV也可以找到被擋住的語法

    SELECT r.session_id,
    r.status AS [指令狀態],
    r.command AS [指令類型],
    r.wait_time/1000.0 AS [等待時間(秒)],
    s.client_interface_name AS [連線資料庫的驅動程式],
    s.host_name AS [電腦名稱],
    s.program_name AS [執行程式名稱],
    t.text AS [執行的SQL語法],
    r.blocking_session_id AS [被鎖定卡住的session_id]
    FROM sys.dm_exec_requests r
    INNER JOIN sys.dm_exec_sessions s
    ON r.session_id = s.session_id
    CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
    WHERE s.is_user_process = 1;

SQL Server有提供各種監控的DMV(Dynamic Management View),只是要兜出完整的資訊往往需要好幾個View一起看,對初學者而言不是很容易的事情,也因此,在SSMS介面中有不少工具可以使用,利用這些工具,也可以很容易地找出究竟現在的SQL Server在”忙甚麼”,下次有使用者問「我的程式查詢按下去跑不出來」可以試著利用這些方法來找出,究竟我的資料庫是被誰給卡住了。


您可在下列課程中了解更多技巧喔!