天天看點

資料庫維護管理和監視新特性

資料庫維護管理和監視新特性

我的查詢沒有響應  為什麼? 哪一個運作T-SQL的連接配接阻塞了我的查詢? 阻塞查詢的連接配接正在運作哪個T-SQL? 哪個T-SQL在等待什麼資源?

診斷工具: Profiler  Performance Monitor(PerfMon)  DBCC command  Activity Monitor  Stored procedures(sp_who,sp_who2,sp_lock...)  其它實用工具(Read80Trace...)

SQL Server 2005維護管理和監視新特性: 動态管理對象DMO-->Dynamic Management Objects  DMO(SQL Server早期版本中的分布式管理對象)與SMO(SQL Server 2005中的管理對象)

什麼是DMV & DMF? DMO動态管理對象(Dynamic Management Objects) DMV--動态管理視圖(Dynamic Management Views) DMF--動态管理函數(Dynamic Management Functions)  擷取用于監視伺服器執行個體的運作狀況、診斷故障以及優化性能的伺服器狀态資訊

DMV & DMF的異同-->相同點: 以T-SQL方式查詢資料庫運作狀态的動态資訊 結果都以表的形式傳回  最大的差別: DMF需要提供一些參數來擷取不同的輸出

分類: DMV & DMF分成兩類-->伺服器範圍内 資料庫範圍内  存儲在Master資料庫的SYS架構中  命名規則: 以"dm_"開頭  共有85個,其中76個為DMV,9個為DMF

功能分組-->見下清單:

              dm_broker_* -                      與Service Broker有關的DMV

              dm_clr_* -                         與公共語言運作時有關的DMV

              dm_db_* -                          與資料庫有關的DMV

              dm_db_index_* -                    與索引有關的DMV & DMF

              dm_db_mirroring_*                  與資料庫鏡像有關的DMV

              dm_exec_* -                        與執行有關的DMV & DMF

              dm_fts_* -                         與全文搜尋有關的DMV

              dm_io_* -                          與I/O有關的DMV & DMF

              dm_os_* -                          與SQL作業系統有關的DMV

              dm_qn_* -                          與查詢通知有關的DMV

              dm_repl_* -                        與複制有關的DMV

              dm_tran_* -                        與事務有關的DMV

用法: 使用Select語句來查詢  與性能計數器類似,通過DMV & DMF檢索到的資訊也不是你通路當時的最新資訊。查詢的結果是動态的。使用兩部分、三部分或四部分所組成的名稱來引用  查詢MSDN幫助時需要使用兩部分命名法  任何動态對象在未來的SQLSERVER版本中可能會發生改變,是以任何涉及DMV及DMF的代碼可能需要重寫或棄用,如果Microsoft改變DMV或DMF。

權限: 授權通路-->SELECT  VIEW SERVER STATE  VIEW DATABASE STATE   禁止通路-->首先在master中建立使用者,然後拒絕該使用者對不希望被通路的動态管理視圖或函數的SELECT權限

如何檢視所有的DMV & DMF、擷取DMV的字段資訊、擷取DMF的參數資訊和授予權限呢?

資料庫維護管理和監視新特性

 1.如果你想檢視目前資料庫有那些DMV的話就把檢視所有的DMV & DMF的語句全選--按執行之後就可以看到總共有多少個DMV了  2.全選擷取DMV的字段資訊的語句--按執行之後就可以看到DMV字段的詳細資訊了  

資料庫維護管理和監視新特性

  全選擷取DMF的參數資訊的語句--按執行之後就可以看到DMF的參數資訊了 

資料庫維護管理和監視新特性

 展開SQL2005(本地計算機)--安全性--對着登入名右鍵--選擇建立登入名--登入名就叫做user1吧--選擇SQL Server身份驗證,輸入密碼--在預設資料庫裡面選擇AdventureWorks  按确定

資料庫維護管理和監視新特性

  展開資料庫--AdventureWorks--安全性--對着使用者右鍵--選擇建立使用者--使用者名就叫做user1吧--按确定

資料庫維護管理和監視新特性

  在對象資料總管裡面按連接配接--選擇資料庫引擎--在身份驗證裡面選擇SQL Server身份驗證--輸入登入名(user1)和密碼  按連接配接

資料庫維護管理和監視新特性

 展開資料庫--系統資料庫--對着master這個資料庫右鍵--選擇建立查詢--輸入select * from sys.dm_clr_tasks這條語句--按執行之後可以看到有一個提示-->使用者沒有執行此操作的權限  現在怎麼辦呢? 我們知道使用DMV需要有浏覽資料庫和伺服器的權限 此時我們需要增加一些權限

資料庫維護管理和監視新特性

  在對象資料總管裡面按連接配接--選擇資料庫引擎--在身份驗證裡面選擇Windows身份驗證--按連接配接

資料庫維護管理和監視新特性

  展開安全性--登入名--對着user1右鍵--選擇屬性--按安全對象--在安全對象裡面按添加--在要添加什麼對象裡面選擇特定類型的所有對象  按确定

資料庫維護管理和監視新特性

  在對象類型裡面把伺服器溝上  按确定

資料庫維護管理和監視新特性

 在SQL2005的顯式權限裡面把View server state的授予這一項權限溝上  按确定 

資料庫維護管理和監視新特性

  展開資料庫--系統資料庫--master--安全性--對着使用者右鍵--選擇建立使用者--使用者名和登入名都叫做user1吧  按确定

資料庫維護管理和監視新特性

 對着user1右鍵--選擇屬性--按安全對象--在安全對象裡面按添加--在要添加什麼對象裡面選擇特定類型的所有對象--按确定

資料庫維護管理和監視新特性

  在選擇要查找的對象類型裡面把資料庫溝上  按确定

資料庫維護管理和監視新特性

  在master的顯式權限裡面把View database state的授予這一項權限溝上  按确定 

資料庫維護管理和監視新特性

 按master這個資料庫--在查詢裡面輸入select * from sys.dm_clr_tasks這條語句--按執行之後可以看到現在已經不存在權限的問題了 可以看到目前的内容了 但是現在沒有clr這個任務的内容

DMV & DMF在診斷性能問題上的典型應用: SQL Server有關的性能問題-->資源瓶頸(CPU,memory,disk I/O and network) Tempdb瓶頸 使用者查詢  診斷瓶頸的相關工具-->System Monitor(PerfMon)  SQL Server Profiler  DBCC commands  DMVs & DMFs

應用之一: CPU瓶頸-->System Monitor: Processor: % Processor Time  可運作任務的數量-->見下清單:

                                                                     Select             Scheduler_id,

                                                                                        Current_tasks_count,

                                                                                        Runnable_tasks_count

                                                                      from              sys.dm_os_schedulers

                                                                      where             Scheduler_id<255

哪一組T-SQL或過程占用了最多的CPU時間-->見下列語句:

select top 50  sum(qs.total_worker_time)

            as total_cpu_time,

       sum(qs.execution_count)as

       total_execution_count, count(*)

       as number_of_statements,

       qs.plan_handle

from   sys.dm_exec_query_stats qs

group by qs.plan_handle

order by sum(qs.total_worker_time)desc

過度的編譯和重編譯問題引起的CPU性能問題: 導緻重編譯的原因-->架構的改變 統計資訊的改變 SET選項的改變 臨時表的改變 帶RECOMPILE選項的存儲過程  診斷-->System Monitor(Perfmon): SQL Server: SQL Statistics: Batch Requests/sec  SQL Server: SQL Statistics: SQL Compilations/sec  SQL Server: SQL Statistics: SQL Recompilations/sec

SQL Server Profiler: 跟蹤事件: SP: Recompile  SQL: StmtRecompile  對事件資料的分析-->見下列語句:

                                                                 select spid,  StartTime,  Textdata,

                                                                        EventSubclass,  ObjectID,

                                                                        DatabaseID,   SQLHandle

                                                                 from   fn_trace_gettable('e:/recompiletrace.trc',1)

                                                                 where  EventClass in(37,75,166)

使用DMVs-->select * from sys.dm_exec_query_optimizer_info

           select top 25   sql_text.text,   sql_handle,

             plan_generation_num,execution_count,

             dbid,   objectid

           from  sys.dm_exec_query_stats a

           cross apply sys.dm_exec_sql_text(sql_handle)as

              sql_text

           where   plan_generation_num>1

           order by plan_generation_num desc

發現過度重編譯的解決辦法-->避免在存儲過程中修改SET選項  避免在存儲過程中使用recompile,考慮改用語句級recompile選項  使用Database Engine Tuning Advisor(DTA)  關閉相關索引的自動更新統計資訊選項  ... 

應用之二: TempDB瓶頸-->Tempdb的用途  與Tempbdb有關的問題: 空間不足 查詢速度緩慢 大量的DDL/DML操作引起系統表的瓶頸問題  Tempbdb空間配置設定: 使用者對象 内部對象 版本存儲區 可用空間

診斷tempdb磁盤空間問題: SQL Server錯誤日志-->見下清單:

     錯誤                         引發錯誤的情況

  1101或1105                  任何會話都必須配置設定tempdb中的空間。

     3959                     版本存儲區已滿。此錯誤在日志中通常出現在錯誤1105或1101之後。

     3967                     由于tempdb已滿,版本存儲區被強制收縮。

  3958或3966                  事務在tempdb中找不到所需的版本記錄。

監視tempdb磁盤空間: 擷取Tempdb中的使用者對象,内部對象,版本存儲區使用的空間量以及可用空間量-->見下列語句:

                                                                 Select  SUM(user_object_reserved_page_count)*8

                                                                           as user_objects_kb,

                                                                       SUM(internal_object_reserved_page_count)*8

                                                                           as internal_objects_kb,

                                                                       SUM(version_store_reserved_page_count)*8

                                                                           as version_store_kb,

                                                                       SUM(unallocated_extent_page_count)*8

                                                                           as freespace_kb

                                                                  From     sys.dm_db_file_space_usage

                                                                  Where    database_id=2

輸出樣例: user_objects_kb  internal_objects_kb  version_store_kb  freespace_kb

          ------------     --------------      ------------       --------

          8736                    128            64                  448

如果版本存儲區使用了tempdb中的大量空間,則需要确定運作時間最長的事務。-->見下列語句:

SELECT transaction_id

FROM

  sys.dm_tran_active_snapshot_database_transactions

ORDER BY elapsed_time_seconds DESC;

使用大量空間的大型查詢-->擷取每個會話中目前運作的所有任務中的内部對象占用的空間-->見下列語句:

                                                        CREATE VIEW all_task_usage AS

                                                        SELECT session_id,

                                                          SUM(internal_objects_alloc_page_count)AS

                                                          task_internal_objects_alloc_page_count,

                                                          SUM(internal_objects_dealloc_page_count)

                                                          AS

                                                          task_internal_objects_dealloc_page_count

                                                         FROM sys.dm_db_task_space_usage

                                                         GROUP BY session_id;

擷取目前會話中正在運作的任務和已完成任務的内部對象占用的空間-->見下列語句:

CREATE VIEW all_session_usage

AS SELECT R1.session_id,

       R1.internal_objects_alloc_page_count+

       R2.task_internal_objects_alloc_page_count AS

       session_internal_objects_alloc_page_count,

       R1.internal_objects_dealloc_page_count+

       R2.task_internal_objects_dealloc_page_count

       AS

       session_internal_objects_dealloc_page_count

  FROM sys.dm_db_session_space_usage AS R1,

       all_task_usage AS R2

  WHERE R1.session_id=R2.session_id;

情景構設: Script 1: Create stored procedure

          USE AdventureWorks

          GO

CREATE PROCEDURE dbo.updater

AS

BEGIN TRAN

UPDATE Person.Contact WITH(HOLDLOCK)

SET FirstName = 'Justin'

WAITFOR DELAY '01:00:00'

ROLLBACK TRAN

GO

          Script 2: Execute Sp

            [email protected]@spid

            EXEC dbo.updater

          Script 3: Select the blocked table

            Select * from Person.Contact

擷取資訊: Script 4: What's going on

          DECLARE @sessionid INT

          SET @sessionid=54-to be changed

          DECLARE @sqlhandle VARBINARY(64)

          DECLARE @planhandle VARBINARY(64)

          SELECT @sqlhandle=sql_handle,@planhandle=plan_handle

          FROM sys.dm_exec_requests

          WHERE [email protected]

          SELECT * FROM sys.dm_exec_sql_text(@sqlhandle)

          SELECT * FROM sys.dm_exec_query_plan(@planhandle)

擷取答案: Script 5: Who blocked me

          SELECT  blocked_query.session_id AS blocked_session_id,

                  blocking_query.session_id AS blocking_session_id,

                  sql_text.text AS blocking_text,waits.wait_type AS

                  blocking_resource

          FROM  sys.dm_exec_requests blocked_query

          JOIN  sys.dm_exec_requests blocking_query ON

                blocked_query.blocking_session_id=blocking_query.session_id

          CROSS APPLY   

                  (SELECT*

                   FROM sys.dm_exec_sql_text(blocking_query.sql_handle)sql_text

          JOIN  sys.dm_os_waiting_tasks waits ON

                waits.session_id=blocking_query.session_id

資料庫維護管理和監視新特性

1.全選第一條語句--按執行來建立存儲過程  2.全選第二條語句--按執行之後就執行我們剛才建立的存儲過程了 如果執行select @@spid這條語句的話就可以看到目前會話的ID是56  3.全選第三條語句--按執行之後會發現查詢沒有響應

資料庫維護管理和監視新特性

 4.全選第四條語句--按執行之後可以看到這個存儲過程二條資訊了  按ShowPlanXML.xmlns="http://schemas.microsoft.com...來打開裡面的内容

資料庫維護管理和監視新特性

  按檔案--按儲存--我把它存儲在C槽裡面--檔案的擴充名叫做sqlplan--儲存類型為XML檔案(*.xml)--按儲存

資料庫維護管理和監視新特性

  打開C槽--把query_plan2.sqlplan.xml的擴充名修改成query_plan2.sqlplan

資料庫維護管理和監視新特性

  輕按兩下query_plan2.sqlplan這個檔案來打開它 可以看到不是剛才看到的XML格式的内容了而是圖形的格式了 讓大家了解這個查詢計劃是怎麼樣執行的

資料庫維護管理和監視新特性

 如果你想查詢究竟是什麼SQL阻塞了我的查詢的話  可以執行它的語句來檢視  5.全選第五條語句--按執行之後可以看到阻塞查詢的會話ID是55  55這個ID就是我查詢Select * from Person.Contact這條語句的會話ID 誰阻塞了55這個會話ID呢? 是56這個ID執行存儲過程阻塞的  它停留什麼資源呢?它運作了一條語句叫做WAITFOR這樣的等待一個小時的語句  大家可以看到DMV和DMF提供了一個非常詳細的資訊 可以非常友善地解決一個查詢沒有響應的問題

更多資訊...

    SQL Server 2005聯機叢書: SQL Server語言參考->Transact_SQL參考->系統視圖(Transact_SQL)->動态管理視圖和函數