Compartilhar via


Destinos de Eventos Estendidos

Aplica-se a: SQL Server Banco de Dados SQL do Azure Instância Gerenciada de SQL do Azure

Este artigo explica quando e como usar destinos de Eventos Estendidos. Para cada destino, este artigo explica:

  • Suas habilidades em coletar e relatar os dados enviados por eventos
  • Seus parâmetros, exceto quando o parâmetro é autoexplicativo

A tabela a seguir descreve a disponibilidade de cada tipo de destino em diferentes mecanismos de banco de dados.

Tipo de destino SQL Server Banco de Dados SQL do Azure Instância Gerenciada de SQL do Azure
etw_classic_sync_target Sim Não No
event_counter Sim Sim Sim
event_file Sim Sim Sim
event_stream Sim Sim Sim
histograma Sim Sim Sim
pair_matching Sim Não No
ring_buffer Sim Sim Sim

Pré-requisitos

Para aproveitar ao máximo este artigo, você deve:

Parâmetros, ações e campos

A instrução CREATE EVENT SESSION é fundamental para Eventos Estendidos. Para escrever a declaração, você precisa do seguinte:

  • Os eventos que você deseja adicionar à sessão
  • Os campos associados a cada evento escolhido
  • Os parâmetros associados a cada destino que você deseja adicionar às sessões

Instruções SELECT, que retornam listas desse tipo das exibições do sistema, estão disponíveis para cópia no seguinte artigo, seção C:

Você pode ver os parâmetros, campos e ações usados no contexto de uma instrução CREATE EVENT SESSION real, na seção B2 (perspectiva T-SQL).

destino etw_classic_sync_target

No SQL Server, Eventos Estendidos podem interoperar com o ETW (Rastreamento de Eventos para Windows) para monitorar a atividade do sistema. Para saber mais, veja:

Esse destino ETW processa os dados recebidos de forma síncrona, enquanto a maioria dos destinos os processa de forma assíncrona.

Observação

A Instância Gerenciada de SQL do Azure e o Banco de Dados SQL do Azure não são compatíveis com etw_classic_sync_target de destino. Como alternativa, use o destino event_file com blobs armazenados no Armazenamento do Azure.

destino event_counter

O destino event_counter conta quantas vezes cada evento especificado ocorre.

Ao contrário da maioria dos outros destinos:

  • O destino event_counter não tem parâmetros.
  • O destino event_counter processa os dados que recebe de forma síncrona.

Saída de exemplo capturada pelo destino event_counter

package_name   event_name         count
------------   ----------         -----
sqlserver      checkpoint_begin   4

Em seguida, está a instrução CREATE EVENT SESSION que retornou os resultados anteriores. Para este exemplo, o campo package0.counter foi usado no predicado da cláusula WHERE para interromper a contagem depois que ela atinge 4.

CREATE EVENT SESSION [event_counter_1]
    ON SERVER
    ADD EVENT sqlserver.checkpoint_begin   -- Test by issuing CHECKPOINT; statements.
    (
        WHERE [package0].[counter] <= 4   -- A predicate filter.
    )
    ADD TARGET package0.event_counter
    WITH
    (
        MAX_MEMORY = 4096 KB,
        MAX_DISPATCH_LATENCY = 3 SECONDS
    );

Destino event_file

O destino event_file grava a saída da sessão de eventos do buffer em um arquivo de disco ou em um blob no Armazenamento do Azure:

  • Você especifica o parâmetro filename na cláusula ADD TARGET. A extensão do arquivo deve ser xel.
  • O nome de arquivo escolhido é usado pelo sistema como um prefixo ao qual é acrescentado um inteiro longo baseado em data e hora, seguido da extensão xel.

Observação

A Instância Gerenciada SQL do Azure e o Banco de Dados SQL do Azure somente usam blobs no Armazenamento do Azure como o valor do parâmetro filename.

Para conhecer um exemplo de código event_file do Banco de Dados SQL ou da Instância Gerenciada de SQL, confira Código de destino do Arquivo de Evento para eventos estendidos no Banco de Dados SQL.

CREATE EVENT SESSION com o destino event_file

Aqui está um exemplo de CREATE EVENT SESSION com uma cláusula ADD TARGET que adiciona um destino event_file.

CREATE EVENT SESSION [locks_acq_rel_eventfile_22]
    ON SERVER
    ADD EVENT sqlserver.lock_acquired
    (
        SET
            collect_database_name=(1),
            collect_resource_description=(1)
        ACTION (sqlserver.sql_text,sqlserver.transaction_id)
        WHERE
        (
            [database_name]=N'InMemTest2'
            AND
            [object_id]=370100359
        )
    ),
    ADD EVENT sqlserver.lock_released
    (
        SET
            collect_database_name=1,
            collect_resource_description=1
        ACTION(sqlserver.sql_text,sqlserver.transaction_id)
        WHERE
        (
            [database_name]=N'InMemTest2'
            AND
            [object_id]=370100359
        )
    )
    ADD TARGET package0.event_counter,
    ADD TARGET package0.event_file
    (
        SET filename=N'C:\temp\locks_acq_rel_eventfile_22-.xel'
    )
    WITH
    (
        MAX_MEMORY=4096 KB,
        MAX_DISPATCH_LATENCY=10 SECONDS
    );

função sys.fn_xe_file_target_read_file()

O destino event_file armazena os dados recebidos em um formato binário que não é legível por humanos. A função sys.fn_xe_file_target_read_file permite representar o conteúdo de um arquivo xel como um conjunto de linhas relacional.

Para o SQL Server 2016 e versões posteriores, use uma instrução SELECT semelhante ao exemplo a seguir.

SELECT f.*
--,CAST(f.event_data AS XML)  AS [Event-Data-Cast-To-XML]  -- Optional
FROM sys.fn_xe_file_target_read_file(
    'C:\temp\locks_acq_rel_eventfile_22-*.xel', NULL, NULL, NULL)  AS f;

Para o SQL Server 2014, use uma instrução SELECT semelhante ao exemplo a seguir. Após o SQL Server 2014, os arquivos xem não são mais usados.

SELECT f.*
--,CAST(f.event_data AS XML)  AS [Event-Data-Cast-To-XML]  -- Optional
FROM sys.fn_xe_file_target_read_file(
    'C:\temp\locks_acq_rel_eventfile_22-*.xel', 'C:\temp\metafile.xem', NULL, NULL) AS f;

Em ambos os exemplos, o curinga * é usado para ler todos os arquivos xel que começam com o prefixo especificado.

No Banco de Dados SQL do Azure, você pode chamar a função sys.fn_xe_file_target_read_file() depois de criar uma credencial com escopo de banco de dados contendo um token SAS com as permissões Read e List no contêiner com os blobs xel:

/*
Create a master key to protect the secret of the credential
*/
IF NOT EXISTS (
    SELECT 1
    FROM sys.symmetric_keys
    WHERE name = '##MS_DatabaseMasterKey##'
)
CREATE MASTER KEY;

/*
(Re-)create a database scoped credential.
The name of the credential must match the URI of the blob container.
*/
IF EXISTS (
    SELECT *
    FROM sys.database_credentials
    WHERE name = 'https://exampleaccount4xe.blob.core.windows.net/extended-events-container'
)
DROP DATABASE SCOPED CREDENTIAL [https://exampleaccount4xe.blob.core.windows.net/extended-events-container];

/*
The secret is the SAS token for the container. The Read and List permissions are set.
*/
CREATE DATABASE SCOPED CREDENTIAL [https://exampleaccount4xe.blob.core.windows.net/extended-events-container]
    WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
        SECRET = 'sp=rl&st=2023-10-09T22:12:54Z&se=2023-10-10T06:12:54Z&spr=https&sv=2022-11-02&sr=c&sig=REDACTED';

/*
Return event session data
*/
SELECT f.*
--,CAST(f.event_data AS XML)  AS [Event-Data-Cast-To-XML]  -- Optional
FROM sys.fn_xe_file_target_read_file('https://exampleaccount4xe.blob.core.windows.net/extended-events-container/event-session-1', DEFAULT, DEFAULT, DEFAULT) AS f;

Na Instância Gerenciada de SQL do Azure, você pode chamar a função sys.fn_xe_file_target_read_file() depois de criar uma credencial de servidor contendo um token SAS com as permissões Read e List no contêiner com os blobs xel:

IF NOT EXISTS (
    SELECT 1
    FROM sys.symmetric_keys
    WHERE name = '##MS_DatabaseMasterKey##'
)
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'REDACTED';

/*
(Re-)create a database scoped credential.
The name of the credential must match the URI of the blob container.
*/
IF EXISTS (
    SELECT *
    FROM sys.credentials
    WHERE name = 'https://exampleaccount4xe.blob.core.windows.net/extended-events-container'
)
DROP CREDENTIAL [https://exampleaccount4xe.blob.core.windows.net/extended-events-container];

/*
The secret is the SAS token for the container. The Read and List permissions are set.
*/
CREATE CREDENTIAL [https://exampleaccount4xe.blob.core.windows.net/extended-events-container]
    WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
        SECRET = 'sp=rl&st=2023-10-09T22:12:54Z&se=2023-10-10T06:12:54Z&spr=https&sv=2022-11-02&sr=c&sig=REDACTED';

/*
Return event session data
*/
SELECT f.*
--,CAST(f.event_data AS XML)  AS [Event-Data-Cast-To-XML]  -- Optional
FROM sys.fn_xe_file_target_read_file('https://exampleaccount4xe.blob.core.windows.net/extended-events-container/event-session-1', DEFAULT, DEFAULT, DEFAULT) AS f;

Dica

Se você especificar um prefixo de nome de blob em vez do nome de blob completo no primeiro argumento de sys.fn_xe_file_target_read_file(), a função retornará dados de todos os blobs no contêiner que correspondem ao prefixo. Isso permite recuperar dados de todos os arquivos de sobreposição de uma determinada sessão de evento sem usar o curinga *, que não tem suporte no Armazenamento do Azure.

Os exemplos anteriores de SQL do Azure omitem a extensão xel para ler todos os arquivos de sobreposição de uma sessão chamada event-session-1.

Dados armazenados no destino event_file

Este é um exemplo de dados retornados de sys.fn_xe_file_target_read_file no SQL Server 2016 (13.x) e versões posteriores.

module_guid                            package_guid                           object_name     event_data                                                                                                                                                                                                                                                                                          file_name                                                      file_offset
-----------                            ------------                           -----------     ----------                                                                                                                                                                                                                                                                                          ---------                                                      -----------
D5149520-6282-11DE-8A39-0800200C9A66   03FDA7D0-91BA-45F8-9875-8B6DD0B8E9F2   lock_acquired   <event name="lock_acquired" package="sqlserver" timestamp="2016-08-07T20:13:35.827Z"><action name="transaction_id" package="sqlserver"><value>39194</value></action><action name="sql_text" package="sqlserver"><value><![CDATA[  select top 1 * from dbo.T_Target;  ]]></value></action></event>   C:\temp\locks_acq_rel_eventfile_22-_0_131150744126230000.xel   11776
D5149520-6282-11DE-8A39-0800200C9A66   03FDA7D0-91BA-45F8-9875-8B6DD0B8E9F2   lock_released   <event name="lock_released" package="sqlserver" timestamp="2016-08-07T20:13:35.832Z"><action name="transaction_id" package="sqlserver"><value>39194</value></action><action name="sql_text" package="sqlserver"><value><![CDATA[  select top 1 * from dbo.T_Target;  ]]></value></action></event>   C:\temp\locks_acq_rel_eventfile_22-_0_131150744126230000.xel   11776

destino de histograma

O destino histogram pode:

  • Contar as ocorrências de vários itens separadamente
  • Contar as ocorrências de diferentes tipos de itens:
    • Campos de evento
    • Ações

O destino histogram processa os dados que recebe de forma síncrona.

O parâmetro source_type é o segredo para controlar o destino de histograma:

  • source_type=0: coletar dados para um campo de evento.
  • source_type=1: coletar dados para uma ação. Esse é o padrão.

O padrão do parâmetro slots é 256. Se você atribuir outro valor, o valor será arredondado para a próxima potência de 2. Por exemplo, slots=59 será arredondado para 64. O número máximo de slots de histograma para um destino histogram é 16384.

Ao usar histogram como destino, às vezes você pode ver resultados inesperados. Alguns eventos podem não aparecer nos espaços esperados, enquanto outros slots podem mostrar um número de eventos maior que o esperado.

Isso pode acontecer se ocorrer uma colisão de hash ao atribuir eventos a slots. Embora ela seja rara, se ocorrer uma colisão de hash, um evento que deveria ser contado em um slot será contado em outro. Por esse motivo, é preciso ter cuidado ao presumir que um evento não ocorreu apenas porque a contagem em um determinado slot é zero.

Por exemplo, considere o cenário a seguir:

  • Você configura uma sessão de eventos estendidos, usando histograma como destino e agrupando por histogram para coletar a execução do procedimento armazenado.
  • Você executa o procedimento armazenado A. Em seguida, executa o procedimento armazenado B.

Se a função de hash retornar o mesmo valor para object_id de ambos os procedimentos armazenados, o histograma mostrará o procedimento armazenado A sendo executado duas vezes, e o procedimento armazenado B não aparecerá.

Para atenuar esse problema quando o número de valores distintos for relativamente pequeno, defina o número de slots de histograma como maior do que o quadrado dos valores distintos esperados. Por exemplo, se o destino histogram tiver seu source definido como o campo de evento table_name e houver 20 tabelas no banco de dados, 20*20 = 400. A próxima potência de 2 maior que 400 é 512, que é o número recomendado de slots neste exemplo.

Destino do histograma com uma ação

Em sua cláusula ADD TARGET ... (SET ...), o seguinte comando CREATE EVENT SESSION especifica a atribuição do parâmetro de destino source_type=1. Isso significa que o destino de histograma acompanha uma ação.

No exemplo atual, a cláusula ADD EVENT ... (ACTION ...) oferece apenas uma ação a ser escolhida, ou seja, sqlos.system_thread_id. Na cláusula ADD TARGET ... (SET ...), vemos a atribuição source=N'sqlos.system_thread_id'.

Observação

Não é possível adicionar mais de um destino do mesmo tipo por sessão de evento. Isso inclui o destino histogram. Também não é possível ter mais de uma origem (campo de ação/evento) por destino histogram. Portanto, é necessária uma nova sessão de eventos para rastrear quaisquer ações ou campos de eventos adicionais em um destino histogram separado.

CREATE EVENT SESSION [histogram_lockacquired]
    ON SERVER
    ADD EVENT sqlserver.lock_acquired
        (
        ACTION
            (
            sqlos.system_thread_id
            )
        )
    ADD TARGET package0.histogram
        (
        SET
            filtering_event_name=N'sqlserver.lock_acquired',
            slots=16,
            source=N'sqlos.system_thread_id',
            source_type=1
        );

Os dados a seguir foi capturados. Os valores na coluna value são valores system_thread_id. Por exemplo, um total de 236 bloqueios foram feitos no thread 6540.

value   count
-----   -----
 6540     236
 9308      91
 9668      74
10144      49
 5244      44
 2396      28

Use SELECT para descobrir as ações disponíveis

A instrução C.3 SELECT pode encontrar as ações que o sistema tem disponíveis para você especificar na instrução CREATE EVENT SESSION. Na cláusula WHERE, primeiro você editará o filtro para que ele corresponda às ações do seu interesse.

Veja a seguir um conjunto de linhas de exemplo retornado por C.3 SELECT. A ação system_thread_id é vista na segunda linha.

Package-Name   Action-Name                 Action-Description
------------   -----------                 ------------------
package0       collect_current_thread_id   Collect the current Windows thread ID
sqlos          system_thread_id            Collect current system thread ID
sqlserver      create_dump_all_threads     Create mini dump including all threads
sqlserver      create_dump_single_thread   Create mini dump for the current thread

Destino do histograma com um campo de evento

O exemplo a seguir configura source_type=0. O valor atribuído a source é um campo de evento.

CREATE EVENT SESSION [histogram_checkpoint_dbid]
    ON SERVER
    ADD EVENT  sqlserver.checkpoint_begin
    ADD TARGET package0.histogram
    (
    SET
        filtering_event_name = N'sqlserver.checkpoint_begin',
        source               = N'database_id',
        source_type          = 0
    );

Os dados a seguir foram capturados pelo destino de histogram. Os dados mostram que o banco de dados com ID 5 teve 7 eventos checkpoint_begin.

value   count
-----   -----
5       7
7       4
6       3

Usar a instrução SELECT para descobrir os campos disponíveis no evento escolhido

A instrução C.4 SELECT mostra os campos de evento que podem ser escolhidos. Primeiro, você editará o filtro o.name LIKE para que ele tenha o nome do evento escolhido.

O conjunto de linhas a seguir foi retornado pela instrução C.4 SELECT. O conjunto de linhas mostra que database_id é o único campo do evento checkpoint_begin que pode fornecer valores para o destino de histogram.

Package-Name   Event-Name         Field-Name   Field-Description
------------   ----------         ----------   -----------------
sqlserver      checkpoint_begin   database_id  NULL
sqlserver      checkpoint_end     database_id  NULL

destino pair_matching

O destino pair_matching permite detectar eventos de início que ocorrem sem um evento de término correspondente. Por exemplo, isso poderá ser um problema quando ocorrer um evento lock_acquired, mas nenhum evento lock_released correspondente ocorrer a seguir, oportunamente.

O sistema não faz automaticamente a correspondência de eventos de início e término. Em vez disso, você explica a correspondência para o sistema na instrução CREATE EVENT SESSION. Quando um evento de início e término forem correspondentes, o par será descartado para se concentrar nos eventos de início não correspondentes.

Encontrar campos que podem ser correspondentes no par de eventos de início e término

Com a instrução C.4 SELECT, vemos no conjunto de linhas a seguir que há aproximadamente 16 campos para o evento lock_acquired. O conjunto de linhas exibido aqui foi dividido manualmente para mostrar de quais campos nosso exemplo fez a correspondência. Para alguns campos, como duration, não faz sentido tentar corresponder.

Package-Name   Event-Name   Field-Name               Field-Description
------------   ----------   ----------               -----------------
sqlserver   lock_acquired   database_name            NULL
sqlserver   lock_acquired   mode                     NULL
sqlserver   lock_acquired   resource_0               The ID of the locked object, when lock_resource_type is OBJECT.
sqlserver   lock_acquired   resource_1               NULL
sqlserver   lock_acquired   resource_2               The ID of the lock partition, when lock_resource_type is OBJECT, and resource_1 is 0.
sqlserver   lock_acquired   transaction_id           NULL

sqlserver   lock_acquired   associated_object_id     The ID of the object that requested the lock that was acquired.
sqlserver   lock_acquired   database_id              NULL
sqlserver   lock_acquired   duration                 The time (in microseconds) between when the lock was requested and when it was canceled.
sqlserver   lock_acquired   lockspace_nest_id        NULL
sqlserver   lock_acquired   lockspace_sub_id         NULL
sqlserver   lock_acquired   lockspace_workspace_id   NULL
sqlserver   lock_acquired   object_id                The ID of the locked object, when lock_resource_type is OBJECT. For other lock resource types it will be 0
sqlserver   lock_acquired   owner_type               NULL
sqlserver   lock_acquired   resource_description     The description of the lock resource. The description depends on the type of lock. This is the same value as the resource_description column in the sys.dm_tran_locks view.
sqlserver   lock_acquired   resource_type            NULL

Um exemplo do destino pair_matching

A instrução CREATE EVENT SESSION a seguir especifica dois eventos e dois destinos. O destino pair_matching especifica dois conjuntos de campos para corresponder os eventos em pares. A sequência de campos delimitados por vírgulas atribuídos a begin_matching_columns e a end_matching_columns deve ser a mesma. Não são permitidas guias nem novas linhas entre os campos mencionados no valor delimitado por vírgula, embora o uso de espaços seja permitido.

Para restringir os resultados, primeiro escolhemos em sys.objects para encontrar o object_id da nossa tabela de teste. Adicionamos um filtro para esse ID de objeto na cláusula ADD EVENT ... (WHERE ...).

CREATE EVENT SESSION [pair_matching_lock_a_r_33]
    ON SERVER
    ADD EVENT sqlserver.lock_acquired
    (
        SET
            collect_database_name = 1,
            collect_resource_description = 1
        ACTION (sqlserver.transaction_id)
        WHERE
        (
            [database_name] = 'InMemTest2'
            AND
            [object_id] = 370100359
        )
    ),
    ADD EVENT sqlserver.lock_released
    (
        SET
            collect_database_name = 1,
            collect_resource_description = 1
        ACTION (sqlserver.transaction_id)
        WHERE
        (
            [database_name] = 'InMemTest2'
            AND
            [object_id] = 370100359
        )
    )
    ADD TARGET package0.event_counter,
    ADD TARGET package0.pair_matching
    (
        SET
            begin_event = N'sqlserver.lock_acquired',
            begin_matching_columns =
                N'resource_0, resource_1, resource_2, transaction_id, database_id',
            end_event = N'sqlserver.lock_released',
            end_matching_columns =
                N'resource_0, resource_1, resource_2, transaction_id, database_id',
            respond_to_memory_pressure = 1
    )
    WITH
    (
        MAX_MEMORY = 8192 KB,
        MAX_DISPATCH_LATENCY = 15 SECONDS
    );

Para testar a sessão de evento, propositadamente impedimos a liberação de dois bloqueios adquiridos. Fizemos isso nas seguintes etapas do T-SQL:

  1. BEGIN TRANSACTION.
  2. UPDATE MyTable....
  3. Propositalmente não emitimos um COMMIT TRANSACTION até depois de examinarmos as metas.
  4. Mais tarde, após os testes, emitimos um COMMIT TRANSACTION.

O destino simples event_counter forneceu as linhas de saída a seguir. Como 52-50=2, o resultado indica que vemos dois eventos lock_acquired desemparelhados ao examinarmos a saída do destino pair-matching.

package_name   event_name      count
------------   ----------      -----
sqlserver      lock_acquired   52
sqlserver      lock_released   50

O destino pair_matching forneceu a saída a seguir. Como sugerido pela saída event_counter, de fato vemos as duas linhas lock_acquired. O fato de que vemos essas linhas significa que esses dois eventos lock_acquired não são emparelhados.

package_name   event_name      timestamp                     database_name   duration   mode   object_id   owner_type   resource_0   resource_1   resource_2   resource_description   resource_type   transaction_id
------------   ----------      ---------                     -------------   --------   ----   ---------   ----------   ----------   ----------   ----------   --------------------   -------------   --------------
sqlserver      lock_acquired   2016-08-05 12:45:47.9980000   InMemTest2      0          S      370100359   Transaction  370100359    3            0            [INDEX_OPERATION]      OBJECT          34126
sqlserver      lock_acquired   2016-08-05 12:45:47.9980000   InMemTest2      0          IX     370100359   Transaction  370100359    0            0                                   OBJECT          34126

As linhas para os eventos lock_acquired desemparelhados podem incluir o texto T-SQL fornecido pela ação sqlserver.sql_text. Isso captura a consulta que adquiriu os bloqueios.

Destino ring_buffer

O destino ring_buffer é útil para uma coleta de eventos rápida e simples apenas na memória. Quando você interrompe a sessão de evento, a saída armazenada é descartada.

Nesta seção, também mostramos como é possível usar XQuery para converter a representação XML do conteúdo do buffer de anel em um conjunto de linhas relacional mais legível.

Dica

Ao adicionar um destino ring_buffer, configure o parâmetro MAX_MEMORY como 1.024 KB ou menos. O uso de valores maiores pode aumentar o consumo de memória desnecessariamente.

Por padrão, MAX_MEMORY para um destino ring_buffer não é limitado no SQL Server e é limitado a 32 MB no Banco de Dados SQL do Azure e na Instância Gerenciada SQL do Azure.

Você consome dados de um destino ring_buffer convertendo-os em XML, conforme mostrado no exemplo a seguir. Durante essa conversão, todos os dados que não se encaixarem em um documento XML de 4 MB serão omitidos. Portanto, mesmo que você capture mais eventos no buffer de anel usando valores MAX_MEMORY maiores (ou deixando esse parâmetro em seu valor padrão), talvez não seja possível consumir todos eles devido ao limite de 4 MB no tamanho do documento XML, considerando a sobrecarga de marcação XML e cadeias de caracteres Unicode.

Você sabe que o conteúdo do buffer de anel é omitido durante a conversão para XML se o atributo truncated no documento XML estiver definido como 1, por exemplo:

<RingBufferTarget truncated="1" processingTime="0" totalEventsProcessed="284" eventCount="284" droppedCount="0" memoryUsed="64139">

CREATE EVENT SESSION com um destino ring_buffer

Confira a seguir um exemplo de criação de uma sessão de evento com um destino ring_buffer. Neste exemplo, o parâmetro MAX_MEMORY aparece duas vezes: uma vez para configurar a memória de destino ring_buffer como 1.024 KB e outra vez para configurar a memória do armazenamento em buffer da sessão de eventos como 2 MB.

CREATE EVENT SESSION [ring_buffer_lock_acquired_4]
    ON SERVER
    ADD EVENT sqlserver.lock_acquired
    (
        SET collect_resource_description=(1)
        ACTION(sqlserver.database_name)
        WHERE
        (
            [object_id]=(370100359)  -- ID of MyTable
            AND
            sqlserver.database_name='InMemTest2'
        )
    )
    ADD TARGET package0.ring_buffer
    (
        SET MAX_EVENTS_LIMIT = 98,
            MAX_MEMORY = 1024
    )
    WITH
    (
        MAX_MEMORY = 2 MB,
        MAX_DISPATCH_LATENCY = 3 SECONDS
    );

Saída XML recebida para lock_acquired pelo destino ring_buffer

Quando recuperado por uma instrução SELECT, o conteúdo de um buffer de anel é apresentado como um documento XML. Um exemplo é exibido a seguir: No entanto, por brevidade, todos os elementos, exceto dois <event>, foram removidos. Além disso, dentro de cada <event>, alguns elementos <data> também foram removidos.

<RingBufferTarget truncated="0" processingTime="0" totalEventsProcessed="6" eventCount="6" droppedCount="0" memoryUsed="1032">
  <event name="lock_acquired" package="sqlserver" timestamp="2016-08-05T23:59:53.987Z">
    <data name="mode">
      <type name="lock_mode" package="sqlserver"></type>
      <value>1</value>
      <text><![CDATA[SCH_S]]></text>
    </data>
    <data name="transaction_id">
      <type name="int64" package="package0"></type>
      <value>111030</value>
    </data>
    <data name="database_id">
      <type name="uint32" package="package0"></type>
      <value>5</value>
    </data>
    <data name="resource_0">
      <type name="uint32" package="package0"></type>
      <value>370100359</value>
    </data>
    <data name="resource_1">
      <type name="uint32" package="package0"></type>
      <value>0</value>
    </data>
    <data name="resource_2">
      <type name="uint32" package="package0"></type>
      <value>0</value>
    </data>
    <data name="database_name">
      <type name="unicode_string" package="package0"></type>
      <value><![CDATA[]]></value>
    </data>
    <action name="database_name" package="sqlserver">
      <type name="unicode_string" package="package0"></type>
      <value><![CDATA[InMemTest2]]></value>
    </action>
  </event>
  <event name="lock_acquired" package="sqlserver" timestamp="2016-08-05T23:59:56.012Z">
    <data name="mode">
      <type name="lock_mode" package="sqlserver"></type>
      <value>1</value>
      <text><![CDATA[SCH_S]]></text>
    </data>
    <data name="transaction_id">
      <type name="int64" package="package0"></type>
      <value>111039</value>
    </data>
    <data name="database_id">
      <type name="uint32" package="package0"></type>
      <value>5</value>
    </data>
    <data name="resource_0">
      <type name="uint32" package="package0"></type>
      <value>370100359</value>
    </data>
    <data name="resource_1">
      <type name="uint32" package="package0"></type>
      <value>0</value>
    </data>
    <data name="resource_2">
      <type name="uint32" package="package0"></type>
      <value>0</value>
    </data>
    <data name="database_name">
      <type name="unicode_string" package="package0"></type>
      <value><![CDATA[]]></value>
    </data>
    <action name="database_name" package="sqlserver">
      <type name="unicode_string" package="package0"></type>
      <value><![CDATA[InMemTest2]]></value>
    </action>
  </event>
</RingBufferTarget>

Para ver o XML anterior, você pode emitir a instrução SELECT a seguir enquanto a sessão de evento está ativa. Os dados XML são recuperados da exibição do sistema sys.dm_xe_session_targets.

SELECT CAST(LocksAcquired.TargetXml AS XML) AS RBufXml
INTO #XmlAsTable
FROM (
    SELECT CAST(t.target_data AS XML) AS TargetXml
    FROM sys.dm_xe_session_targets AS t
    INNER JOIN sys.dm_xe_sessions AS s
        ON s.address = t.event_session_address
    WHERE t.target_name = 'ring_buffer'
        AND s.name = 'ring_buffer_lock_acquired_4'
) AS LocksAcquired;

SELECT *
FROM #XmlAsTable;

XQuery para ver o XML como um conjunto de linhas

Para ver o XML anterior como um conjunto de linhas relacional, continue após a instrução SELECT anterior emitindo o comando T-SQL a seguir. As linhas com comentários explicam cada um dos usos do XQuery.

SELECT
    -- (A)
    ObjectLocks.value('(@timestamp)[1]', 'datetime') AS [OccurredDtTm],
    -- (B)
    ObjectLocks.value('(data[@name="mode"]/text)[1]', 'nvarchar(32)') AS [Mode],
    -- (C)
    ObjectLocks.value('(data[@name="transaction_id"]/value)[1]', 'bigint') AS [TxnId],
    -- (D)
    ObjectLocks.value('(action[@name="database_name" and @package="sqlserver"]/value)[1]', 'nvarchar(128)') AS [DatabaseName]
FROM #XmlAsTable
CROSS APPLY
    -- (E)
    TargetDateAsXml.nodes('/RingBufferTarget/event[@name="lock_acquired"]') AS T(ObjectLocks);

Observações do XQuery da instrução SELECT anterior

(A)

  • timestamp= valor do atributo, no elemento <event>.
  • O constructo '(...)[1]' garante apenas um valor retornado por iteração, já que essa é uma limitação necessária do método .value() do XQuery de colunas e variável do tipo de dados XML.

(B)

  • Valor interno do elemento <text> em um elemento <data> que tem seu atributo name= igual a mode.

(C)

  • Valor interno do elemento <value> em um elemento <data> que tem seu atributo name= igual a transaction_id.

(D)

  • <event> contém <action>.
  • <action> com o atributo name= igual database_name, e o atributo package= igual a sqlserver (e não package0), obtém o valor interno do elemento <value>.

(E)

  • CROSS APPLY faz com que o processamento seja repetido para cada elemento <event> individual, que tem seu atributo name igual a lock_acquired.
  • Isso se aplica ao XML retornado pela cláusula FROM anterior.

Saída do XQuery SELECT

Veja a seguir o conjunto de linhas gerado pelo T-SQL precedente que inclui o XQuery.

OccurredDtTm              Mode    DatabaseName
------------              ----    ------------
2016-08-05 23:59:53.987   SCH_S   InMemTest2
2016-08-05 23:59:56.013   SCH_S   InMemTest2

Destino event_stream

O destino event_stream apenas pode ser usado em programas do .NET escritos em linguagens como o C#. Os desenvolvedores C# e outros desenvolvedores .NET podem acessar um fluxo de eventos por meio de classes do .NET Framework no namespace Microsoft.SqlServer.XEvents.Linq. Esse destino não pode ser usado no T-SQL.

Se você encontrar o erro 25726, The event data stream was disconnected because there were too many outstanding events. To avoid this error either remove events or actions from your session or add a more restrictive predicate filter to your session. ao ler do destino event_stream, significa que o fluxo de eventos foi preenchido com dados mais rapidamente do que o cliente poderia consumir os dados. Isso faz com que o mecanismo de banco de dados se desconecte do fluxo de eventos para evitar afetar o desempenho do mecanismo de banco de dados.

Namespaces de XEvent