SQL Server中關於跟蹤(Trace)那點事

前言

一提到跟蹤倆字,很多人想到警匪片中的場景,同樣在我們的SQL Server數據庫中“跟蹤”也是無處不在的,如果我們利用好了跟蹤技巧,就可以針對某些特定的場景做定向分析,找出充足的證據來破案。

簡單的舉幾個應用場景:

在線生產庫爲何突然宕機?數百張數據表爲何不翼而飛?剛打好補丁的系統爲何屢遭黑手?新添加的信息表爲何頻頻丟失?某張表字段的突然更改,究竟爲何人所爲?這些個匿名的訪問背後,究竟是人是鬼?突然增加的增量數據,究竟是對是錯?數百兆的日誌爆炸式的增長背後又隱藏着什麼?這一且的背後,是應用程序的BUG還是用戶品質的缺失?

請關注本篇文章,讓我們一起利用數據庫的“跟蹤”(Trace)走進數據庫背後,查看其內部原理。

 

我相信如用過SQL Server數據庫的人,都會或多或少的利用過SQL Profiler工具。這個玩意就是利用SQL Trace形成的一個圖形化操作工具,我們直接進入本篇的正題。

 

一.查看系統默認跟蹤信息(Default Trace)

Trace作爲一個很好的數據庫追蹤工具,在SQL Server 2005中便集成到系統功能中去,並且默認是開啓的,當然我們也可以手動的關掉它,它位於sp_config配置參數中,我們可以通過以下語句查看:

select * from sys.configurations where configuration_id = 1568

我們也可以通過下面的語句找到這個跟蹤的記錄

select * from sys.traces

如果沒有開啓,我們也可以利用如下語句進行開啓,或者關閉等操作

複製代碼
--開啓Default Trace
sp_configure 'show advanced options' , 1 ;
GO
RECONFIGURE;
GO
sp_configure 'default trace enabled' , 1 ;
GO
RECONFIGURE;
GO

--測試是否開啓
EXEC sp_configure 'default trace enabled';
GO

--關閉Default Trace
sp_configure 'default trace enabled' , 0 ;
GO
RECONFIGURE;
GO
sp_configure 'show advanced options' , 0 ;
GO
RECONFIGURE;
GO
複製代碼

通過以下命令找到默認跟蹤的文件路徑

select * from ::fn_trace_getinfo(0)

以上命令返回的結果值,各個值(property)代表的含義如下:

第一個:2表示滾動文件;

第二個:表示當前使用的trace文件路徑,根據它我們可以找到其它的跟蹤文件,默認是同一目錄下

第三個:表示滾動文件的大小(單位MB),當到達這個值就會創建新的滾動文件

第四個:跟蹤的停止時間,這裏爲Null,表示沒有固定的停止時間

第五個:當前跟蹤的狀態:0 停止;1 運行

 

找到該目錄,我們查看下該文件:

系統默認提供5個跟蹤文件,並且每一個文件默認大小都是20MB,SQL Server會自己維護這5個文件,當實例重啓的時候或者到達最大值的時候,之後會重新生成新的文件,將最早的跟蹤文件刪除,依次滾動更新。

 

我們通過以下命令來查看跟蹤文件中的內容:

 默認的跟蹤文件,提供的跟蹤信息還是很全的,從中我們可以找到登錄人,操作信息等,上面的截圖只是包含的部分信息。我們可以利用該語句進行自己的加工,然後獲得更有用的信息。

複製代碼
--獲取跟蹤文件中前100行執行內容
SELECT TOP 100
 gt.[HostName] 
,gt.[ServerName] 
,gt.[DatabaseName] 
,gt.[SPID] 
,gt.[ObjectName] 
,gt.[objecttype] [ObjectTypeID] 
,sv.[subclass_name] [ObjectType] 
,e.[category_id] [CategoryID] 
,c.[Name] [Category] 
,gt.[EventClass] [EventID] 
,e.[Name] [EventName] 
,gt.[LoginName] 
,gt.[ApplicationName] 
,gt.[StartTime] 
,gt.[TextData] 
FROM fn_trace_gettable('E:\dataDefaultFileManger\MSSQL10.MSSQLSERVER\MSSQL\Log\log_1267.trc', DEFAULT) gt 
LEFT JOIN sys.trace_subclass_values sv 
ON gt.[eventclass] = sv.[trace_event_id] AND sv.[subclass_value] = gt.[objecttype] 
INNER JOIN sys.trace_events e 
ON gt.[eventclass] = e.[trace_event_id] 
INNER JOIN sys.trace_categories c 
ON e.[category_id] = c.[category_id] 
WHERE gt.[spid] > 50 AND --50以內的spid爲系統使用
    gt.[DatabaseName] = 'master' AND --根據DatabaseName過濾
    gt.[ObjectName] = 'fn_trace_getinfo' AND --根據objectname過濾
    e.[category_id]  = 5 AND --category 5表示對象,8表示安全
    e.[trace_event_id] = 46 
    --trace_event_id 
    --46表示Create對象(Object:Created),
    --47表示Drop對象(Object:Deleted),
    --93表示日誌文件自動增長(Log File Auto Grow),
    --164表示Alter對象(Object:Altered),
    --20表示錯誤日誌(Audit Login Failed)
ORDER BY [StartTime] DESC
複製代碼

 我創建了一張表,通過上面的跟蹤,可以跟蹤到該記錄的信息,根據不同的過濾信息,我們可以查詢出到跟蹤的某個庫的某個表的更改信息,包括:46創建(Created)、47刪除(Deleted)、93文件自動增長信息(Log File Auto Grow)、146修改(Alter)、20表示錯誤日誌(Login Failed)

 

在生產環境中,以上幾個分類都是比較常用的,對定位部分問題的定位能夠在找到充分的證據可循,比如某廝將數據庫數據刪除掉了還不承認等,這裏面的Login Failed信息,能夠追蹤出有那麼用戶嘗試登陸過數據庫,並且失敗,如果大面積的出現這種情況,那就要謹防黑客襲擊了。

 

當然,這裏我還可以利用SQL Server自帶的Profile工具,打開查看跟蹤文件中的內容。

這個圖像化的工具就比較熟悉了,直接打開進行篩選就可以了。

這種方式看似不錯,但是它也有本身的缺點,我們來看:

1、這5個文件是滾動更新的,而且每個文件默認最大都爲20MB,並且沒有提供更改的接口,所以當文件填充完之後就會刪除掉,所以會找不到太久以前的內容;

2、本身默認的跟蹤,只是提供一些關鍵信息的追蹤,其中包括:auditing events,database events,error events,full text events,object creation,object deletion,object alteration,想要找到其它更詳細的內容,此方式可能無能爲力;

3、在SQL Server2012後續版本的 Microsoft SQL Server 將刪除該功能,改用擴展事件。

 

二.自定義跟蹤信息(Default Trace)

根據上面SQL Server自帶的跟蹤信息有一些侷限性,SQL Server爲我們提供了自定義跟蹤的接口,我們可以自己定義跟蹤,充分擴展方法。

利用如下系統存儲過程,我們可以創建自定義的Trace

sp_trace_create [ @traceid = ] trace_id OUTPUT 
          , [ @options = ] option_value  
          , [ @tracefile = ] 'trace_file' 
     [ , [ @maxfilesize = ] max_file_size ]
     [ , [ @stoptime = ] 'stop_time' ]
     [ , [ @filecount = ] 'max_rollover_files' ]

@traceid  系統默認分配跟蹤的ID號

@options 指定爲跟蹤設置的選項,系統默認提供的幾個選項:

                  2表示當文件寫滿的時候,關閉當前跟蹤並創建新文件。

                  4表示如果不能將跟蹤寫入文件,不管什麼原因導致,SQL Server則會關閉。這個可以利用此選項,追蹤問題

                  8制定服務器產生的最後5MB的跟蹤信息記錄由服務器保存。

@tracefile 跟蹤文件的路徑,這裏可以是share的路徑

@maxfilesize 跟蹤文件的大小,單位是MB,默認不設置爲5MB

@stoptime 跟蹤停止的時間,利用它我們可以定時跟蹤結束的日期

@filecount 默認生產的跟蹤文件的數量,比如默認的爲5個,那就在第5個文件寫完的時候進行覆蓋第1個文件滾動

 

比如我們可以利用如下腳本進行創建 

複製代碼
--創建跟蹤文件返回值
declare @rc int
--創建一個跟蹤句柄
declare @TraceID int
--創建跟蹤文件路徑
declare @TraceFilePath nvarchar(500)
set @TraceFilePath=N'F:\SQLTest\'
--跟蹤文件的大小
declare @maxfilesize bigint
set @maxfilesize=5
--設置停止的時間
declare @EndTime datetime
set @EndTime=null
--設置系統默認的操作
declare @options int
set @options=2
--設置默認滾動文件的數目
declare @filecount int
set @filecount=5

exec @rc=sp_trace_Create
@TraceID output,
@options,
@TraceFilePath,
@maxfilesize,
@EndTime,
@filecount
if(@rc=0)
select  @TraceID
複製代碼

我們通過上面的跟蹤創建的過程,可以在系統自帶的默認的sys.traces中找到該跟蹤的明細

select * from sys.traces
where id=2

通過上面的腳本,我們已經創建了一個新的跟蹤(trace),但是這個跟蹤狀態爲0,也就是說還沒有運行,下面我們的步驟就是要爲這個跟蹤添加事件(event)

 

這個也是利用SQL Server爲我們提供的操作函數

sp_trace_setevent [ @traceid = ] trace_id  
          , [ @eventid = ] event_id 
          , [ @columnid = ] column_id 
          , [ @on = ] on

@traceid 要修改的跟蹤的 ID號

@eventid 要打開的事件的 ID

@columnid 要爲該事件添加的列的 ID

@on 表示事件狀態

其中最主要的就是時間ID,這個是SQL Server爲我們提供的一些列的碼錶時間值,具體值可以參考聯機叢書 sp_trace_setevent (Transact-SQL)

這裏面最常用的就是:

事件號

事件名稱

說明

10                 

RPC:Completed

在完成了遠程過程調用 (RPC) 時發生。

11

RPC:Starting

在啓動了 RPC 時發生。

12

SQL:BatchCompleted

在完成了 Transact-SQL 批處理時發生。

13

SQL:BatchStarting

在啓動了 Transact-SQL 批處理時發生。

14

Audit Login

在用戶成功登錄到 SQL Server 時發生。

15

Audit Logout

在用戶從 SQL Server 註銷時發生。

16

Attention

在發生需要關注的事件(如客戶端中斷請求或客戶端連接中斷)時發生。

17

ExistingConnection

檢測在啓動跟蹤前連接到 SQL Server 的用戶的所有活動。

18

Audit Server Starts and Stops

在修改 SQL Server 服務狀態時發生。

20

Audit Login Failed

指示試圖從客戶端登錄到 SQL Server 失敗。

21

EventLog

指示已將事件記錄到 Windows 應用程序日誌中。

22

ErrorLog

指示已將錯誤事件記錄到 SQL Server 錯誤日誌中。

23

Lock:Released

指示已釋放某個資源(如頁)的鎖。

24

Lock:Acquired

指示獲取了某個資源(如數據頁)的鎖。

25

Lock:Deadlock

指示兩個併發事務由於試圖獲得對方事務擁有的資源的不兼容鎖而發生了相互死鎖。

26

Lock:Cancel

指示已取消獲取資源鎖(例如,由於死鎖)。

27

Lock:Timeout

指示由於其他事務持有所需資源的阻塞鎖而使對資源(例如頁)鎖的請求超時。 超時由 @@LOCK_TIMEOUT 函數確定,並可用 SET LOCK_TIMEOUT 語句設置。

28

Degree of Parallelism Event(7.0 插入)

在執行 SELECT、INSERT 或 UPDATE 語句之前發生。

33

Exception

指示 SQL Server 中出現了異常。

34

SP:CacheMiss

指示未在過程緩存中找到某個存儲過程。

35

SP:CacheInsert

指示某個項被插入到過程緩存中。

36

SP:CacheRemove

指示從過程緩存中刪除了某個項。

37

SP:Recompile

指示已重新編譯存儲過程。

38

SP:CacheHit

指示在過程緩存中找到了存儲過程。

40

SQL:StmtStarting

在啓動了 Transact-SQL 語句時發生。

41

SQL:StmtCompleted

在完成了 Transact-SQL 語句時發生。

42

SP:Starting

指示啓動了存儲過程。

43

SP:Completed

指示完成了存儲過程。

44

SP:StmtStarting

指示已開始執行存儲過程中的 Transact-SQL 語句。

45

SP:StmtCompleted

指示存儲過程中的 Transact-SQL 語句已執行完畢。

46

Object:Created

指示 CREATE INDEX、CREATE TABLE 和 CREATE DATABASE 這樣的語句已創建了一個對象。

47

Object:Deleted

指示已在 DROP INDEX 和 DROP TABLE 這樣的語句中刪除了對象。

50

SQL Transaction

跟蹤 Transact-SQL BEGIN、COMMIT、SAVE 和 ROLLBACK TRANSACTION 語句。

51

Scan:Started

指示啓動了表或索引掃描

52

Scan:Stopped

指示停止了表或索引掃描。

53

CursorOpen

指示 ODBC、OLE DB 或 DB-Library 在 Transact-SQL 語句中打開了一個遊標。

54

TransactionLog

將事務寫入事務日誌時進行跟蹤。

55

Hash Warning

指示未在緩衝分區進行的某一哈希操作(例如,哈希聯接、哈希聚合、哈希 union 運算、哈希非重複)已恢復爲替換計劃。 發生此事件的原因可能是遞歸深度、數據扭曲、跟蹤標記或位計數。

58

Auto Stats

指示發生了自動更新索引統計信息。

59

Lock:Deadlock Chain

爲導致死鎖的每個事件而生成。

60

Lock:Escalation

指示較細粒度的鎖轉換成了較粗粒度的鎖(例如,頁鎖升級或轉換爲 TABLE 或 HoBT 鎖)。

61

OLE DB Errors

指示發生了 OLE DB 錯誤。

67

Execution Warnings

指示在執行 SQL Server 語句或存儲過程期間發生的任何警告。

68

Showplan Text (Unencoded)

顯示所執行 Transact-SQL 語句的計劃樹。

69

Sort Warnings

指示不適合內存的排序操作。 不包括與創建索引有關的排序操作;只包括某查詢內的排序操作(如 SELECT 語句中使用的 ORDER BY 子句)。

70

CursorPrepare

指示已準備了 ODBC、OLE DB 或 DB-Library 用於 Transact-SQL 語句的遊標。

71

Prepare SQL

ODBC、OLE DB 或 DB-Library 已準備好了一個或多個要使用的 Transact-SQL 語句。

72

Exec Prepared SQL

ODBC、OLE DB 或 DB-Library 已執行了一個或多個準備好的 Transact-SQL 語句。

73

Unprepare SQL

ODBC、OLE DB 或 DB-Library 已撤消(刪除)了一個或多個準備好的 Transact-SQL 語句。

74

CursorExecute

執行了先前由 ODBC、OLE DB 或 DB-Library 爲 Transact-SQL 語句準備的遊標。

75

CursorRecompile

由 ODBC 或 DB-Library 爲 Transact-SQL 語句打開的遊標已直接重新編譯或由於架構更改而重新編譯。

爲 ANSI 和非 ANSI 遊標觸發。

76

CursorImplicitConversion

SQL Server 將 Transact-SQL 語句的遊標從一種類型轉換爲另一種類型。

爲 ANSI 和非 ANSI 遊標觸發。

77

CursorUnprepare

ODBC、OLE DB 或 DB-Library 撤消(刪除)了準備好的 Transact-SQL 語句的遊標。

78

CursorClose

關閉了先前由 ODBC、OLE DB 或 DB-Library 爲 Transact-SQL 語句打開的遊標。

79

Missing Column Statistics

可能曾經對優化器有用的列統計信息不可用。

80

Missing Join Predicate

正在執行沒有聯接謂詞的查詢。 這可能導致長時間運行查詢。

81

Server Memory Change

SQL Server 內存的使用量已增加或減少了 1 MB 或最大服務器內存的 5%(兩者中較大者)。

82-91

User Configurable (0-9)

用戶定義的事件數據。

92

Data File Auto Grow

指示服務器已自動擴展了數據文件。

93

Log File Auto Grow

指示服務器已自動擴展了日誌文件。

94

Data File Auto Shrink

指示服務器已自動收縮了數據文件。

95

Log File Auto Shrink

指示服務器已自動收縮了日誌文件。

96

Showplan Text

顯示來自查詢優化器的 SQL 語句的查詢計劃樹。 請注意,TextData 列不包含此事件的顯示計劃。

97

Showplan All

顯示查詢計劃,並顯示已執行的 SQL 語句的完整編譯時詳細信息。 請注意,TextData 列不包含此事件的顯示計劃。

98

Showplan Statistics Profile

顯示查詢計劃,並顯示已執行的 SQL 語句的完整運行時詳細信息。 請注意,TextData 列不包含此事件的顯示計劃。

100

RPC Output Parameter

生成每個 RPC 的參數的輸出值。

108

Audit Add Login to Server Role Event

在從固定服務器角色添加或刪除登錄時發生;針對 sp_addsrvrolemembersp_dropsrvrolemember

112

Audit App Role Change Password Event

在更改應用程序角色的密碼時發生。

113

Audit Statement Permission Event

在使用語句權限(如 CREATE TABLE)時發生。

114

Audit Schema Object Access Event

在成功或未成功使用了對象權限(如 SELECT)時發生。

115

Audit Backup/Restore Event

在發出 BACKUP 或 RESTORE 命令時發生。

116

Audit DBCC Event

在發出 DBCC 命令時發生。

117

Audit Change Audit Event

在修改審覈跟蹤時發生。

118

Audit Object Derived Permission Event

在發出 CREATE、ALTER 和 DROP 對象命令時發生。

119

OLEDB Call Event

爲分佈式查詢和遠程存儲過程調用 OLE DB 訪問接口時發生。

120

OLEDB QueryInterface Event

爲分佈式查詢和遠程存儲過程調用 OLE DB QueryInterface 時發生。

121

OLEDB DataRead Event

對 OLE DB 訪問接口調用數據請求時發生。

122

Showplan XML

在執行 SQL 語句時發生。 包括該事件可以標識 Showplan 運算符。 每個事件都存儲在格式正確的 XML 文檔中。 請注意,此事件的 Binary 列包含已編碼的顯示計劃。 使用 SQL Server Profiler 可打開跟蹤並查看顯示計劃。

123

SQL:FullTextQuery

執行全文查詢時發生。

124

Broker:Conversation

報告 Service Broker 會話的進度。

125

Deprecation Announcement

使用將從 SQL Server 的未來版本中刪除的功能時發生。

126

Deprecation Final Support

使用將從 SQL Server 的下一個主版本中刪除的功能時發生。

127

Exchange Spill Event

tempdb 數據庫臨時寫入並行查詢計劃中的通信緩衝區時發生。

128

Audit Database Management Event

創建、更改或刪除數據庫時發生。

129

Audit Database Object Management Event

對數據庫對象(如架構)執行 CREATE、ALTER 或 DROP 語句時發生。

130

Audit Database Principal Management Event

創建、更改或刪除數據庫的主體(如用戶)時發生。

131

Audit Schema Object Management Event

創建、更改或刪除服務器對象時發生。

132

Audit Server Principal Impersonation Event

服務器範圍中發生模擬(如 EXECUTE AS LOGIN)時發生。

133

Audit Database Principal Impersonation Event

數據庫範圍中發生模擬(如 EXECUTE AS USER 或 SETUSER)時發生。

134

Audit Server Object Take Ownership Event

服務器範圍中的對象的所有者發生更改時發生。

135

Audit Database Object Take Ownership Event

數據庫範圍中的對象的所有者發生更改時發生。

136

Broker:Conversation Group

Service Broker 創建新的會話組或刪除現有會話組時發生。

137

Blocked Process Report

進程被阻塞的時間超過了指定的時間時發生。 不包括系統進程或正在等待未發現死鎖的資源的進程。 請使用 sp_configure 來配置生成報表時的閾值和頻率。

138

Broker:Connection

報告 Service Broker 管理的傳輸連接的狀態。

139

Broker:Forwarded Message Sent

Service Broker 轉發消息時發生。

140

Broker:Forwarded Message Dropped

Service Broker 刪除用於轉發的消息時發生。

141

Broker:Message Classify

Service Broker 確定消息的路由時發生。

142

Broker:Transmission

指示在 Service Broker 傳輸層中發生了錯誤。 錯誤號和狀態值指示了錯誤源。

143

Broker:Queue Disabled

指示檢測到有害消息,這是由於在 Service Broker 隊列中有五個連續的事務回滾。 該事件包含數據庫 ID 和包含有害消息的隊列的隊列 ID。

146

Showplan XML Statistics Profile

在執行 SQL 語句時發生。 標識 Showplan 運算符,並顯示完整的編譯時數據。 請注意,此事件的 Binary 列包含已編碼的顯示計劃。 使用 SQL Server Profiler 可打開跟蹤並查看顯示計劃。

148

Deadlock Graph

取消獲取鎖的嘗試時發生,這是因爲該嘗試是死鎖的一部分,並且被選爲死鎖犧牲品。 提供死鎖的 XML 說明。

149

Broker:Remote Message Acknowledgement

Service Broker 發送或收到消息確認時發生。

150

Trace File Close

跟蹤文件在回滾期間關閉時發生。

152

Audit Change Database Owner

使用 ALTER AUTHORIZATION 更改數據庫的所有者,並且檢查執行該操作的權限時發生。

153

Audit Schema Object Take Ownership Event

使用 ALTER AUTHORIZATION 來將所有者分配給對象,並且檢查執行該操作的權限時發生。

155

FT:Crawl Started

全文爬網(填充)開始時發生。 用於檢查工作線程任務是否拾取了爬網請求。

156

FT:Crawl Stopped

全文爬網(填充)停止時發生。 爬網成功完成或發生錯誤時停止。

157

FT:Crawl Aborted

在全文爬網過程中遇到異常時發生。 通常導致全文爬網停止。

158

Audit Broker Conversation

報告與 Service Broker 對話安全性相關的審覈消息。

159

Audit Broker Login

報告與 Service Broker 傳輸安全性相關的審覈消息。

160

Broker:Message Undeliverable

Service Broker 無法保留收到的消息時發生,該消息應當已傳遞給某個服務。

161

Broker:Corrupted Message

Service Broker 收到損壞的消息時發生。

162

User Error Message

顯示出現錯誤或異常時用戶看到的錯誤消息。

163

Broker:Activation

隊列監視器啓動激活存儲過程時,發送 QUEUE_ACTIVATION 通知時,或者隊列監視器啓動的激活存儲過程退出時發生。

164

Object:Altered

數據庫對象更改時發生。

165

Performance statistics

將經過編譯的查詢計劃第一次緩存、重新編譯或從計劃緩存中刪除時發生。

166

SQL:StmtRecompile

發生語句級別的重新編譯時發生。

167

Database Mirroring State Change

鏡像數據庫的狀態更改時發生。

168

Showplan XML For Query Compile

編譯 SQL 語句時發生。 顯示完整的編譯時數據。 請注意,此事件的 Binary 列包含已編碼的顯示計劃。 使用 SQL Server Profiler 可打開跟蹤並查看顯示計劃。

169

Showplan All For Query Compile

編譯 SQL 語句時發生。 顯示完整的編譯時數據。 用於標識 Showplan 運算符。

170

Audit Server Scope GDR Event

指示在服務器範圍中發生了權限的授予、拒絕或撤消事件(如創建登錄)。

171

Audit Server Object GDR Event

指示發生了對架構對象(如表或函數)的授予、拒絕或撤消事件。

172

Audit Database Object GDR Event

指示發生了對數據庫對象(如程序集和架構)的授予、拒絕或撤消事件。

173

Audit Server Operation Event

使用了安全審覈操作(如使用了更改設置、資源、外部訪問或授權)時發生。

175

Audit Server Alter Trace Event

檢查語句的 ALTER TRACE 權限時發生。

176

Audit Server Object Management Event

創建、更改或刪除服務器對象時發生。

177

Audit Server Principal Management Event

創建、更改或刪除了服務器主體時發生。

178

Audit Database Operation Event

發生數據庫操作(如檢查或訂閱查詢通知)時發生。

180

Audit Database Object Access Event

訪問數據庫對象(如架構)時發生。

181

TM: Begin Tran starting

BEGIN TRANSACTION 請求開始時發生。

182

TM: Begin Tran completed

BEGIN TRANSACTION 請求完成時發生。

183

TM: Promote Tran starting

PROMOTE TRANSACTION 請求開始時發生。

184

TM: Promote Tran completed

PROMOTE TRANSACTION 請求完成時發生。

185

TM: Commit Tran starting

COMMIT TRANSACTION 請求開始時發生。

186

TM: Commit Tran completed

COMMIT TRANSACTION 請求完成時發生。

187

TM: Rollback Tran starting

ROLLBACK TRANSACTION 請求開始時發生。

188

TM: Rollback Tran completed

ROLLBACK TRANSACTION 請求完成時發生。

189

Lock:Timeout (timeout > 0)

對資源(如頁)的鎖請求超時時發生。

190

Progress Report: Online Index Operation

報告生成進程正在運行時,聯機索引生成操作的進度。

191

TM: Save Tran starting

SAVE TRANSACTION 請求開始時發生。

192

TM: Save Tran completed

SAVE TRANSACTION 請求完成時發生。

193

Background Job Error

後臺作業不正常終止時發生。

194

OLEDB Provider Information

分佈式查詢運行並收集對應於提供程序連接的信息時發生。

195

Mount Tape

收到磁帶裝入請求時發生。

196

Assembly Load

發生加載 CLR 程序集的請求時發生。

198

XQuery Static Type

執行 XQuery 表達式時發生。 此事件類提供靜態類型的 XQuery 表達式。

199

QN: subscription

無法訂閱查詢註冊時發生。 TextData 列包含事件的有關信息。

200

QN: parameter table

有關活動訂閱的信息存儲在內部參數表中。 在創建或刪除參數表時發生該事件類。 通常,重新啓動數據庫時將創建或刪除這些表。 TextData 列包含事件的有關信息。

201

QN: template

查詢模板代表訂閱查詢的類。 通常,除參數值以外,相同類中的查詢是相同的。 當新的訂閱請求針對已存在的類 (Match)、新類 (Create) 或 Drop 類(指示清除沒有活動訂閱的查詢類的模板)時,發生此事件類。 TextData 列包含事件的有關信息。

202

QN: dynamics

跟蹤查詢通知的內部活動。 TextData 列包含事件的有關信息。

213

Database Suspect Data Page

指示何時將某頁添加到 msdbsuspect_pages 表。

214

CPU threshold exceeded

指示資源調控器檢測到查詢超過 CPU 閾值 (REQUEST_MAX_CPU_TIME_SEC) 的時間。

215

指示 LOGON 觸發器或資源調控器分類器函數開始執行的時間。

指示 LOGON 觸發器或資源調控器分類器函數開始執行的時間。

216

PreConnect:Completed

指示 LOGON 觸發器或資源調控器分類器函數完成執行的時間。

217

Plan Guide Successful

指示 SQL Server 已成功爲計劃指南中包含的查詢或批處理生成執行計劃。

218

Plan Guide Unsuccessful

指示 SQL Server 無法爲包含計劃指南的查詢或批處理生成執行計劃。 SQL Server 嘗試在不應用計劃指南的情況下爲此查詢或批處理生成執行計劃。 無效的計劃指南可能是導致此問題的原因。 您可以通過使用 sys.fn_validate_plan_guide 系統函數驗證該計劃指南。

 

上述的跟蹤事件中,基本包含了SQL Server中所能做的任何操作,我們可以根據自己需要進行定義,當我們可以針對日常經常遇到的一些問題進行定位,比如:死鎖、等待、登錄失敗等等吧...當然也可以追蹤某個人的所有行爲,這裏我們來定義幾個來看看

 

我們定義追蹤所有語句批量操作的追蹤,從上面表我們可以查找到爲12,13

exec sp_trace_setevent 2,12,1,1
exec sp_trace_setevent 2,13,1,1

 

通過如下存儲過程,將我們自定的追蹤啓動

--設置跟蹤狀態以啓動
exec sp_trace_setstatus @TraceID,1

至此,我們新建的追蹤已經開始運行了,我們可以利用上面的方法,來查看我們生成的追蹤文件了,其實大部分時候,我們都是利用此種方法設置好”圈套“,等待魚兒上網

比如死鎖查找,CPU消耗高,IO值高的那些語句....

 

我們可以利用如下語句,查找跟蹤文件的信息

--查看跟蹤文件以表顯示
select * from ::fn_trace_gettable('F:\SQLTest\.trc',1)

將我們剛纔的所有操作,已經追蹤出來了。

 

通過如下命令進行跟蹤的關閉

--設置跟蹤狀態以停止
exec sp_trace_setstatus @TraceID,0


通過如下命令進行跟蹤的刪除

--從系統中移除跟蹤
exec sp_trace_setstatus @TraceID,2


我們知道在SQL Server默認的跟蹤文件在實例重啓時候,都會消失,所以我們可以通過如下方法解決,保證在每次實例重新啓動的時候都會執行該追蹤

複製代碼
--新建追蹤的存儲過程
use master
go
create proc StartBlackBoxTrace
as
begin
    --默認開啓追蹤所有的SQL 執行語句,文件文件路徑爲默認
    DECLARE @TraceID int
    DECLARE @MaxFileSize bigint
    SET @MaxFileSize=25
    EXEC SP_TRACE_CREATE
    @TraceID OUTPUT,
    8,
    NULL,
    @MaxFileSize
    EXEC SP_TRACE_SETSTATUS @TraceID,1
END

--將該存儲過程設置爲SQL Server服務啓動時自動啓動
EXEC sp_procoption
'StartBlackBoxTrace','STARTUP','ON'
GO
複製代碼

 

通過如下腳本刪除到所有的跟蹤

複製代碼
create  proc [dbo].[Performance_Trace_StopAll]  
AS   
declare traceCursor cursor for 
select id from sys.traces where id <> 1   
open traceCursor   
    declare @curid int   
    fetch next from traceCursor 
    into @curid   
    while(@@fetch_status=0)  
    begin          
        exec  sp_trace_setstatus @curid,0  
        exec  sp_trace_setstatus @curid,2   
        fetch next from traceCursor into @curid   
    end   
close traceCursor   
deallocate traceCursor 
複製代碼

 

三.死鎖案例(2014年11月23日晚補充)

這裏我們來利用自己新建跟蹤來跟蹤一個死鎖的發生過程,並且將其記錄到我們的Trace文件中,這裏我們來製作一個死鎖

以上代碼參照院子裏大牛宋沄劍,這裏我們利用系統的自帶的profile進行設計追蹤,我們直接選擇系統自帶的死鎖模板,進行追蹤

然後設置,默認的SPID爲大於等於50,小於50的爲系統自有事件

然後,我們利用上面的死鎖腳本,運行獲取死鎖的捕捉

可以看到,我們已經順利的追蹤到這個死鎖。我們知道這種追蹤是高成本的,並且我們有時候不知道死鎖發生的具體時間,所以不能一直開着這個Profile,出於性能考慮也不建議這麼做,所以我們採用新建的Trace文件,來保存改腳本,然後重定向到我們自己的文件夾,將死鎖的信息放置到該文件夾下,提供更大靈活性。

SQL Server本身自帶的Profile工具就提供編輯腳本的功能,我們將上面的設計,導出成Trace腳本,我們點擊“文件”,導出該設計腳本

將該腳本保存到一個位置,然後我們打開,我順便將默認的文件路徑添加上

複製代碼
/****************************************************/
/* Created by: SQL Server 2008 Profiler             */
/* Date: 2014/11/23  20:28:11         */
/****************************************************/


-- Create a Queue
declare @rc int
declare @TraceID int
declare @maxfilesize bigint
--可以更改文件大小
set @maxfilesize = 5 

--默認死鎖文件放置目錄
declare @FilePath nvarchar(max)
set @FilePath=N'F:\SQLTest\DeadLock.trc'
-- Please replace the text InsertFileNameHere, with an appropriate
-- filename prefixed by a path, e.g., c:\MyFolder\MyTrace. The .trc extension
-- will be appended to the filename automatically. If you are writing from
-- remote server to local drive, please use UNC path and make sure server has
-- write access to your network share

exec @rc = sp_trace_create @TraceID output, 0, @FilePath, @maxfilesize, NULL 
if (@rc != 0) goto error

-- Client side File and Table cannot be scripted

-- Set the events
declare @on bit
set @on = 1
exec sp_trace_setevent @TraceID, 137, 15, @on
exec sp_trace_setevent @TraceID, 137, 32, @on
exec sp_trace_setevent @TraceID, 137, 1, @on
exec sp_trace_setevent @TraceID, 137, 13, @on
exec sp_trace_setevent @TraceID, 137, 22, @on
exec sp_trace_setevent @TraceID, 148, 11, @on
exec sp_trace_setevent @TraceID, 148, 12, @on
exec sp_trace_setevent @TraceID, 148, 14, @on
exec sp_trace_setevent @TraceID, 148, 1, @on
exec sp_trace_setevent @TraceID, 26, 15, @on
exec sp_trace_setevent @TraceID, 26, 32, @on
exec sp_trace_setevent @TraceID, 26, 1, @on
exec sp_trace_setevent @TraceID, 26, 9, @on
exec sp_trace_setevent @TraceID, 26, 57, @on
exec sp_trace_setevent @TraceID, 26, 2, @on
exec sp_trace_setevent @TraceID, 26, 10, @on
exec sp_trace_setevent @TraceID, 26, 11, @on
exec sp_trace_setevent @TraceID, 26, 35, @on
exec sp_trace_setevent @TraceID, 26, 12, @on
exec sp_trace_setevent @TraceID, 26, 13, @on
exec sp_trace_setevent @TraceID, 26, 6, @on
exec sp_trace_setevent @TraceID, 26, 14, @on
exec sp_trace_setevent @TraceID, 26, 22, @on
exec sp_trace_setevent @TraceID, 25, 15, @on
exec sp_trace_setevent @TraceID, 25, 32, @on
exec sp_trace_setevent @TraceID, 25, 1, @on
exec sp_trace_setevent @TraceID, 25, 9, @on
exec sp_trace_setevent @TraceID, 25, 57, @on
exec sp_trace_setevent @TraceID, 25, 2, @on
exec sp_trace_setevent @TraceID, 25, 10, @on
exec sp_trace_setevent @TraceID, 25, 11, @on
exec sp_trace_setevent @TraceID, 25, 35, @on
exec sp_trace_setevent @TraceID, 25, 12, @on
exec sp_trace_setevent @TraceID, 25, 13, @on
exec sp_trace_setevent @TraceID, 25, 6, @on
exec sp_trace_setevent @TraceID, 25, 14, @on
exec sp_trace_setevent @TraceID, 25, 22, @on
exec sp_trace_setevent @TraceID, 59, 32, @on
exec sp_trace_setevent @TraceID, 59, 1, @on
exec sp_trace_setevent @TraceID, 59, 57, @on
exec sp_trace_setevent @TraceID, 59, 2, @on
exec sp_trace_setevent @TraceID, 59, 14, @on
exec sp_trace_setevent @TraceID, 59, 22, @on
exec sp_trace_setevent @TraceID, 59, 35, @on
exec sp_trace_setevent @TraceID, 59, 12, @on
exec sp_trace_setevent @TraceID, 60, 32, @on
exec sp_trace_setevent @TraceID, 60, 9, @on
exec sp_trace_setevent @TraceID, 60, 57, @on
exec sp_trace_setevent @TraceID, 60, 10, @on
exec sp_trace_setevent @TraceID, 60, 11, @on
exec sp_trace_setevent @TraceID, 60, 35, @on
exec sp_trace_setevent @TraceID, 60, 12, @on
exec sp_trace_setevent @TraceID, 60, 6, @on
exec sp_trace_setevent @TraceID, 60, 14, @on
exec sp_trace_setevent @TraceID, 60, 22, @on
exec sp_trace_setevent @TraceID, 189, 15, @on
exec sp_trace_setevent @TraceID, 189, 32, @on
exec sp_trace_setevent @TraceID, 189, 1, @on
exec sp_trace_setevent @TraceID, 189, 9, @on
exec sp_trace_setevent @TraceID, 189, 57, @on
exec sp_trace_setevent @TraceID, 189, 2, @on
exec sp_trace_setevent @TraceID, 189, 10, @on
exec sp_trace_setevent @TraceID, 189, 11, @on
exec sp_trace_setevent @TraceID, 189, 35, @on
exec sp_trace_setevent @TraceID, 189, 12, @on
exec sp_trace_setevent @TraceID, 189, 13, @on
exec sp_trace_setevent @TraceID, 189, 6, @on
exec sp_trace_setevent @TraceID, 189, 14, @on
exec sp_trace_setevent @TraceID, 189, 22, @on
exec sp_trace_setevent @TraceID, 45, 16, @on
exec sp_trace_setevent @TraceID, 45, 1, @on
exec sp_trace_setevent @TraceID, 45, 9, @on
exec sp_trace_setevent @TraceID, 45, 17, @on
exec sp_trace_setevent @TraceID, 45, 10, @on
exec sp_trace_setevent @TraceID, 45, 18, @on
exec sp_trace_setevent @TraceID, 45, 11, @on
exec sp_trace_setevent @TraceID, 45, 35, @on
exec sp_trace_setevent @TraceID, 45, 12, @on
exec sp_trace_setevent @TraceID, 45, 13, @on
exec sp_trace_setevent @TraceID, 45, 6, @on
exec sp_trace_setevent @TraceID, 45, 14, @on
exec sp_trace_setevent @TraceID, 45, 22, @on
exec sp_trace_setevent @TraceID, 45, 15, @on
exec sp_trace_setevent @TraceID, 44, 1, @on
exec sp_trace_setevent @TraceID, 44, 9, @on
exec sp_trace_setevent @TraceID, 44, 10, @on
exec sp_trace_setevent @TraceID, 44, 11, @on
exec sp_trace_setevent @TraceID, 44, 35, @on
exec sp_trace_setevent @TraceID, 44, 12, @on
exec sp_trace_setevent @TraceID, 44, 6, @on
exec sp_trace_setevent @TraceID, 44, 14, @on
exec sp_trace_setevent @TraceID, 44, 22, @on
exec sp_trace_setevent @TraceID, 41, 15, @on
exec sp_trace_setevent @TraceID, 41, 16, @on
exec sp_trace_setevent @TraceID, 41, 1, @on
exec sp_trace_setevent @TraceID, 41, 9, @on
exec sp_trace_setevent @TraceID, 41, 17, @on
exec sp_trace_setevent @TraceID, 41, 10, @on
exec sp_trace_setevent @TraceID, 41, 18, @on
exec sp_trace_setevent @TraceID, 41, 11, @on
exec sp_trace_setevent @TraceID, 41, 35, @on
exec sp_trace_setevent @TraceID, 41, 12, @on
exec sp_trace_setevent @TraceID, 41, 13, @on
exec sp_trace_setevent @TraceID, 41, 6, @on
exec sp_trace_setevent @TraceID, 41, 14, @on
exec sp_trace_setevent @TraceID, 40, 1, @on
exec sp_trace_setevent @TraceID, 40, 9, @on
exec sp_trace_setevent @TraceID, 40, 6, @on
exec sp_trace_setevent @TraceID, 40, 10, @on
exec sp_trace_setevent @TraceID, 40, 14, @on
exec sp_trace_setevent @TraceID, 40, 11, @on
exec sp_trace_setevent @TraceID, 40, 35, @on
exec sp_trace_setevent @TraceID, 40, 12, @on


-- Set the Filters
declare @intfilter int
declare @bigintfilter bigint

exec sp_trace_setfilter @TraceID, 10, 0, 7, N'SQL Server Profiler - efbc9d24-69cd-465f-8daf-e38493da0332'
-- Set the trace status to start
exec sp_trace_setstatus @TraceID, 1

-- display trace id for future references
select TraceID=@TraceID
goto finish

error: 
select ErrorCode=@rc

finish: 
go
複製代碼

我們只需要將這個腳本運行就可以,當然此段腳本,在實例重啓的時候,所有的trace都會刪除掉,可以將該段代碼改成存儲過程,然後設置成實例啓動的時候運行,

方法參考本篇的上半部分。

當然我們也可以設置別的參數,比如啓動時間,運行時間,跟蹤文件大小,位置,數量等,刪除不必要的trace跟蹤事件...

當運行到一段時間之後,我們直接拷貝下來,找臺電腦分析就可以了。

更靈活的方式是採取非業務高峯期,利用SQL Server自帶的郵件提醒功能,直接檢測出問題,然後Send Email....

 

四.SQL Server中黑匣子(2014年11月28日晚補充)

黑匣子作爲飛機出現事故後的追蹤利器,在微軟的SQL Server這個數據庫中默認也給裝上了此引擎,但是沒有開啓,此功能可能幫助我們診斷間歇性的服務器崩潰。它比我們上面介紹的默認開啓的跟蹤跟蹤的信息更全,跟蹤更大一些。其內容包含了:“SP:啓動”、“SQL:批處理啓動”、異常和注意等事件

這個跟蹤通過在sp_trace_create的默認@option參數設置爲8來配置的。代碼如下:

DECLARE @Traced INT
EXEC sp_trace_create
@Traced OUTPUT,
@options=8
EXEC sp_trace_setstatus @Traced,1

通過以上的配置會自動配置成兩個滾動文件,當達到默認的最大文件容量5MB的時候,就在兩個文件中循環滾動依次更新。

當然如果感覺生成的文件5MB有點小,可以手動配置更改大小,或者自定義文件路徑,這些都是允許自定義設置的。

複製代碼
DECLARE @TraceID INT
DECLARE @maxfilesize BIGINT
SET @maxfilesize=25
DECLARE @tracefile nvarchar(245)
SET @tracefile=N'F:\SQLTest\TRACE\MYTRACE.trc'
EXEC sp_trace_create
@TraceID OUTPUT,
@options=8,
@tracefile=NULL,
@maxfilesize=@maxfilesize
EXEC sp_trace_setstatus @TraceID,1
複製代碼


此方法能將數據庫執行的所有SQL滾動記錄下來,以防止SQL Server宕機之後的事故查找。

參考我博文的上面介紹,只需要將這個方法存儲於存儲過程,然後設置成實例啓動後運行,那麼恭喜你的SQL Server已經成功裝上了黑匣子引擎,假如有一天突然宕機,我們只需要打開此黑匣子就可以。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章