RDS for SQL Server死鎖處理方法

問題現象

當應用程序頻繁讀寫某個表或者資源時,容易出現死鎖現象。出現死鎖時,SQL Server會選擇終止其中一個事務,並且向發起該事務的客戶端發送如下錯誤信息:

Error Message:Msg 1205, Level 13, State 47, Line 1Transaction (Process ID 53) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

處理方法

  1. 使用客戶端連接實例,請參見連接實例
  2. 監控相關視圖:
    • 循環監控sys.sysprocesses,SQL如下:
      while 1=1
      begin
      select * from sys.sysprocesses where blocked<>0
      waitfor delay '00:00:01'  --循環間隔時間可以自定義
      end

      sysprocesses死鎖

      說明 監控結果中 blocked列的值爲阻塞該會話的阻塞源會話ID, waitresource爲被阻塞的會話等待的資源。從上述結果可以看到,spid 53和spid 56相互阻塞,形成了死鎖。

    • 循環監控sys.dm_tran_locks,sys.dm_os_waiting_tasks等視圖,SQL如下:
      while 1=1
          Begin
          SELECT
          db.name DBName,
          tl.request_session_id,  --被阻塞session
          wt.blocking_session_id,  --阻塞頭session
          OBJECT_NAME(p.OBJECT_ID) BlockedObjectName,
          tl.resource_type,
          h1.TEXT AS RequestingText,
          h2.TEXT AS BlockingText,
          tl.request_mode
          FROM sys.dm_tran_locks AS tl
          INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id
          INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address
          INNER JOIN sys.partitions AS p ON p.hobt_id = tl.resource_associated_entity_id
          INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id
          INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id
          CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
          CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
          waitfor delay '00:00:01' --循環間隔時間可以自定義
          End

      死鎖2
      說明
      • DBName:request_session_id操作的數據庫。
      • request_session_id:當前請求的會話 ID,即被阻塞的會話。
      • blocking_session_id:阻塞源會話ID。
      • BlockedObjectName:被阻塞的會話操作的對象。
      • resource_type:等待的資源類型。
      • RequestingText:當前會話執行的語句,即被阻塞的語句。
      • BlockingText:阻塞源會話執行的語句。
      • request_mode:當前會話請求的鎖模式。
    • 如果您使用的是RDS for SQL Server 2012,您還可以使用SQL Server Profiler來監控和抓取死鎖圖譜。
      Profiler

      抓取的死鎖圖譜如下。
      Profiler2

  3. 調優:
    • 關閉阻塞源會話,可以幫助快速解除阻塞。
    • 查看是否有長時間未提交的事務,及時提交事務。
    • 使用with(nolock)查詢。

      說明 如果有S鎖參與死鎖,並且應用允許髒讀,可以使用with nolock,讓select語句避免申請鎖,從而避免死鎖,例如 select * from table with(nolock)

    • 檢查應用程序邏輯,按順序訪問某個資源。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章