クエリの実行中に取得したロックを表示する(SQL Server)


回答:


14

クエリの実行中に取得されたロックをタイプとともに表示することは可能ですか?

はい、ロックを決定するために、

  1. Erland Sommarskogで使用できますbeta_lockinfo

    beta_lockinfoは、プロセスとそれらが保持するロック、およびアクティブなトランザクションに関する情報を提供するストアドプロシージャです。beta_lockinfoブロッキング状況に関する情報を可能な限り収集するように設計されているため、状況が絶望的な場合に即座に犯人を見つけてブロッキングプロセスを終了できます。その後、座って出力を分析しbeta_lockinfo、ブロッキング状況がどのように発生したかを理解し、状況が再発しないようにするために実行するアクションを把握します。からの出力にbeta_lockinfoは、すべてのアクティブプロセスと、ロックのあるパッシブプロセス、ロックするオブジェクト、最後に送信したコマンド、実行しているステートメントが表示されます。また、現在のステートメントのクエリプランも取得します。通常、実行しますbeta_lockinfo出力を直接見ることができますが、データをテーブルに保存するアーカイブモードもあります。beta_lockinfo自分にアクセスできないサイトから誰かに出力を送信してもらいたい場合、これはあまり有用ではありません。

  2. もう1つの方法はsp_whoIsActive、Adam Machanicで使用することです。@get_locks = 1

    EXEC sp_WhoIsActive 
    @filter = '', 
    @filter_type = 'session', 
    @not_filter = '', 
    @not_filter_type = 'session', 
    @show_own_spid = 0, 
    @show_system_spids = 0, 
    @show_sleeping_spids = 1, 
    @get_full_inner_text = 0, 
    @get_plans = 1, 
    @get_outer_command = 1, 
    @get_transaction_info = 0, 
    @get_task_info = 1, 
    @get_locks = 1,   ----------> 1 = ON (get lock info); 0 = OFF
    @get_avg_time = 0, 
    @get_additional_info = 0, 
    @find_block_leaders = 0, 
    @delta_interval = 0, 
    @output_column_list = '[dd%][session_id][sql_text][sql_command][login_name][wait_info][tasks][tran_log%][cpu%][temp%][block%][reads%][writes%][context%][physical%][query_plan][locks][%]', 
    @sort_order = '[start_time] ASC', 
    @format_output = 1, 
    @destination_table = '', 
    @return_schema = 0, 
    @schema = NULL, 
    @help = 0

おかげで、上記のストアドプロシージャはdb管理シナリオに最適ですが、クエリ最適化シナリオの代替案を知っていますか。開発環境での挿入クエリのロック動作を理解しようとしています(多くのデータがないため、クエリは非常に長く実行されません)。クエリの実行後に取得されたすべてのロックを確認したいのですが、クエリプランの仕組みと同様に、ロックプランを確認することに興味があります。
ファイサルマンスール

1
SQL Server 2012を使用しているため、クエリの詳細レベルで、XEvents- ロックを保持しているクエリを特定する必要があります。これは良いスタートになります。
キンシャー

4

プロセス/テーブル/ロックタイプごとにロックを確認する方法は次のとおりです。

SELECT 
    HostName,
    "OS UserName",
    Login, 
    spid, 
    "Database", 
    TableID,
    "Table Name_________", 
    IndID, 
--  [Index Name],
    "Lock Type", 
    "Lock Mode", 
    Status, 
--  Resource,
    Count(*) AS "Lock Count"
FROM (
    SELECT
        Convert(VarChar(30), RTRIM(P.HostName)) AS HostName,
        Convert(VarChar(30), RTRIM(P.nt_UserName)) AS "OS UserName",
        Convert(VarChar(30), Suser_SName(p.sid)) AS Login, 
        Convert(SmallInt, req_spid) AS spid,
        Convert(VarChar(30), DB_Name(rsc_dbid)) AS "Database",
        rsc_objid AS TableID,
    Convert(VarChar(30), Object_Name(rsc_objid, rsc_dbid))
        AS [Table Name_________],
        rsc_indid AS IndID, 
        CASE SubString (lock_type.name, 1, 4) 
            When '' Then 'None'
            When 'DB' Then 'Database'
            When 'FIL' Then 'File'
            When 'IDX' Then 'Index'
            When 'TAB' Then 'Table'
            When 'PAG' Then 'Page'
            When 'KEY' Then 'Key'
            When 'EXT' Then 'Extent'
            When 'RID' Then 'Row ID'
            When 'APP' Then 'Application'
            Else SubString (lock_type.name, 1, 4)
        END AS "Lock Type",
        Case SubString (lock_mode.name, 1, 12)
            When NULL Then 'N/A'
            When 'Sch-S' Then 'SCHEMA (Stability)'--'SCHEMA stability lock'
            When 'Sch-M' Then 'SCHEMA (Modification)'--'SCHEMA modification lock'
            When 'S' Then 'SHARED'--'SHARED Lock acquisition'
            When 'U' Then 'UPDATE'--'UPDATE lock acquisition'
            When 'X' Then 'EXCLUSIVE'--'EXCLUSIVE lock granted'
            When 'IS' Then 'SHARED (Intent)'--'INTENT for SHARED lock'
            When 'IU' Then 'UPDATE (Intent)'--'INTENT for UPDATE lock'
            When 'IX' Then 'EXCLUSIVE (Intent)'--'INTENT for EXCLUSIVE lock'
            When 'SIU' Then 'SHARED (Intent UPDATE)'--'SHARED lock with INTENT for UPDATE'
            When 'SIX' Then 'SHARED (Intent EXCLUSIVE)'--'SHARED lock with INTENT for EXCLUSIVE'
            When 'UIX' Then 'UPDATE'--'UPDATE lock with INTENT for EXCLUSIVE'
            When 'BU' Then 'UPDATE (BULK)'--'BULK UPDATE lock'
            Else SubString (lock_mode.name, 1, 12)
        END AS "Lock Mode", 
        SubString(lock_status.name, 1, 5) AS Status,
        SubString (rsc_text, 1, 16) AS Resource
    FROM 
        Master..SysLockInfo S
        JOIN Master..spt_values lock_type on S.rsc_type = lock_type.number
        JOIN Master..spt_values lock_status on S.req_status = lock_status.number
        JOIN Master..spt_values lock_mode on S.req_mode = lock_mode.number -1
        JOIN Master..SysProcesses P on S.req_spid = P.spid
    WHERE
            lock_type.type = 'LR'
        AND lock_status.type = 'LS'
        AND lock_mode.type = 'L'
        AND DB_Name(rsc_dbid) NOT IN ('master', 'msdb', 'model')
    ) AS X
WHERE TableID > 0
GROUP BY 
    HostName,
    "OS UserName",
    Login, 
    spid, 
    "Database", 
    TableID,
    "Table Name_________", 
    IndID, 
    "Lock Type", 
    "Lock Mode", 
    Status
ORDER BY
    spid, "Database", "Table Name_________", "Lock Type", Login

3
それは素晴らしい答えであり、互換性ビューを使用するのは非常に残念です。さあ、2015年です!
スパゲッティ

3

これを実行した後、取得したロックの履歴を「メッセージ」タブで表示できます。それらが必要です。


1

sp_lockまたはsys.dm_tran_locksを使用して、セッションのロックを表示できます。どちらの方法でも、セッションでフィルタリングできます。拡張イベントを使用してそれを行うこともできます。


0

はい、クエリ実行中にロックとそのタイプを表示できます

  1. Adam mechanicsのSP_whoisactive ここをクリックして表示

  2. さらに、ここで説明されているように、トレースを使用してブロックレポートを作成する場合


1
performance countersインスタンス全体の動作を提供します。OPはクエリレベルで必要です。
キンシャー

@Kin、ありがとう、追加情報を削除しただけです:)
KASQLDBA
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.