Dot-Net

如何跟踪 SQL Server 跟踪中的呼叫程式碼?

  • August 7, 2011

我想使用 SQL Server 跟踪來跟踪有關哪些程式碼正在使用數據庫的更多上下文。我打算在連接字元串上使用“應用程序名稱”屬性。這看起來像下面這樣:

object CallingObject; //set elsewhere
SqlConnectionStringBuilder connectionString = GetConnectionString();
connectionString.ApplicationName = CallingObject.GetType().ToString();
using (SqlConnection connection = new SqlConnection(connectionString.ToString()))
{
   // do your thing
}

除了大量生成的連接字元串意味著.net 的連接池不再有效。

如何在 SQL 跟踪中跟踪呼叫程式碼而不失去連接池的好處?

只要您使用 SQL Server,並且只要您擁有(或可以擁有)集中式連接創建邏輯,就可以使用該CONTEXT_INFO功能:http: //msdn.microsoft.com/en-us/library/ms187768 .aspx

我們做這樣的事情來跟踪多使用者伺服器端應用程序中的數據庫連接。每次創建新的數據庫連接時(實際上是從連接池中重用,但在 ADODB/ADO.Net 程式碼中“創建”):

DECLARE @ContextInfoBinary binary(128); 
SET @ContextInfoBinary = Convert(Binary(128), 'XX' + Replicate(Char(0), 36) + 'Up to 90 characters of connection info - username, page, action, etc') 
SET CONTEXT_INFO @ContextInfoBinary

稍後,當您想“跟踪”連接時,可以將指定範圍的上下文資訊轉換回 VarChar 內容:

SELECT RTRIM(hostname) AS hostname
   , hostprocess
   , RTRIM(program_name) AS program_name
   , CASE 
       WHEN SubString(Context_Info, 1, 2) = 0x5858
           THEN Replace(Convert(VarChar(90), SubString(Context_Info, 39, 90)), CHAR(0), '')
       ELSE 'UNKNOWN' 
       END AS ExtendedConnectionDescription
   --More stuff here, depending on what you're looking for
FROM master.sys.sysprocesses 

一些考慮:

  • 由於應用程序名稱功能的連接池問題,我們專門轉向了這個概念。能夠在任何給定時間點跟踪特定使用者和程序的阻塞原因對我們來說很重要。
  • 這會為創建的每個連接添加一個要執行的 DB 命令- 這可能代表也可能不代表顯著成本,具體取決於您的應用程序設計
  • 此範例使用 VarChar(最多 90 個字元);如果您需要跟踪 NVarChar(擴展字元)數據,您的空間將減少到 45 個字元
  • 在這個例子中,我們留下了 36 個字節,這些字節可以用於其他目的,例如防止觸發器對某些連接執行。
  • 您可以使用 將值顯式輸出到跟踪sp_trace_generateevent,如以下相關問題中所述:How do you access the Context_Info() variable in SQL2005 Profiler?

更新:

只有在重新閱讀您的問題後,我才意識到您似乎只是明確地希望將資訊添加到 Traces,而不是對您目前連接的臨時分析(這更多是我與“應用程序名稱”的使用相關聯)與,對不起);我專門看到的唯一有用的方法是sp_trace_generateevent呼叫。如果您要這樣做,我建議您添加 connection_info,因為它不會再花費您(您已經有 db 往返sp_trace_generateevent)並且肯定會幫助您進行其他類型的分析稍後的。

引用自:https://stackoverflow.com/questions/6927245