Le plan d'exécution de la requête n'affiche pas les détails de verrouillage par défaut, est-il possible de visualiser les verrous, ainsi que le type, acquis lors de l'exécution d'une requête?
est-il possible de visualiser les verrous, ainsi que le type, acquis lors de l'exécution d'une requête?
Oui, pour déterminer les verrous,
Vous pouvez utiliser beta_lockinfo par Erland Sommarskog
beta_lockinfo
est une procédure stockée qui fournit des informations sur les processus et les verrous qu'ils détiennent ainsi que leurs transactions actives.beta_lockinfo
est conçu pour recueillir autant d'informations que possible sur une situation de blocage, afin que vous puissiez instantanément trouver le coupable et tuer le processus de blocage si la situation est désespérée. Ensuite, vous pouvez vous asseoir et analyser la sortie debeta_lockinfo
pour comprendre comment la situation de blocage est survenue et déterminer les mesures à prendre pour éviter que la situation ne se reproduise. La sortie debeta_lockinfo
montre tous les processus actifs ainsi que les processus passifs avec des verrous, quels objets ils verrouillent, quelle commande ils ont soumise en dernier et quelle instruction ils exécutent. Vous obtenez également les plans de requête pour les instructions en cours. Normalement, vous exécutezbeta_lockinfo
pour regarder directement la sortie, mais il existe également un mode d'archivage où les données sont enregistrées dans la table. Ce n'est pas le moins utile, si vous voulez que quelqu'un vous envoie la sortie debeta_lockinfo
sur un site auquel vous n'avez pas accès.
Une autre méthode consiste à utiliser sp_whoIsActive par Adam Machanic avec @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
Voici comment je regarde les verrous par type de processus/table/verrou:
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
Vous pouvez afficher l'historique des verrous acquis dans l'onglet "Messages" après avoir exécuté ceci: DBCC TRACEON (1200, 3604, -1) Mais ATTENTION, il active GLOBALEMENT ces indicateurs de trace, alors n'oubliez pas de les désactiver dès que vous ne le faites pas besoin d'eux.
Vous pouvez afficher les verrous d'une session à l'aide de sp_lock ou sys.dm_tran_locks. Dans les deux cas, vous pouvez filtrer par session. Vous pouvez également utiliser des événements étendus pour ce faire.
Oui, vous pouvez afficher les verrous et leur type lors de l'exécution de la requête via
SP_whoisactive d'Adam Mechanics cliquez ici pour voir
De plus si vous voulez créer un rapport de bloc avec vous pouvez le faire avec l'aide de la trace comme expliqué ici