Visualizza i blocchi acquisiti durante l'esecuzione della query (SQL Server)


12

Il piano di esecuzione della query non mostra i dettagli di blocco per impostazione predefinita, è possibile visualizzare i blocchi, insieme al tipo, acquisiti durante l'esecuzione di una query?

Risposte:


14

è possibile visualizzare i blocchi, insieme al tipo, acquisiti durante l'esecuzione di una query?

Sì, per determinare i blocchi,

  1. È possibile utilizzare beta_lockinfoda Erland Sommarskog

    beta_lockinfoè una procedura memorizzata che fornisce informazioni sui processi e sui blocchi che detengono nonché sulle loro transazioni attive. beta_lockinfoè progettato per raccogliere quante più informazioni possibili su una situazione di blocco, in modo da poter trovare immediatamente il colpevole e uccidere il processo di blocco se la situazione è disperata. Quindi puoi rilassarti e analizzare l'output da beta_lockinfoper capire come si è verificata la situazione di blocco e capire quali azioni intraprendere per impedire che si ripresenti. L'output da beta_lockinfomostra tutti i processi attivi e passivi con blocchi, quali oggetti bloccano, quale comando hanno inviato per ultimo e quale istruzione stanno eseguendo. È inoltre possibile ottenere i piani di query per le dichiarazioni correnti. Normalmente, corribeta_lockinfoper guardare direttamente l'output, ma esiste anche una modalità di archiviazione in cui i dati vengono salvati nella tabella. Questo non è il meno utile, se vuoi che qualcuno ti invii l'output da beta_lockinfoun sito non hai accesso a te stesso.

  2. Un altro metodo è quello di usare sp_whoIsActiveAdam Machanic con@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
    

grazie, i proc memorizzati sopra sono ottimi per gli scenari di amministrazione db, ma conosci qualche alternativa per gli scenari di ottimizzazione delle query. Sto cercando di capire il comportamento di blocco di una query di inserimento nell'ambiente di sviluppo (che non ha molti dati, quindi la query non dura molto a lungo). Vorrei vedere tutti i blocchi acquisiti da una query dopo la sua esecuzione, mi interessa vedere il piano di blocco, simile a come funziona il piano di query.
Faisal Mansoor,

1
Dal momento che stai usando SQL Server 2012, a livello granulare di query, dovresti esaminare XEvents: determinare quali query trattengono blocchi . Questo ti darà un buon inizio.
Kin Shah,

4

Ecco come guardo i blocchi per processo / tabella / tipo di blocco:

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
È un'ottima risposta ed è un peccato che utilizzi le visualizzazioni di compatibilità. Dai, è il 2015!
spaghettidba,

3

È possibile visualizzare la cronologia dei blocchi acquisiti nella scheda "Messaggi" dopo aver eseguito questo: DBCC TRACEON (1200, 3604, -1) Ma ATTENZIONE, sta abilitando GLOBALMENTE quei flag di traccia, quindi non dimenticare di disattivarli non appena bisogno di loro.


1

È possibile visualizzare i blocchi per una sessione utilizzando sp_lock o sys.dm_tran_locks. In entrambi i modi è possibile filtrare per sessione. Puoi anche utilizzare gli Eventi estesi per farlo.


0

Sì, è possibile visualizzare i blocchi e il relativo tipo durante l'esecuzione della query tramite

  1. SP_whoisactive di Adam mechanics fai clic qui per visualizzare

  2. Inoltre, se si desidera creare un report di blocco, è possibile farlo con l'aiuto di trace, come spiegato qui


1
performance countersti darà solo un comportamento ampio di istanza. L'OP vuole a livello di query.
Kin Shah,

@Kin, grazie, ho appena rimosso le informazioni extra :)
KASQLDBA
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.