it-swarm.com.de

So überprüfen Sie, welche Sperren auf einem Tisch gehalten werden

Wie können wir überprüfen, welche Datenbanksperren für welche Zeilen für einen Abfragestapel angewendet werden?

Gibt es ein Tool, das das Sperren auf Tabellenzeilenebene in Echtzeit hervorhebt?

DB: SQL Server 2005

145
usman shaheen

Um zu den anderen Antworten hinzuzufügen, sp_lock kann auch verwendet werden, um vollständige Sperrinformationen für alle laufenden Prozesse zu sichern. Die Ausgabe kann überwältigend sein, aber wenn Sie genau wissen möchten, was gesperrt ist, ist es eine wertvolle Aufgabe, sie auszuführen. Ich benutze es normalerweise zusammen mit sp_who2, um Probleme mit dem Sperren schnell zu beheben.

Es gibt mehrere verschiedene Versionen von "friendlier" sp_lock online verfügbare Prozeduren, abhängig von der jeweiligen Version von SQL Server.

In Ihrem Fall ist für SQL Server 2005 sp_lock ist immer noch verfügbar, aber veraltet. Daher wird jetzt empfohlen, sys.dm_tran_locks Ansicht für diese Art der Sache. Sie finden ein Beispiel, wie Sie Ihre eigene sp_lock-Funktion "rollen" können hier .

113
mwigdahl

Dies zeigt Ihnen nicht genau, welche Zeilen gesperrt sind, aber dies kann für Sie hilfreich sein.

Sie können überprüfen, welche Anweisungen blockiert sind, indem Sie Folgendes ausführen:

select cmd,* from sys.sysprocesses
where blocked > 0

Außerdem erfahren Sie, worauf jeder Block wartet. Sie können das also bis zum Ende verfolgen, um zu sehen, welche Anweisung den ersten Block verursacht hat, der die anderen Blöcke verursacht hat.

Bearbeiten Kommentar hinzufügen von @ MikeBlandford :

Die blockierte Spalte gibt die Geschwindigkeit des Blockierungsprozesses an. Sie können kill {spid} ausführen, um das Problem zu beheben.

104
Brian R. Bondy

Sie können aktuelle Sperren für Ihre Tabelle finden, indem Sie die folgende Abfrage ausführen.

USE yourdatabase;
GO

SELECT * FROM sys.dm_tran_locks
  WHERE resource_database_id = DB_ID()
  AND resource_associated_entity_id = OBJECT_ID(N'dbo.yourtablename');

Siehe sys.dm_tran_locks

Wenn mehrere Instanzen desselben request_owner_type vorhanden sind, wird die Spalte request_owner_id verwendet jede Instanz zu unterscheiden. Bei verteilten Transaktionen werden in den Spalten request_owner_type und request_owner_guid die unterschiedlichen Werte angezeigt Entitätsinformationen.

Beispielsweise besitzt Sitzung S1 eine gemeinsam genutzte Sperre für Tabelle1. und Transaktion T1, die unter Sitzung S1 ausgeführt wird, besitzt auch eine gemeinsam genutzte Sperre für Tabelle1. In diesem Fall wird die Spalte resource_description von sys.dm_tran_locks zurückgegeben. Zeigt zwei Instanzen derselben Ressource an. In der Spalte request_owner_type wird eine Instanz als Sitzung und die andere als Transaktion angezeigt. Außerdem weist die Spalte resource_owner_id unterschiedliche Werte auf.

47
Somnath Muluk

Ich verwende eine Dynamic Management View (DMV), um Sperren sowie die object_id oder partition_id des gesperrten Elements zu erfassen.

(MUSS zu der Datenbank wechseln, die Sie beobachten möchten, um object_id zu erhalten)

SELECT 
     TL.resource_type,
     TL.resource_database_id,
     TL.resource_associated_entity_id,
     TL.request_mode,
     TL.request_session_id,
     WT.blocking_session_id,
     O.name AS [object name],
     O.type_desc AS [object descr],
     P.partition_id AS [partition id],
     P.rows AS [partition/page rows],
     AU.type_desc AS [index descr],
     AU.container_id AS [index/page container_id]
FROM sys.dm_tran_locks AS TL
INNER JOIN sys.dm_os_waiting_tasks AS WT 
 ON TL.lock_owner_address = WT.resource_address
LEFT OUTER JOIN sys.objects AS O 
 ON O.object_id = TL.resource_associated_entity_id
LEFT OUTER JOIN sys.partitions AS P 
 ON P.hobt_id = TL.resource_associated_entity_id
LEFT OUTER JOIN sys.allocation_units AS AU 
 ON AU.allocation_unit_id = TL.resource_associated_entity_id;
35
Jon

Sie können auch das integrierte sp_who2 gespeicherte Prozedur, um aktuelle blockierte und blockierende Prozesse auf einer SQL Server-Instanz abzurufen. Normalerweise führen Sie dies zusammen mit einer SQL Profiler-Instanz aus, um einen Blockierungsprozess zu finden und den neuesten Befehl zu suchen, den spid im Profiler ausgegeben hat.

16
Neil Barnwell

Details finden Sie über das unten stehende Skript.

-- List all Locks of the Current Database 
SELECT TL.resource_type AS ResType 
      ,TL.resource_description AS ResDescr 
      ,TL.request_mode AS ReqMode 
      ,TL.request_type AS ReqType 
      ,TL.request_status AS ReqStatus 
      ,TL.request_owner_type AS ReqOwnerType 
      ,TAT.[name] AS TransName 
      ,TAT.transaction_begin_time AS TransBegin 
      ,DATEDIFF(ss, TAT.transaction_begin_time, GETDATE()) AS TransDura 
      ,ES.session_id AS S_Id 
      ,ES.login_name AS LoginName 
      ,COALESCE(OBJ.name, PAROBJ.name) AS ObjectName 
      ,PARIDX.name AS IndexName 
      ,ES.Host_name AS HostName 
      ,ES.program_name AS ProgramName 
FROM sys.dm_tran_locks AS TL 
     INNER JOIN sys.dm_exec_sessions AS ES 
         ON TL.request_session_id = ES.session_id 
     LEFT JOIN sys.dm_tran_active_transactions AS TAT 
         ON TL.request_owner_id = TAT.transaction_id 
            AND TL.request_owner_type = 'TRANSACTION' 
     LEFT JOIN sys.objects AS OBJ 
         ON TL.resource_associated_entity_id = OBJ.object_id 
            AND TL.resource_type = 'OBJECT' 
     LEFT JOIN sys.partitions AS PAR 
         ON TL.resource_associated_entity_id = PAR.hobt_id 
            AND TL.resource_type IN ('PAGE', 'KEY', 'RID', 'HOBT') 
     LEFT JOIN sys.objects AS PAROBJ 
         ON PAR.object_id = PAROBJ.object_id 
     LEFT JOIN sys.indexes AS PARIDX 
         ON PAR.object_id = PARIDX.object_id 
            AND PAR.index_id = PARIDX.index_id 
WHERE TL.resource_database_id  = DB_ID() 
      AND ES.session_id <> @@Spid -- Exclude "my" session 
      -- optional filter  
      AND TL.request_mode <> 'S' -- Exclude simple shared locks 
ORDER BY TL.resource_type 
        ,TL.request_mode 
        ,TL.request_type 
        ,TL.request_status 
        ,ObjectName 
        ,ES.login_name;



--TSQL commands
SELECT 
       db_name(rsc_dbid) AS 'DATABASE_NAME',
       case rsc_type when 1 then 'null'
                             when 2 then 'DATABASE' 
                             WHEN 3 THEN 'FILE'
                             WHEN 4 THEN 'INDEX'
                             WHEN 5 THEN 'TABLE'
                             WHEN 6 THEN 'PAGE'
                             WHEN 7 THEN 'KEY'
                             WHEN 8 THEN 'EXTEND'
                             WHEN 9 THEN 'RID ( ROW ID)'
                             WHEN 10 THEN 'APPLICATION' end  AS 'REQUEST_TYPE',

       CASE req_ownertype WHEN 1 THEN 'TRANSACTION'
                                     WHEN 2 THEN 'CURSOR'
                                     WHEN 3 THEN 'SESSION'
                                     WHEN 4 THEN 'ExSESSION' END AS 'REQUEST_OWNERTYPE',

       OBJECT_NAME(rsc_objid ,rsc_dbid) AS 'OBJECT_NAME', 
       PROCESS.HOSTNAME , 
       PROCESS.program_name , 
       PROCESS.nt_domain , 
       PROCESS.nt_username , 
       PROCESS.program_name ,
       SQLTEXT.text 
FROM sys.syslockinfo LOCK JOIN 
     sys.sysprocesses PROCESS
  ON LOCK.req_spid = PROCESS.spid
CROSS APPLY sys.dm_exec_sql_text(PROCESS.SQL_HANDLE) SQLTEXT
where 1=1
and db_name(rsc_dbid) = db_name()



--Lock on a specific object
SELECT * 
FROM sys.dm_tran_locks
WHERE resource_database_id = DB_ID()
AND resource_associated_entity_id = object_id('Specific Table');
0
Metin Atalay