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:
Familiarizar-se com os conceitos básicos de Eventos Estendidos, conforme descrito em Início rápido: Eventos Estendidos.
Ter instalado uma versão recente do SQL Server Management Studio (SSMS). Para obter mais informações, consulte Baixar o SSMS (SQL Server Management Studio).
No SSMS, saiba como usar o Pesquisador de Objetos para clicar com o botão direito do mouse no nó de destino na sessão de evento para facilitar a exibição dos dados de saída.
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:
- Destino do Rastreamento de Eventos para Windows
- Monitorar a atividade do sistema usando Eventos Estendidos
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áusulaADD TARGET
. A extensão do arquivo deve serxel
. - 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:
BEGIN TRANSACTION
.UPDATE MyTable...
.- Propositalmente não emitimos um
COMMIT TRANSACTION
até depois de examinarmos as metas. - 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 amode
.
(C)
- Valor interno do elemento
<value>
em um elemento<data>
que tem seu atributo name= igual atransaction_id
.
(D)
<event>
contém<action>
.<action>
com o atributo name= igualdatabase_name
, e o atributo package= igual asqlserver
(e nãopackage0
), 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 atributoname
igual alock_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.