快速入門:擴充事件

適用於:SQL ServerAzure SQL 資料庫Azure SQL 受控執行個體

擴充事件是輕量的效能監視系統,可讓使用者收集用於監視問題及對其進行疑難排解的資料。 藉由使用擴充事件,您可以看到資料庫引擎內部作業的詳細資料,這些作業與效能監視和疑難排解用途相關。 如需深入了解擴充事件,請參閱擴充事件概觀

本文旨在協助不熟悉擴充事件的 SQL 系統管理員、工程師和開發人員,以及想要在短短幾分鐘內開始使用事件資料的人員。

擴充事件也稱為 XEvents,有時簡稱 XE

閱讀本文之後,您可以:

  • 了解如何在 SQL Server Management Studio (SSMS) 中建立事件工作階段,並顯示範例螢幕擷取畫面
  • 將螢幕擷取畫面相互關聯至對等的 Transact-SQL 陳述式
  • 詳細了解 SSMS 使用者介面和 XEvents T-SQL 陳述式背後的詞彙和概念
  • 了解如何測試您的事件工作階段
  • 了解工作階段結果,包括:
    • 結果儲存體的可用選項
    • 已處理的結果與未經處理的結果比較
    • 以不同的方式及不同的時間間隔檢視結果的工具
  • 示範如何搜尋及探索所有可用的事件
  • 了解擴充事件系統檢視之間的關聯性

提示

如需 Azure SQL 資料庫中擴充事件的詳細資訊 (包括程式碼範例),請參閱 SQL Database 中的擴充事件

初始必要條件

若要開始,您需要:

  1. 下載 SQL Server Management Studio (SSMS). 建議使用最新版本的 SSMS 搭配最新的改進功能和修正。
  2. 確定您的帳戶具有 ALTER ANY EVENT SESSION伺服器權限

此文章結尾的附錄將提供擴充事件之相關安全性和權限的詳細資料。

SSMS 中的擴充事件

SSMS 提供擴充事件的完整功能使用者介面 (UI)。 許多案例都可使用此 UI 來完成,而不需要使用 T-SQL 或動態管理檢視 (DMV)。

在本節中,您會看到建立擴充事件工作階段的 UI 步驟,以及它所報告的資料。 完成這些步驟實作或檢閱本文中的步驟之後,您可閱讀步驟中相關概念,以便更深入地了解。

在 SSMS 中建立事件工作階段

在建立擴充事件工作階段時,即是告訴系統:

  • 您感興趣的事件
  • 系統要如何回報資料給您

示範會開啟 [新增工作階段] 對話方塊,顯示如何使用其四個頁面,名稱如下:

  • 一般
  • 事件
  • 資料儲存體
  • 進階

SSMS 版本中的文字和支援螢幕擷取畫面可能略有差異,但仍應與基本概念的說明相關。

  1. 連接到資料庫引擎執行個體。 SQL Server 2014 以上版本、Azure SQL 資料庫和 Azure SQL 受控執行個體支援擴充事件。

  2. 在物件總管中,選取 [管理 > 擴充事件]。 在 Azure SQL 資料庫中,事件工作階段設定資料庫範圍,因此在每一個資料庫下可找到 [擴充事件] 選項,而不是 [管理] 下。 以滑鼠右鍵按一下 [工作階段] 資料夾,然後選取 [新增工作階段]。 使用 [新增工作階段] 對話方塊會比使用 [新增工作階段精靈] 更合適,但兩者類似。

  3. 在左上方,選取 [一般] 頁面。 然後在 [工作階段名稱] 文字輸入框中,輸入 YourSession,或者任何您想要的名稱。 尚未選取 [確定],因為您仍需要在其他頁面上輸入一些詳細資料。

    Screenshot of New Session > General > Session name.

  4. 在左上方,選取 [事件] 頁面。

    Screenshot of New Session > Events > Select > Event library, Selected events.

  5. 在 [事件程式庫] 區域的下拉式清單中,選擇 [僅限事件名稱]

    • 在文字輸入框中輸入 sql_statement_。 這會篩選清單,以僅顯示名稱中的 sql_statement_ 事件。
    • 捲動並選取名稱為 sql_statement_completed 的事件。
    • 選取向右鍵按鈕 >,將事件移至 [選取的事件] 方塊。
  6. 事件頁面上,選取右上方的設定按鈕。 這會開啟所選事件的 [事件組態選項] 方塊。

    Screenshot of New Session > Events > Configure > Filter (Predicate) > Field.

  7. 選取 [篩選條件 (述詞)] 索引標籤。接下來,選取 [選取這裡以新增子句]。 我們會設定此篩選條件 (也稱為述詞),以擷取包含 HAVING 子句的所有 SELECT 陳述式。

  8. 在 [欄位] 下拉式清單中,選擇 sqlserver.sql_text

    • 針對 [運算子],選擇 like_i_sql_unicode_string。 這裡,運算子名稱中的 i 表示不區分大小寫。
    • 針對 [值],輸入 %SELECT%HAVING%。 這裡,百分比符號是代表任何字元字串的萬用字元。

    注意

    在這個兩部分欄位名稱中,sqlserver 是套件名稱,而 sql_text 是欄位名稱。 我們稍早所選的事件 sql_statement_completed,必須和我們選擇的欄位在同一套件中。

  9. 在左上方,選取 [資料存放區] 頁面。

  10. 在 [目標] 區域中,選取 [選取此處以新增目標]

    • 在 [類型] 下拉式清單中,選擇 event_file。 這表示事件資料將會存放在我們稍後可開啟並檢視的檔案中。 在 Azure SQL 資料庫或 Azure SQL 受控執行個體中,事件資料存放在 Azure 儲存體 Blob 中。

    注意

    自 SQL Server 2019 開始,您可在 SQL Server 的 event_file 目標中使用 Azure Blob 儲存體。

    Screenshot of New Session > Data Storage > Targets > Type > event_file.

  11. 在 [屬性] 區域的 [伺服器上的檔案名稱] 文字輸入框中,輸入完整路徑和檔案名稱。 您還可使用 [瀏覽] 按鈕。 副檔名必須是 xel。 在我們的範例中,我們使用 C:\Temp\YourSession_Target.xel

    Screenshot of New Session > Advanced > Maximum dispatch latency > OK.

  12. 在左上方,選取 [進階] 頁面。 將 [分派延遲上限] 減少為 3 秒。

  13. 選取底部的 [確定] 按鈕,以建立此事件工作階段。

  14. 回到物件總管,開啟或重新整理 [工作階段] 資料夾,並查看 YourSession 的新節點。 工作階段尚未啟動。 您稍後會啟動。

    Screenshot of Node for your new *event session* named YourSession, in the Object Explorer, under Management > Extended Events > Sessions.

在 SSMS 中編輯事件工作階段

在 SSMS 物件總管中,您可以編輯事件工作階段,方法是以滑鼠右鍵按一下其節點,然後按一下 [屬性]。 這會顯示相同的多頁對話方塊。

使用 T-SQL 建立事件工作階段

在 SSMS 擴充事件 UI 中,您可以產生 T-SQL 指令碼來建立事件工作階段,如下所示:

  • 以滑鼠右鍵按一下事件工作階段節點,然後選取 [將工作階段指令碼設定為 > CREATE 至 > 剪貼板]
  • 貼到任何文字編輯器中。

以下是針對 YourSession 產生的 CREATE EVENT SESSION T-SQL 陳述式:

CREATE EVENT SESSION [YourSession]
    ON SERVER -- For SQL Server and Azure SQL Managed Instance
    -- ON DATABASE -- For Azure SQL Database
    ADD EVENT sqlserver.sql_statement_completed
    (
        ACTION(sqlserver.sql_text)
        WHERE
        ( [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text], N'%SELECT%HAVING%')
        )
    )
    ADD TARGET package0.event_file
    (SET
        filename = N'C:\Temp\YourSession_Target.xel',
        max_file_size = (2),
        max_rollover_files = (2)
    )
    WITH (
        MAX_MEMORY = 2048 KB,
        EVENT_RETENTION_MODE = ALLOW_MULTIPLE_EVENT_LOSS,
        MAX_DISPATCH_LATENCY = 3 SECONDS,
        MAX_EVENT_SIZE = 0 KB,
        MEMORY_PARTITION_MODE = NONE,
        TRACK_CAUSALITY = OFF,
        STARTUP_STATE = OFF
    );
GO

事件工作階段的條件式 DROP

CREATE EVENT SESSION 陳述式之前,您能夠有條件地執行 DROP EVENT SESSION 陳述式,以免使用相同名稱的工作階段已經存在。 這會刪除現有的工作階段。 若未執行此操作,嘗試建立使用相同名稱的工作階段會引起錯誤。

IF EXISTS (SELECT *
      FROM sys.server_event_sessions
      WHERE name = 'YourSession')
BEGIN
    DROP EVENT SESSION YourSession
          ON SERVER;
END
GO

使用 T-SQL 啟動和停止事件工作階段

當您建立事件工作階段時,預設為無法自動開始執行。 您可使用下列 ALTER EVENT SESSION T-SQL 陳述式,隨時啟動或停止事件工作階段。

ALTER EVENT SESSION [YourSession]
      ON SERVER
    STATE = START; -- STOP;

啟動資料庫引擎執行個體之後,您可以選擇設定事件工作階段自動啟動。 請參閱 STARTUP STATE = ON 中的 CREATE EVENT SESSION 關鍵詞。

SSMS UI 會在 [新增工作階段 > 一般] 頁面上提供對應的核取方塊:[在伺服器啟動時啟動事件工作階段]

測試事件工作階段

利用下列步驟來測試您的事件工作階段:

  1. 在物件總管中,以滑鼠右鍵按一下您的事件工作階段節點,然後選取 [啟動工作階段]
  2. 當連線至您建立事件工作階段的相同伺服器 (或 Azure SQL 資料庫 中的相同資料庫) 時,請執行下列 SELECT...HAVING 陳述式數次。 請考慮針對每次執行來變更 HAVING 子句中的值,在 2 和 3 之間切換。 這可讓您查看不同的結果。
  3. 以滑鼠右鍵按一下您的工作階段節點,然後選取 [停止工作階段]
  4. 閱讀下一小節有關 如何 SELECT 並檢視結果的相關資訊。
SELECT
        c.name,
        Count(*)  AS [Count-Per-Column-Repeated-Name]
    FROM
             sys.syscolumns  AS c
        JOIN sys.sysobjects  AS o
            ON o.id = c.id
    WHERE
        o.type = 'V'
        AND
        c.name like '%event%'
    GROUP BY
        c.name
    HAVING
        Count(*) >= 3   --2     -- Try both values during session.
    ORDER BY
        c.name;

如需了解完整性,請參閱上述 SELECT...HAVING 的範例輸出。

/* Approximate output, 6 rows, all HAVING Count >= 3:
name                   Count-Per-Column-Repeated-Name
---------------------  ------------------------------
event_group_type       4
event_group_type_desc  4
event_session_address  5
event_session_id       5
is_trigger_event       4
trace_event_id         3
*/

以 XML 檢視事件工作階段資料

在 SSMS 的查詢視窗中,執行下列 SELECT 陳述式,以查看依工作階段擷取的事件資料。 每個資料列代表一次發生事件。 CAST(... AS xml) 會將資料行的資料類型從 nvarchar 變更為 xml。 這可讓您選取資料行值,以在新視窗中開啟,便於讀取。

注意

event_file 目標一律會在 xel 檔案名稱中插入數值部分。 您必須先複製包含此數值部分的 xel 檔案的實際全名,然後將其貼至 SELECT 陳述式中,才能執行下列查詢。 在下列範例中,數值部分為 _0_131085363367310000

SELECT
        object_name,
        file_name,
        file_offset,
        event_data,
        'CLICK_NEXT_CELL_TO_BROWSE_XML RESULTS!'
                AS [CLICK_NEXT_CELL_TO_BROWSE_XML_RESULTS],
        CAST(event_data AS xml) AS [event_data_XML]
                -- TODO: In the SSMS results grid, click this XML cell
    FROM
        sys.fn_xe_file_target_read_file(
            'C:\Temp\YourSession_Target_0_131085363367310000.xel',
            null, null, null
        );

此查詢提供兩種方式,來檢視任何指定事件資料列的完整結果:

  • 在 SSMS 中執行 SELECT,然後選取 event_data_XML 資料行中的資料格。

  • event_data 資料行的資料格中,複製 XML 字串。 貼至任何文字編輯器中 (例如記事本),並儲存在副檔名為 xml 的檔案。 然後在瀏覽器,或能夠顯示 XML 資料的編輯器中開啟檔案。

XML 中的事件資料

接下來,我們將看到以 XML 格式表示的部分結果。 為簡潔起見,這裡的 XML 會在此編輯。 <data name="row_count"> 顯示值為 6,符合稍早所顯示的六個結果資料列。 此外,我們也會看到整個 SELECT 陳述式。

<event name="sql_statement_completed" package="sqlserver" timestamp="2016-05-24T04:06:08.997Z">
  <data name="duration">
    <value>111021</value>
  </data>
  <data name="cpu_time">
    <value>109000</value>
  </data>
  <data name="physical_reads">
    <value>0</value>
  </data>
  <data name="last_row_count">
    <value>6</value>
  </data>
  <data name="offset">
    <value>0</value>
  </data>
  <data name="offset_end">
    <value>584</value>
  </data>
  <data name="statement">
    <value>SELECT
        c.name,
        Count(*)  AS [Count-Per-Column-Repeated-Name]
    FROM
             sys.syscolumns  AS c
        JOIN sys.sysobjects  AS o

            ON o.id = c.id
    WHERE
        o.type = 'V'
        AND
        c.name like '%event%'
    GROUP BY
        c.name
    HAVING
        Count(*) &gt;= 3   --2     -- Try both values during session.
    ORDER BY
        c.name</value>
  </data>
</event>

在 SSMS 中顯示事件工作階段資料

您可以使用 SSMS UI 中的幾項進階功能,來檢視擴充事件擷取的資料。 如需詳細資訊,請參閱檢視 SQL Server Management Studio 中的事件資料

您會從標示為 [檢視目標資料]和 [監看即時資料] 的操作特色選單開始。

檢視目標資料

在 SSMS 物件總管中,以滑鼠右鍵按一下您的事件工作階段節點下的目標節點。 在特色選單中,選取 [檢視目標資料]。 SSMS 會隨即顯示資料。

在工作階段中發生新事件時,不會更新顯示。 但您可以再次選取 [檢視目標資料]

Screenshot of View Target Data, in SSMS, Management > Extended Events > Sessions > YourSession > package0.event_file, right-click.

監看即時資料

在 SSMS 物件總管中,以滑鼠右鍵按一下您的事件工作階段節點。 在特色選單中,選取 [監看即時資料]。 SSMS 會即時顯示持續送達的內送資料。

Screenshot of Watch Live Data, in SSMS, Management > Extended Events > Sessions > YourSession, right-click.

擴充事件的詞彙和概念

下表列出用於擴充事件的詞彙,並說明其意義。

詞彙 描述
event session 目標為以一或多項事件為主的建構,加上支援的項目 (例如動作)。 CREATE EVENT SESSION 陳述式會建立每個事件工作階段。 您可以隨意 ALTER 事件工作階段,以開始和停止工作階段。

如果內容釐清其表示「事件工作階段」 ,事件工作階段有時簡稱為「工作階段」 。

如需事件工作階段的詳細資料,請參閱:擴充事件工作階段
event 使用中的事件工作階段在系統中監看的特定項目。

例如,sql_statement_completed 事件代表任何指定 T-SQL 陳述式完成的時間點。 此事件會報告其持續時間和其他資料。
target 從所擷取的事件接收輸出資料的項目。 此目標會向您顯示資料。

範例包括 event_file 本快速入門稍早使用的 ring_buffer 目標,以及將最新的事件保留在記憶體中的 目標。

任何類型的目標都可用於任何事件工作階段。 如需詳細資料,請參閱擴充事件的目標
action 事件已知的欄位。 此欄位中的資料會傳送至目標。 [動作] 欄位與「述詞篩選條件」 密切相關。
predicate,或篩選條件 事件欄位中的資料測試,以此方式使用時,只會將相關事件項目子集傳送至目標。

例如,篩選可以只包含 sql_statement_completed 事件項目,其中 T-SQL 陳述式內含字串 HAVING
package 附加至一組項目中每個項目的名稱限定詞,此限定詞是以事件核心為主。

例如,封裝可能會有 T SQL 文字的相關事件。 一個事件可以與批次中的所有 T-SQL 相關。 同時有另一個範圍較小的事件與個別 T-SQL 陳述式相關。 此外,任何一個 T-SQL 陳述式都會有 startedcompleted 事件。

事件的適當欄位也會與事件一起封裝。 大多數目標會在 package0 中,並可搭配許多其他封裝中的事件使用。

擴充事件案例和使用方式詳細資料

使用擴充事件來監視和疑難排解資料庫引擎和查詢工作負載,有許多案例。 下列文章提供使用鎖定相關案例的範例:

如何探索封裝中可用的事件

下列查詢會針對每個可用的事件傳回一個資料列,其名稱包含三個字元字串 sql。 您可以編輯 LIKE 子句,來搜尋不同的事件名稱。 結果集也會識別包含事件的封裝。

SELECT -- Find an event you want.
    p.name AS [Package-Name],
    o.object_type,
    o.name AS [Object-Name],
    o.description AS [Object-Descr],
    p.guid AS [Package-Guid]
FROM sys.dm_xe_packages AS p
INNER JOIN sys.dm_xe_objects AS o
    ON p.guid = o.package_guid
WHERE o.object_type = 'event' --'action'  --'target'
    AND p.name LIKE '%'
    AND o.name LIKE '%sql%'
ORDER BY p.name,
    o.object_type,
    o.name;

下列結果範例顯示傳回的資料列,並在此處格式 column name = value 的樞紐作業。 此資料來自上述範例步驟中所使用的 sql_statement_completed 事件。 物件的描述 (在此範例中為事件) 可充當文件字串。

Package-Name = sqlserver
object_type  = event
Object-Name  = sql_statement_completed
Object-Descr = Occurs when a Transact-SQL statement has completed.
Package-Guid = 655FD93F-3364-40D5-B2BA-330F7FFB6491

使用 SSMS UI 尋找事件

另一個依名稱尋找事件的選項是,使用 [新增工作階段 > 事件 > 事件程式庫] 對話方塊,如上述螢幕擷取畫面所示。 您可以輸入部份事件名稱,並尋找所有相符的事件名稱。

SQL 追蹤事件類別

如需搭配 SQL 追蹤事件類別和資料行使用擴充事件的說明,請參閱:檢視同等於 SQL 追蹤事件類別的擴充事件

Windows 事件追蹤 (ETW)

如需搭配 Windows 事件追蹤 (ETW) 使用擴充事件的說明,請參閱:

系統事件工作階段

在 SQL Server 和 Azure SQL 受控執行個體中,預設會建立數個系統事件工作階段,並設定為在啟動資料庫引擎時啟動。 與大多數事件工作階段一樣,它們會取用少量資源,而且不會大幅影響工作負載效能。 Microsoft 建議這些工作階段保持啟用並執行。 健康情況工作階段,特別是 system_health 工作階段,通常適用於監視和疑難排解。

您會在 SSMS 物件總管的 [管理 > 擴充事件 > 工作階段] 下,看到這些事件工作階段。 例如,在 SQL Server 中,這些系統事件工作階段如下:

  • AlwaysOn_health
  • system_health
  • telemetry_events

PowerShell 提供者

您可以使用 SQL Server PowerShell 提供者來管理擴充事件。 如需詳細資訊,請參閱 針對擴充事件使用 PowerShell 提供者

系統檢視表

擴充事件的系統檢視表包括:

  • 目錄檢視:了解有關 CREATE EVENT SESSION 定義之事件工作階段的相關資訊。
  • 動態管理檢視 (DMV):了解有關作用中 (已啟動) 事件工作階段的相關資訊。

SQL Server 擴充事件系統檢視表中的 SELECT 和 JOIN 提供下列相關資訊:

  • 如何聯結檢視
  • 基於這些檢視的數個實用查詢
  • 下列項目之間的相互關聯:
    • 檢視資料行
    • CREATE EVENT SESSION 子句
    • SSMS UI

附錄:尋找擴充事件權限持有人的查詢

本文中提到的權限包括:

  • ALTER ANY EVENT SESSION
  • VIEW SERVER STATE
  • CONTROL SERVER

下列 SELECT...UNION ALL 陳述式會傳回資料列,顯示哪些人員具有建立事件工作階段,以及查詢系統目錄檢視中的擴充事件時所需的權限。

-- Ascertain who has the permissions listed in the ON clause.
-- 'CONTROL SERVER' permission includes the permissions
-- 'ALTER ANY EVENT SESSION' and 'VIEW SERVER STATE'.
SELECT 'Owner-is-Principal' AS [Type-That-Owns-Permission],
    NULL AS [Role-Name],
    prin.name AS [Owner-Name],
    PERM.permission_name COLLATE Latin1_General_CI_AS_KS_WS AS [Permission-Name]
FROM sys.server_permissions AS PERM
INNER JOIN sys.server_principals AS prin
    ON prin.principal_id = PERM.grantee_principal_id
WHERE PERM.permission_name IN (
    'ALTER ANY EVENT SESSION',
    'VIEW SERVER STATE',
    'CONTROL SERVER'
)
UNION ALL
-- Plus check for members of the 'sysadmin' fixed server role,
-- because 'sysadmin' includes the 'CONTROL SERVER' permission.
SELECT 'Owner-is-Role',
    prin.name, -- [Role-Name]
    CAST((IsNull(pri2.name, N'No members')) AS NVARCHAR(128)),
    NULL
FROM sys.server_role_members AS rolm
RIGHT JOIN sys.server_principals AS prin
    ON prin.principal_id = rolm.role_principal_id
LEFT JOIN sys.server_principals AS pri2
    ON rolm.member_principal_id = pri2.principal_id
WHERE prin.name = 'sysadmin';

HAS_PERMS_BY_NAME 函數

下列 SELECT 陳述式會報告您的權限。 它需要內建函數 HAS_PERMS_BY_NAME

此外,如果您有暫時模擬其他登入的權限,您可以取消註解 EXECUTE AS LOGINREVERT 陳述式,以查看其他登入是否持有 ALTER ANY EVENT SESSION 權限。

--EXECUTE AS LOGIN = 'LoginNameHere';
SELECT HAS_PERMS_BY_NAME(NULL, NULL, 'ALTER ANY EVENT SESSION');
--REVERT;