Lihat kunci yang diperoleh selama eksekusi permintaan (SQL Server)

12

Rencana pelaksanaan kueri tidak menampilkan detail penguncian secara default, apakah mungkin untuk melihat kunci, bersama dengan jenisnya, yang diperoleh selama eksekusi kueri?

Faisal Mansoor
sumber

Jawaban:

14

apakah mungkin untuk melihat kunci, bersama dengan jenisnya, yang diperoleh selama pelaksanaan kueri?

Ya, untuk menentukan kunci,

  1. Anda dapat menggunakan beta_lockinfooleh Erland Sommarskog

    beta_lockinfoadalah prosedur tersimpan yang menyediakan informasi tentang proses dan kunci yang mereka pegang serta transaksi aktifnya. beta_lockinfodirancang untuk mengumpulkan informasi sebanyak mungkin tentang situasi pemblokiran, sehingga Anda dapat langsung menemukan pelakunya dan membunuh proses pemblokiran jika situasinya putus asa. Kemudian Anda dapat duduk dan menganalisis output dari beta_lockinfountuk memahami bagaimana situasi pemblokiran muncul dan mencari tahu tindakan apa yang harus diambil untuk mencegah agar situasi tidak terjadi lagi. Keluaran dari beta_lockinfomenunjukkan semua proses aktif serta proses pasif dengan kunci, objek mana yang dikunci, perintah apa yang terakhir mereka kirimkan dan pernyataan apa yang mereka jalankan. Anda juga mendapatkan paket permintaan untuk laporan saat ini. Biasanya, Anda laribeta_lockinfountuk melihat output secara langsung, tetapi ada juga mode arsip di mana data disimpan ke tabel. Ini bukan yang paling tidak berguna, jika Anda ingin seseorang mengirimi Anda hasil dari beta_lockinfositus yang tidak dapat Anda akses sendiri.

  2. Metode lain adalah menggunakan sp_whoIsActiveoleh Adam Machanic dengan@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
Kin Shah
sumber
terima kasih, procs yang disimpan di atas sangat bagus untuk skenario admin db, tetapi, apakah Anda tahu ada alternatif untuk skenario optimasi kueri. Saya mencoba memahami perilaku penguncian permintaan memasukkan di lingkungan pengembangan (yang tidak memiliki banyak data, sehingga permintaan tidak berjalan sangat lama). Saya ingin melihat semua kunci yang diperoleh oleh kueri setelah dieksekusi, saya tertarik melihat rencana kunci, mirip dengan cara kerja rencana kueri.
Faisal Mansoor
1
Karena Anda menggunakan sql server 2012, pada tingkat granular kueri, Anda harus melihat ke XEvents - Tentukan Kueri yang Dimiliki Kunci . Ini akan memberi Anda awal yang baik.
Kin Shah
4

Inilah cara saya melihat kunci berdasarkan proses / tabel / jenis kunci:

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
Shane Estelle
sumber
3
Ini jawaban yang bagus dan memalukan karena menggunakan tampilan kompatibilitas. Ayo, ini tahun 2015!
spaghettidba
3

Anda dapat melihat riwayat kunci yang diperoleh di tab "Pesan" setelah menjalankan ini: DBCC TRACEON (1200, 3604, -1) Namun WASPADALAH, ini memungkinkan bendera jejak tersebut secara GLOBAL, jadi jangan lupa mematikannya segera setelah Anda tidak melakukannya. butuh mereka.

Vedran
sumber
1

Anda dapat melihat kunci untuk sesi menggunakan sp_lock atau sys.dm_tran_locks. Dengan kedua cara ini, Anda dapat memfilter menurut sesi. Anda juga dapat menggunakan Acara yang Diperpanjang untuk melakukan itu.

Matan Yungman
sumber
0

Ya, Anda dapat melihat kunci dan jenisnya selama eksekusi permintaan melalui

  1. SP_whoisactive Adam mechanics klik di sini untuk melihat

  2. Apalagi jika Anda ingin membuat laporan blok dengan Anda dapat melakukannya dengan bantuan pelacakan seperti yang dijelaskan di sini

KASQLDBA
sumber
1
performance countershanya akan memberi Anda contoh perilaku luas. OP ingin di tingkat permintaan.
Kin Shah 15
@ Kin, terima kasih, baru saja menghapus info tambahan :)
KASQLDBA