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