Ver bloqueos adquiridos durante la ejecución de consultas (SQL Server)

12

El plan de ejecución de consultas no muestra los detalles de bloqueo de forma predeterminada, ¿es posible ver los bloqueos, junto con el tipo, adquiridos durante la ejecución de una consulta?

Faisal Mansoor
fuente

Respuestas:

14

¿Es posible ver los bloqueos, junto con el tipo, adquirido durante la ejecución de una consulta?

Sí, para determinar las cerraduras,

  1. Puedes usar beta_lockinfopor Erland Sommarskog

    beta_lockinfoes un procedimiento almacenado que proporciona información sobre los procesos y los bloqueos que contienen, así como sus transacciones activas. beta_lockinfoestá diseñado para recopilar tanta información sobre una situación de bloqueo como sea posible, de modo que pueda encontrar instantáneamente al culpable y matar el proceso de bloqueo si la situación es desesperada. Luego, puede sentarse y analizar el resultado beta_lockinfopara comprender cómo surgió la situación de bloqueo y determinar qué acciones tomar para evitar que la situación vuelva a ocurrir. La salida de beta_lockinfomuestra todos los procesos activos y pasivos con bloqueos, qué objetos bloquean, qué comando enviaron por última vez y qué declaración están ejecutando. También obtiene los planes de consulta para las declaraciones actuales. Normalmente corresbeta_lockinfopara mirar la salida directamente, pero también hay un modo de archivo donde los datos se guardan en la tabla. Esto no es lo menos útil, si desea que alguien le envíe la salida desde beta_lockinfoun sitio en el que no tiene acceso.

  2. Otro método es utilizarlo sp_whoIsActivepor Adam 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
    
Kin Shah
fuente
gracias, los procesos almacenados anteriores son excelentes para los escenarios de administración de db, pero, ¿conoce alguna alternativa para los escenarios de optimización de consultas? Estoy tratando de comprender el comportamiento de bloqueo de una consulta de inserción en el entorno de desarrollo (que no tiene muchos datos, por lo que la consulta no se ejecuta por mucho tiempo). Me gustaría ver todos los bloqueos adquiridos por una consulta después de su ejecución, estoy interesado en ver el plan de bloqueo, similar a cómo funciona el plan de consulta.
Faisal Mansoor
1
Dado que está utilizando SQL Server 2012, en un nivel de consulta granular, debe buscar en XEvents: determinar qué consultas tienen bloqueos . Esto te dará un buen comienzo.
Kin Shah
4

Así es como miro las cerraduras por proceso / tabla / tipo de cerradura:

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
fuente
3
Es una gran respuesta y es una pena que use vistas de compatibilidad. ¡Vamos, es 2015!
spaghettidba
3

Puede ver el historial de bloqueos adquiridos en la pestaña "Mensajes" después de ejecutar esto: DBCC TRACEON (1200, 3604, -1) Pero CUIDADO, está habilitando esas marcas de seguimiento GLOBALMENTE, así que no olvide desactivarlas tan pronto como no lo haga. los necesito

Vedran
fuente
1

Puede ver los bloqueos para una sesión usando sp_lock o sys.dm_tran_locks. En ambos sentidos, puede filtrar por sesión. También puede usar eventos extendidos para hacer eso.

Matan Yungman
fuente
0

Sí, puede ver los bloqueos y su tipo durante la ejecución de la consulta a través de

  1. SP_whoisactive de Adam Mechanics haga clic aquí para ver

  2. Además, si desea crear un informe de bloque, puede hacerlo con la ayuda de la traza como se explica aquí

KASQLDBA
fuente
1
performance counterssolo le dará un comportamiento amplio de instancia. El OP quiere a nivel de consulta.
Kin Shah
@ Kin, gracias, acabo de eliminar la información adicional :)
KASQLDBA