Exibir bloqueios adquiridos durante a execução da consulta (SQL Server)

12

O plano de execução da consulta não mostra os detalhes do bloqueio por padrão. É possível visualizar os bloqueios, juntamente com o tipo, adquirido durante a execução de uma consulta?

Faisal Mansoor
fonte

Respostas:

14

é possível visualizar os bloqueios, juntamente com o tipo, adquiridos durante a execução de uma consulta?

Sim, para determinar bloqueios,

  1. Você pode usar beta_lockinfopor Erland Sommarskog

    beta_lockinfoé um procedimento armazenado que fornece informações sobre processos e bloqueios que eles mantêm, bem como suas transações ativas. beta_lockinfofoi projetado para reunir o máximo de informações possível sobre uma situação de bloqueio, para que você possa encontrar instantaneamente o culpado e matar o processo de bloqueio, se a situação estiver desesperada. Em seguida, você pode sentar e analisar a saída beta_lockinfopara entender como surgiu a situação de bloqueio e descobrir quais ações executar para impedir que a situação se repita. A saída de beta_lockinfomostra todos os processos ativos e passivos com bloqueios, quais objetos eles bloqueiam, qual comando eles enviaram pela última vez e qual instrução eles estão executando. Você também obtém os planos de consulta para as instruções atuais. Normalmente, você correbeta_lockinfopara olhar diretamente para a saída, mas também há um modo de arquivamento em que os dados são salvos na tabela. Isso não é o menos útil, se você deseja que alguém envie a saída de beta_lockinfoum site, você não tem acesso a si mesmo.

  2. Outro método é usar sp_whoIsActivepor Adam Machanic com@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
fonte
obrigado, os procs armazenados acima são ótimos para cenários de administração de banco de dados, mas você conhece alguma alternativa para cenários de otimização de consulta. Estou tentando entender o comportamento de bloqueio de uma consulta de inserção no ambiente de desenvolvimento (que não possui muitos dados, portanto, a consulta não é executada por muito tempo). Gostaria de ver todos os bloqueios adquiridos por uma consulta após sua execução. Estou interessado em ver o plano de bloqueios, semelhante à forma como o plano de consultas funciona.
Faisal Mansoor 04/04
1
Como você está usando o sql server 2012, em um nível granular de consulta, deve procurar no XEvents - Determinar quais consultas estão bloqueando . Isso lhe dará um bom começo.
Kin Shah
4

Aqui está como eu vejo os bloqueios por processo / tabela / tipo de bloqueio:

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
fonte
3
É uma ótima resposta e é uma pena que ela use visualizações de compatibilidade. Vamos lá, é 2015!
Spaghettidba
3

Você pode visualizar o histórico de bloqueios adquiridos na guia "Mensagens" depois de executar o seguinte: DBCC TRACEON (1200, 3604, -1) Mas lembre-se de ativar os sinalizadores de rastreamento GLOBALMENTE, portanto, não se esqueça de desativá-los assim que você não o fizer. preciso deles.

Vedran
fonte
1

Você pode visualizar os bloqueios para uma sessão usando sp_lock ou sys.dm_tran_locks. Nos dois sentidos, você pode filtrar pela sessão. Você também pode usar Eventos estendidos para fazer isso.

Matan Yungman
fonte
0

Sim, você pode visualizar os bloqueios e seu tipo durante a execução da consulta via

  1. SP_whoisactive de Adam mechanics clique aqui para ver

  2. Além disso, se você deseja criar um relatório de bloco, pode fazer com a ajuda de rastreamento, conforme explicado aqui

KASQLDBA
fonte
1
performance countersapenas fornecerá um amplo comportamento da instância. O OP quer no nível da consulta.
Kin Shah
@Kin, graças, acabou de remover a informação adicional :)
KASQLDBA