1. 程式人生 > >sql server 臨時表(中) Tempdb監控

sql server 臨時表(中) Tempdb監控

 一. 監控概述

  Tempdb庫空間使用的一大特點,是隻有一部分物件,例如使用者建立的臨時表、table變數等,可以用sys.allocation_units和sys.partitions這樣的管理檢視來管理,許多內部物件和版本儲存在這些管理檢視中沒有體現,所以sp_spaceused的結果和真實的使用情況會有很大差異,tempdb的空間使用是不能用sp_spaceused來跟蹤的。使用dbcc showfilestats 可以反映資料檔案使用的整體情況,但不能監控到空間被誰以什麼樣的方式用掉。

  對於Tempdb的磁碟空間不足,可能會嚴重破壞 SQL Server 生產環境,並會使正在執行的應用程式無法完成操作。可以使用 sys.dm_db_file_space_usage 動態管理檢視來監視 tempdb 檔案中的這些功能使用的磁碟空間。此外,若要在會話級或任務級監視 tempdb 中的頁分配或頁釋放活動,可以使用動態管理檢視 sys.dm_db_session_space_usage 和 sys.dm_db_task_space_usage。這些檢視可用於標識使用 tempdb 中大量磁碟空間的大型查詢、臨時表或表變數。還可以使用若干個windows效能計數器來監視 tempdb 中的可用空間以及使用 tempdb 的資源。

  (1)使用sys.dm_db_file_space_usage 檢視能反映tempdb在幾個大類裡的空間使用分佈, 使用sys.dm_db_session_space_usage 檢視能反映tempdb在各會話中空間使用分佈。(2)監控磁碟I/O來確認是否有瓶頸。(3)監視TempDB相關的DDL。

二. 監視tempdb空間分佈

  2.1 sys.dm_db_file_space_usage檢視

    使用該檢視可以:返回資料庫中每個檔案的空間使用資訊。下面例出該檢視的主要資訊,詳細檢視檢視msdn。通過這個檢視就能知道tempdb的空間是被哪一塊物件使用掉的,是使用者物件,還是內部物件,還是版本儲存。

列名

資料型別

說明

database_id

smallint

資料庫 ID

file_id

smallint

檔案 ID

unallocated_extent_page_count

bigint

檔案的未分配區中的總頁數。

不包括已分配區中的未使用頁

version_store_reserved_page_count

bigint

版本儲存分配的統一區中的總頁數

user_object_reserved_page_count

bigint

從統一區為資料庫中的使用者物件分配的總頁數

internal_object_reserved_page_count

bigint

從統一區為檔案中的內部物件分配的總頁數

  2.2 sys.dm_db_session_space_usage檢視 

    使用該檢視,能返回資料庫每個會話分配和釋放的頁數。此檢視僅適用於tempdb資料庫。只有在任務結束時才更新計數器; 統計不反映正在執行的任務。

列名

資料型別

描述

SESSION_ID

SMALLINT

會話ID。

user_objects_alloc_page_count

BIGINT

此會話為使用者物件保留或分配的頁數

user_objects_dealloc_page_count

BIGINT

此會話取消分配且不再為使用者物件保留的頁數

internal_objects_alloc_page_count

BIGINT

此會話為內部物件保留或分配的頁數

internal_objects_dealloc_page_count

BIGINT

此會話取消分配且不再為內部物件保留的頁數。

user_objects_deferred_dealloc_page_count

BIGINT

已標記為延遲釋放的頁數。

  2.3 監視的sql指令碼 

    對於監視tempdb三類物件空間分佈,這裡使用比較"輕量極"對系統影響不大的方法。通過間隔時間執行來監視空間使用,監視包括 DBCC,DMV,DMF 等,把結果輸出到一個檔案或資料庫表裡。

-- 間隔每秒執行一次,手工終止或加入作業
use tempdb
while 1=1
BEGIN

     select GETDATE() AS '當前時間'
     
     --------------query1 從檔案級檢視tempdb使用情況------------------
     /*
       TotalExtents 是磁碟佔用的空間,一個extent為64k
       UsedExtents  是磁碟使用的空間
     */
     dbcc showfilestats
     
     ------------- query2 檢視當前Tempdb各物件,佔用總空間-------------
     /*
      user_object_reserved_page_count 使用者物件包括: 臨時表,表變數,表值函式中返回的表,定義的表和索引
      internal_object_reserved_page_count 內部物件包括:排序段,雜湊聯接,遊標
      version_store_reserved_page_count 行版本包括: 觸發器,執行聯機索引,快照隔離級別或使用行版本控制
      unallocated_extent_page_count:未分配空間(可用空間)
    */
      select  'Tempdb' as DB, GETDATE() as  [Time],
              SUM(user_object_reserved_page_count)*8.0 as  '使用者物件佔用總空間_kb',
              SUM(internal_object_reserved_page_count)*8.0 as '內部物件佔用總空間_kb',
              SUM(version_store_reserved_page_count) * 8.0 as '行版本佔用總空間_kb',
              SUM(unallocated_extent_page_count) *8.0 as '未分配總空間_kb'
       from sys.dm_db_file_space_usage
         where database_id=2 
  
     -----------------query3 查詢tempdb各會話,佔用和釋放的空間-------------
     SELECT 
        t1.session_id,
        (t1.internal_objects_alloc_page_count * 8.0) AS internal_objects_alloc_kb,
        (t1.user_objects_alloc_page_count * 8.0)AS user_objects_alloc_kb,
        (t1.internal_objects_dealloc_page_count* 8.0) AS internal_objects_dealloc_kb,
        (t1.user_objects_dealloc_page_count * 8.0)  AS user_objects_dealloc_kb
    from sys.dm_db_session_space_usage as t1, 
    sys.dm_exec_sessions as t3 
    where t1.session_id = t3.session_id 
    and (t1.internal_objects_alloc_page_count >0
    or t1.user_objects_alloc_page_count>0
    or t1.internal_objects_dealloc_page_count>0
    or t1.user_objects_dealloc_page_count>0)
    and t1.session_id <>@@SPID
    
     -----------------query4 查詢tempdb 各會話以及sql語句,佔用空間-------------
    /*
     會話的內部物件和使用者物件的保留或釋放的頁數
    */
    SELECT t1.session_id,  
    (t1.internal_objects_alloc_page_count * 8.0) AS internal_objects_alloc_kb,
    (t1.user_objects_alloc_page_count * 8.0)AS user_objects_alloc_kb,
    (t1.internal_objects_dealloc_page_count* 8.0) AS internal_objects_dealloc_kb,
    (t1.user_objects_dealloc_page_count * 8.0)  AS user_objects_dealloc_kb,                                                
    st.text                                                        
    from sys.dm_db_session_space_usage as t1,                               
    sys.dm_exec_requests as t4                                              
    CROSS APPLY sys.dm_exec_sql_text(t4.sql_handle) AS st                   
     where  t1.session_id = t4.session_id                                       
       and t1.session_id >50                                                
    and (t1.internal_objects_alloc_page_count>0
    or t1.user_objects_alloc_page_count >0
    or t1.internal_objects_dealloc_page_count>0
    or t1.user_objects_dealloc_page_count>0) 
    and t1.session_id <>@@SPID

END

  監聽如下圖所示:

   2.4  行版本監控

      行版本是可以跨會話的,所以在sys.dm_db_session_space_usage中只有內部物件和使用者物件所佔用的空間檢視。如果要監聽和回收這部分空間,可使用下面指令碼:

--(1)另外查詢行版本執行最長的事務
select top 2 
    transaction_id, 
    transaction_sequence_num, 
    elapsed_time_seconds 
from sys.dm_tran_active_snapshot_database_transactions
order by elapsed_time_seconds DESC

--(2)根據得到當前會話
select   session_id from sys.dm_tran_session_transactions where transaction_id=@transaction_id

三. 監視TempDB的I/O磁碟

 由於TempDB被多個地方廣泛使用,有可能造成磁碟的消耗較大,成為I/O瓶頸。除了監視windows效能計數器,還有就是DMV檢視。

  3.1 對於windows效能計數器主要包括三個

-- 每次資料傳輸的平均時間
AVG.Disk sec/Transfer
--磁碟讀資料所需的平均時間
AVG.Disk sec/Read
--磁碟寫資料所需的平均時間
AVG.Disk sec/Write

  3.2 DMV檢視

    下面使用sys.dm_io_virtual_file_stats來確認IO瓶頸,它返回資料檔案和日誌檔案的 I/O 統計資訊,包括對檔案發出的讀取/寫入次數以及總位元組數, file_id欄位中1 是資料檔案,2是日誌檔案,指令碼如下:

SELECT DB_NAME(database_id) AS 'DBName',
file_id,
io_stall_read_ms/num_of_reads AS 'Avg Read ms/Transfer',
io_stall_write_ms/num_of_writes AS 'Avg Write ms/Transfer'
 FROM sys.dm_io_virtual_file_stats(NULL,null)
WHERE  database_id=2

  下面是資料檔案及日誌檔案效能指標建議列表,僅供參考

資料檔案 日誌檔案
目標:<10ms 目標:<5ms
可接受:10 ~ 20 ms 可接受:5~15ms
不可接受:>20ms 不可接受:>15ms

四 監視TempDB相關的DDL

  DDL主要是用在定義或改變表的結構,資料型別,表之間的連結和約束等初始化工作上。對於大量,頻繁地建立和刪除臨時表和表變數會引起元資料上的爭用。在2008版本中在一定條件下區域性臨時表和表變數會被快取,以減少元資料的爭用。通過windows效能計數器或sys.dm_os_waiting_tasks 檢視可以週期性的檢查等待時間較長的會話。

  4.1 sys.dm_os_waiting_tasks 

    使用該檢視返回有關正在等待某些資源的任務的等待佇列的資訊。指令碼如下

SELECT session_id,wait_duration_ms,resource_description,GETDATE()AS '當前時間'
FROM sys.dm_os_waiting_tasks 
WHERE resource_description LIKE '2:%' AND wait_type LIKE 'PAGE%LATCH_%'
ORDER BY wait_duration_ms desc

  4.2 windows效能計數器

SQL Server:Access Methods\Workfiles Created/Sec
SQL Server:Access Methods\Worktables Created/Sec
SQL Server:Access Methods\Mixed Page Allocations/Sec
SQL Server:Access Methods\Temp Tables Created/Sec
SQL Server:Access Methods\Temp Tables for destruction