性能調優12:阻塞

阻塞就是常說的等待,是指事務A等待特定的資源獲得知足以後,才能繼續執行下去。發生阻塞的另一種狀況是被其餘事務阻塞。阻塞對性能的影響,有時會比死鎖更嚴重,這是由於死鎖持續的時間很是短,SQL Server 一旦探測到死鎖的發生,就會當即殺死一個進程,以結束死鎖,使其餘進程可以正常運行下去。然而,阻塞不會被殺死,能夠持續很長很長時間,這就使得被阻塞的進程即便瞬間就能夠完成,也必須等待資源獲得知足才能執行下去。sql

一,探測阻塞

使用下面的腳本探測到當前活躍的阻塞:數據庫

select w.session_id as waiting_session_id
    ,w.waiting_task_address
    ,w.wait_type
    ,w.wait_duration_ms/1000 as duration_s
    ,db_name(k.resource_database_id) as resource_db_name
    ,k.resource_type
    ,k.resource_associated_entity_id
    ,w.resource_description
    ,k.request_mode
    ,k.request_type
    ,k.request_status
    ,w.blocking_session_id
    ,w.blocking_task_address
from sys.dm_os_waiting_tasks as w
inner join sys.dm_tran_locks as k
  on w.resource_address=k.lock_owner_address
where w.wait_duration_ms>5000
  and w.session_id>50

SQL Server 沒有記錄阻塞的歷史信息,只有一個關於等待的統計信息,若是要查看數據庫系統曾經遇到過的全部等待消息,那麼就須要手動記錄阻塞的信息。session

二,捕獲阻塞

要想捕獲阻塞相關的信息,最方便的選項是經過SQL Server Profiler,並把數據保存到表以對阻塞進行分析。數據結構

配置SQL Server Profiler捕獲阻塞相關的數據,首先打開SSMS的Tools菜單,打開SQL Server Profiler,在Events Selection中勾選Blocked process report 事件,並勾選全部的列,保存足夠多的信息:分佈式

Blocked process report 代表一個Task被阻塞時間超過了一個閾值,該閾值能夠經過 sys.sp_configue命令來設置。性能

在啓動SQL Server Profiler以前,請務必配置 blocked process threshold 選項:spa

sp_configure 'show advanced options', 1
go
reconfigure
go 
sp_configure 'blocked process threshold', 20
go 
reconfigure 
go 

三,即時查看阻塞的動態管理視圖

一般狀況下,使用下面4個DMV來查看阻塞的信息。線程

1,sys.dm_os_waiting_taskscode

該視圖返回正在等待的task信息,字段分爲兩組:申請資源的Task和擁有資源的Task,簡稱爲等待組(Task或Session)和阻塞組(Task 或 Session),等待組在申請資源時因爲資源被阻塞組佔用而必須等待,阻塞組擁有資源。server

  • 字段waiting_task_address :表示申請資源的Task的內存地址,記做等待Task,該Task在申請資源時,因爲資源沒法被知足而被迫阻塞。
  • 字段blocking_task_address:表示擁有資源的Task的內存地址,記做阻塞Task,該Task當前擁有資源,只有該Task釋放資源,被阻塞的Task(即 waiting_task_address )才能得到資源的使用權。

該視圖的字段解釋:

  • waiting_task_address:處於等待資源狀態的Task地址(即 等待Task)
  • session_id:與「等待Task」相關聯的Session的 ID(處於等待狀態的Session)。
  • exec_context_id:與「等待Task」關聯的執行上下文的 ID。
  • wait_type:等待類型的名稱。
  • wait_duration_ms:此等待類型的總等待時間(毫秒),此時間包含 signal_wait_time。
  • resource_address:該「等待Task」等待的資源地址,該字段能夠和 sys.dm_tran_locks  的lock_owner_address字段關聯起來
  • blocking_task_address:當前持有此資源的Task的地址(即 阻塞Task)。
  • blocking_session_id:阻塞 「等待Task」的Session ID,也就是說,該Session擁有資源,阻塞了 「等待Task」 對資源的請求:
    •   若是此列值爲 NULL,則表示當前請求未被阻塞,或阻塞會話的信息不可用(或沒法進行標識)。
    •   -2 = 阻塞資源由孤立的分佈式事務擁有。
    •   -3 = 阻塞資源由延遲的恢復事務擁有。
    •   -4 = 因爲內部閂鎖狀態轉換而沒法肯定阻塞閂鎖全部者的會話 ID。
  • blocking_exec_context_id:「阻塞Task」的執行上下文 ID。
  • resource_description:爭用的資源描述

2, sys.dm_tran_locks 

該視圖返回當前活躍的鎖管理器資源的信息,每一行表明一個向鎖管理器申請鎖的請求,該請求當前是活躍的,申請的鎖已經被授予或者正在等待被授予。

該視圖的字段主要分爲兩類,資源和請求,資源組描述鎖定的資源,請求組描述鎖的請求,主要字段解釋:

  • resource_type:鎖定的資源類型,常見的資源類型是 OBJECT、PAGE、KEY、EXTENT、RID、HOBT 等。
  • resource_subtype:鎖定的資源類型的子類型,是對 resource_type的細分
  • resource_database_id:此資源位於其範圍以內的數據庫的 ID。由鎖管理器處理的全部資源均按數據庫 ID 劃分範圍。
  • resource_description:資源描述
  • resource_associated_entity_id:數據庫中與資源相關聯的實體的 ID。該值能夠是對象 ID、Hobt ID 或分配單元 ID,具體視資源類型而定。
  • resource_lock_partition:已分區鎖資源的鎖分區 ID。對於未分區鎖資源,該值爲 0。
  • request_mode:請求的模式。對於已授予的請求,爲已授予模式;對於等待請求,爲正在請求的模式。
  • request_type:請求類型,該值爲 LOCK。
  • request_status:用於描述請求的狀態,可能值爲 GRANTED、CONVERT和 WAIT,granted 表示請求者(requestor)已經被受權,容許鎖定資源;wait 表示請求者尚未被受權鎖定資源, convet 表示請求者已經被受權,等待鎖定資源。
  • request_reference_count:同一請求程序已請求該資源的近似次數。
  • request_session_id:當前擁有該請求的會話 ID
  • request_exec_context_id:當前擁有該請求的進程的執行上下文ID。
  • request_request_id:當前擁有該請求的進程的Request ID(即 Batch ID)
  • request_owner_type:擁有該請求的實體類型。鎖管理器請求能夠由多種實體所擁有,可能的值有:
    •   TRANSACTION = 請求由事務全部。
    •   CURSOR = 請求由遊標全部。
    •   SESSION = 請求由用戶會話全部。
    •   SHARED_TRANSACTION_WORKSPACE = 請求由事務工做區的共享部分全部。
    •   EXCLUSIVE_TRANSACTION_WORKSPACE = 請求由事務工做區的排他部分全部。
    •        NOTIFICATION_OBJECT =請求由內部的SQL Server組件全部
  • request_owner_id:請求的特定全部者 ID,分兩種狀況,第一種狀況是:事務是該請求的全部者,request_owner_id值是事務ID。 第二種狀況:
    •        若是FileTable是該請求的全部者,request_owner_id值 爲 -4 表示FileTable持有database lock; request_owner_id值爲 -3 表示 FileTable持有table lock。
    •        若是是其餘值,request_owner_id值表明文件句柄,在sys.dm_filestream_non_transacted_handles 中顯示爲fcb_id字段。
  • lock_owner_address:用於跟蹤該請求的內部數據結構的內存地址。該列能夠與 sys.dm_os_waiting_tasks 中的 resource_address 列鏈接。

 

3,sys.dm_os_wait_stats

等待統計,統計數據庫系統中出現的等待:

  • wait_type:等待類型的名稱。
  • waiting_tasks_count:該等待類型的等待次數
  • wait_time_ms:該等待類型的總等待時間(毫秒)
  • max_wait_time_ms:該等待類型的最長等待時間。
  • signal_wait_time_ms:正在等待的線程從收到信號通知到開始運行之間的時差。

 

4,sys.dm_os_tasks

返回當前SQL Server實例中活躍的Task:

  • task_address:Task結構的內存地址
  • task_state:Task的狀態,有效值有:PENDING、RUNNABLE、RUNNING、SUSPENDED、DONE和SPINLOOP
  • context_switches_count:Task已經完成的調度程序上下文切換的次數
  • pending_io_count:該Task執行的物理IO的次數
  • pending_io_byte_count:該Task執行的物理IO的字節總數量
  • pending_io_byte_average:Task執行的物理IO的字節平均數量
  • scheduler_id:父調度程序的ID,這是調度程序的句柄
  • session_id:該Task關聯的Session ID
  • exec_context_id:該Task關聯的執行上下文ID
  • request_id:該Task處理的請求 ID
  • worker_address:執行該Task的Worker的內存地址,若是該值爲NULL,表示該Task等待Worker去執行,或者已經執行完成。
  • host_address:host的內存地址
  • partner_task_address:該Task的父Task的內存地址

 

參考文檔:

sys.dm_tran_locks

相關文章
相關標籤/搜索