Sql-Server

處理大型 .xel 文件(SQL Server 擴展事件日誌)的正確工具是什麼?

  • July 15, 2019

我的目標是審核一個實例上的所有查詢、誰在執行它們以及從哪裡執行、讀取多少次,以便在另一個實例上合併/遷移。

找出最好的方法是通過擴展事件到 .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"

引用自:https://dba.stackexchange.com/questions/206863