處理大型 .xel 文件(SQL Server 擴展事件日誌)的正確工具是什麼?
我的目標是審核一個實例上的所有查詢、誰在執行它們以及從哪裡執行、讀取多少次,以便在另一個實例上合併/遷移。
找出最好的方法是通過擴展事件到 .xel 文件,超過 2 週,複製這些文件並在我精心設計的桌面上進行分析。使用最少數量的細節(欄位)設置擷取,所以真的不能讓它比這更小 - 12 個文件中大約 12GB。在 SSMS 中使用“合併擴展事件文件”來載入 .xel 文件和過程,詳見https://docs.microsoft.com/en-us/sql/relational-databases/extended-events/advanced-viewing-of-來自擴展事件的目標數據在 sql-server?view=sql-server-2017
這真的是最好的方法嗎?有沒有更好的工具來載入文件?SSMS 17.7真的很慢- 範例:到目前為止只有 4 個過濾器(在進入分組和聚合之前)需要 12 多小時才能處理 50% 的日誌。
對於大型 XE 跟踪文件,我使用帶有QueryableXEventData的自定義工具。我發現這比 T-SQL 中的 XML 解析要快得多。
下面是一個基本的 PowerShell,它將
rpc_completed
事件跟踪中的選定欄位和操作以 10K 批次的形式導入到表中。您需要為和程序集包含一個Add-Type
命令,該命令將位於您的 SQL Server 安裝文件夾中,其確切位置將根據 SQL 版本和選擇的安裝位置而有所不同。Microsoft.SqlServer.XE.Core.dll``Microsoft.SqlServer.XEvent.Linq.dll
$SharedPath = "C:\Program Files\Microsoft SQL Server\140\Shared"; $SqlInstanceName = ""; $xeCore = [System.IO.Path]::Combine($SharedPath, "Microsoft.SqlServer.XE.Core.dll"); $xeLinq = [System.IO.Path]::Combine($SharedPath, "Microsoft.SqlServer.XEvent.Linq.dll"); Add-Type -Path $xeLinq; if( [System.IO.File]::Exists($xeCore) ) { Add-Type -Path $xeCore; }
請注意,該類中有單獨的 Fields 和 Actions 集合,
PublishedEvent
因此您需要從適當的連接中提取值。# create target table $connectionString = "Data Source=.;Initial Catalog=tempdb;Integrated Security=SSPI" $connection = New-Object System.Data.SqlClient.SqlConnection($connectionString) $command = New-Object System.Data.SqlClient.SqlCommand(@" CREATE TABLE dbo.rpc_completed( event_name sysname , timestamp datetimeoffset , statement nvarchar(MAX) , username nvarchar(256) ); "@, $connection) $connection.Open() [void]$command.ExecuteNonQuery() $connection.Close() # data table for SqlBulkCopy $dt = New-Object System.Data.DataTable [void]$dt.Columns.Add("event_name", [System.Type]::GetType("System.String")) $dt.Columns["event_name"].MaxLength = 256 [void]$dt.Columns.Add("timestamp", [System.Type]::GetType("System.DateTimeOffset")) [void]$dt.Columns.Add("statement", [System.Type]::GetType("System.String")) [void]$dt.Columns.Add("username", [System.Type]::GetType("System.String")) $dt.Columns["username"].MaxLength = 128 $dt.Columns["statement"].MaxLength = -1 $events = new-object Microsoft.SqlServer.XEvent.Linq.QueryableXEventData("D:\TraceFiles\Log\rpc_completed*.xel") # import XE events from file(s) $bcp = New-Object System.Data.SqlClient.SqlBulkCopy($connectionString) $bcp.DestinationTableName = "dbo.rpc_completed" $eventCount = 0 foreach($event in $events) { $eventCount += 1 $row = $dt.NewRow() $dt.Rows.Add($row) $row["event_name"] = $event.Name $row["timestamp"] = $event.Timestamp $row["statement"] = $event.Fields["statement"].Value # username is a collected action $row["username"] = $event.Actions["username"].Value if($eventCount % 10000 -eq 0) { $bcp.WriteToServer($dt) $dt.Rows.Clear() } } $bcp.WriteToServer($dt) # write last batch Write-Host "$eventCount records imported"