Cách kiểm tra ổ khóa nào được giữ trên bàn


158

Làm cách nào chúng ta có thể kiểm tra khóa cơ sở dữ liệu nào được áp dụng trên các hàng so với lô truy vấn?

Bất kỳ công cụ nổi bật khóa cấp bảng hàng trong thời gian thực?

DB: Máy chủ SQL 2005

Câu trả lời:


118

Để thêm vào các phản hồi khác, sp_lockcũng có thể được sử dụng để kết xuất thông tin khóa đầy đủ trên tất cả các quy trình đang chạy. Đầu ra có thể áp đảo, nhưng nếu bạn muốn biết chính xác những gì bị khóa, thì đó là một thứ có giá trị để chạy. Tôi thường sử dụng nó cùng với sp_who2để nhanh chóng không gặp vấn đề về khóa.

Có nhiều phiên bản khác nhau của sp_lockquy trình "thân thiện hơn" có sẵn trực tuyến, tùy thuộc vào phiên bản SQL Server được đề cập.

Trong trường hợp của bạn, đối với SQL Server 2005, sp_lockvẫn có sẵn, nhưng không được dùng nữa, vì vậy hiện tại bạn nên sử dụng sys.dm_tran_lockschế độ xem cho loại điều này. Bạn có thể tìm thấy một ví dụ về cách "cuộn" hàm sp_lock của riêng bạn tại đây .


116

Điều này không chính xác cho bạn thấy những hàng nào bị khóa, nhưng điều này có thể hữu ích cho bạn.

Bạn có thể kiểm tra câu lệnh nào bị chặn bằng cách chạy lệnh này:

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

Nó cũng sẽ cho bạn biết những gì mỗi khối đang chờ đợi. Vì vậy, bạn có thể theo dõi tất cả các cách để xem câu lệnh nào gây ra khối đầu tiên gây ra các khối khác.

Chỉnh sửa để thêm nhận xét từ @MikeBlandford :

Cột bị chặn cho biết spid của quá trình chặn. Bạn có thể chạy kill {spid} để sửa nó.


7
Cột bị chặn cho biết spid của quá trình chặn. Bạn có thể chạy kill {spid} để sửa nó.
Mike Blandford

52

Bạn có thể tìm thấy các khóa hiện tại trên bảng của bạn bằng cách truy vấn sau.

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');

Xem sys.dm_tran_locks

Nếu tồn tại nhiều phiên bản của cùng một request_owner_type , cột request_owner_id được sử dụng để phân biệt từng phiên bản. Đối với các giao dịch phân tán, các cột request_owner_typerequest_owner_guid sẽ hiển thị thông tin thực thể khác nhau.

Ví dụ, Phiên S1 sở hữu khóa chia sẻ trên Bảng1; và giao dịch T1, đang chạy trong phiên S1, cũng sở hữu khóa chia sẻ trên Bảng1. Trong trường hợp này, cột resource_description được trả về bởi sys.dm_tran_locks sẽ hiển thị hai trường hợp của cùng một tài nguyên. Các request_owner_type cột sẽ hiển thị một ví dụ như một phiên và người kia là một giao dịch. Ngoài ra, cột resource_owner_id sẽ có các giá trị khác nhau.


36

Tôi sử dụng Chế độ xem quản lý động (DMV) để chụp các khóa cũng như object_id hoặc phân vùng_id của mục bị khóa.

(PHẢI chuyển sang Cơ sở dữ liệu bạn muốn quan sát để lấy object_id)

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;

Tôi đang cố gắng sử dụng tuyên bố này để tìm ra các đối tượng mà một quá trình đang chờ đợi. Tôi có thể thấy rõ một phiên đang chờ một phiên khác bằng cách sử dụng sp_who2và trong sys.dm_os_waiting_task(cả hai đều cố gắng cập nhật cùng một bảng). Nhưng tuyên bố của bạn không trả lại bất kỳ hàng. Có ý kiến ​​gì không?
a_horse_with_no_name

17

Bạn cũng có thể sử dụng sp_who2thủ tục được lưu trữ tích hợp để nhận các quy trình bị chặn và chặn hiện tại trên một phiên bản SQL Server. Thông thường, bạn sẽ chạy lệnh này cùng với phiên bản SQL Profiler để tìm quy trình chặn và xem lệnh gần đây nhất được phát hành trong trình lược tả.


5

Bạn có thể tìm thấy chi tiết thông qua các kịch bản dưới đây.

-- 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');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.