Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Usando eventos estendidos para registrar recursos obsoletos sendo usados ​​em uma instância do SQL Server (exemplo T-SQL)


Eventos estendidos é um sistema de monitoramento de desempenho leve que permite aos usuários coletar dados necessários para monitorar e solucionar problemas no SQL Server.

Este artigo demonstra como eventos estendidos podem ser usados ​​para criar um arquivo de log que contém todos os recursos preteridos que ainda estão sendo usados ​​em uma instância do SQL Server. O log registra todas as ocorrências desde que a sessão do evento foi iniciada.

Se você quiser apenas uma contagem rápida de quantas vezes um recurso preterido foi usado desde que o SQL Server foi iniciado, consulte a maneira mais rápida de encontrar recursos preteridos ainda sendo usados ​​em uma instância do SQL Server.

Mas se você precisar de um log mais detalhado que inclua coisas como; a instrução SQL usada que contém o recurso obsoleto, o banco de dados em que foi executado, o usuário que o executou, a hora em que foi executado etc.


Criar a Sessão de Evento Estendida


A primeira etapa é criar a sessão de evento estendida. Aqui, especificamos a origem dos eventos, o destino da sessão do evento e as opções da sessão do evento.
CREATE EVENT SESSION [Deprecation Events] ON SERVER 
ADD EVENT sqlserver.deprecation_announcement(
    ACTION(
        sqlserver.database_name,
        sqlserver.sql_text,
        sqlserver.username
        )
),
ADD EVENT sqlserver.deprecation_final_support(
    ACTION(
        sqlserver.database_name,
        sqlserver.sql_text,
        sqlserver.username
    )
)
ADD TARGET package0.event_file(
    SET filename=N'/var/opt/mssql/tmp/DeprecationEvents.xel'
    )
WITH (
    TRACK_CAUSALITY = ON
    );

Nesse caso, especifico um destino de /var/opt/mssql/tmp/DeprecationEvents.xel . Isso significa que os dados do evento serão armazenados nesse arquivo. Você pode especificar qualquer nome de arquivo e caminho.

Este exemplo usa um caminho de arquivo Linux, que usa barras. Se você estiver no Windows, precisará usar barras invertidas. Por exemplo:C:\Temp\DeprecationEvents.xel .

Iniciar a Sessão de Evento Estendido


A criação da sessão do evento não a inicia. Use ALTER EVENT SESSION para pará-lo e iniciá-lo. Neste caso, queremos iniciá-lo:
ALTER EVENT SESSION [Deprecation Events] ON SERVER STATE = START;

Fazer algo obsoleto


Agora que iniciamos a sessão de evento estendida, vamos executar algum código obsoleto:
SELECT * FROM sys.sql_dependencies;

Porque sys.sql_dependencies estiver obsoleto, esse código adicionará dados ao arquivo XEL que especificamos anteriormente.

Visualizar o arquivo XEL


Agora que adicionamos (presumivelmente) dados ao nosso arquivo XEL, vamos dar uma olhada nele:
SELECT event_data 
FROM sys.fn_xe_file_target_read_file (
    '/var/opt/mssql/tmp/DeprecationEvents*.xel', 
    null, 
    null, 
    null
    );  

Resultado:
<event name="deprecation_announcement" package="sqlserver" timestamp="2019-10-31T04:03:06.528Z"><data name="feature_id"><value>198</value></data><data name="feature"><value><![CDATA[sql_dependencies]]></value></data><data name="message"><value><![CDATA[sql_dependencies will be removed in a future version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use it.]]></value></data><action name="username" package="sqlserver"><value><![CDATA[sa]]></value></action><action name="sql_text" package="sqlserver"><value><![CDATA[SELECT * FROM sys.sql_dependencies;]]></value></action><action name="database_name" package="sqlserver"><value><![CDATA[Test]]></value></action><action name="attach_activity_id_xfer" package="package0"><value>5566866F-8266-467A-9950-895310CF21E3-0</value></action><action name="attach_activity_id" package="package0"><value>07971CB0-F9CC-46C6-B885-5BA8A904B880-1</value></action>

Nesse caso, retornei apenas event_data , porque é onde residem todos os dados do evento.

Infelizmente, não é o mais fácil para nós, humanos, ler.

E se eu formatar?
<event name="deprecation_announcement" package="sqlserver" timestamp="2019-10-31T04:03:06.528Z">
   <data name="feature_id">
      <value>198</value>
   </data>
   <data name="feature">
      <value><![CDATA[sql_dependencies]]></value>
   </data>
   <data name="message">
      <value><![CDATA[sql_dependencies will be removed in a future version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use it.]]></value>
   </data>
   <action name="username" package="sqlserver">
      <value><![CDATA[sa]]></value>
   </action>
   <action name="sql_text" package="sqlserver">
      <value><![CDATA[SELECT * FROM sys.sql_dependencies;]]></value>
   </action>
   <action name="database_name" package="sqlserver">
      <value><![CDATA[Test]]></value>
   </action>
   <action name="attach_activity_id_xfer" package="package0">
      <value>5566866F-8266-467A-9950-895310CF21E3-0</value>
   </action>
   <action name="attach_activity_id" package="package0">
      <value>07971CB0-F9CC-46C6-B885-5BA8A904B880-1</value>
   </action>
</event>

É um pouco mais fácil de ler quando está formatado, mas podemos fazer melhor do que isso.

Analisar o arquivo XEL


Neste exemplo, eu analiso o arquivo XEL para que eu possa ver os dados em uma grade, assim como qualquer outra consulta de banco de dados.
SELECT
    EventXml.value('(@timestamp)[1]', 'datetime2') AS [timestamp],
    EventXml.value('(action[@name="username"]/value)[1]', 'nvarchar(256)') AS username,
    EventXml.value('(action[@name="database_name"]/value)[1]', 'nvarchar(128)') AS database_name,
    EventXml.value('(action[@name="sql_text"]/value)[1]', 'varchar(4000)') AS sql_text,
    EventXml.value('(@name)[1]', 'varchar(50)') AS event_name,
    EventXml.value('(data[@name="feature"]/value)[1]', 'varchar(255)') AS feature,
    EventXml.value('(data[@name="message"]/value)[1]', 'varchar(max)') AS message
FROM (SELECT CAST(event_data AS XML) AS XmlEventData
    FROM sys.fn_xe_file_target_read_file (
        '/var/opt/mssql/tmp/DeprecationEvents*.xel', 
        null, 
        null, 
        null
    )) AS EventTable
CROSS APPLY EventTable.XmlEventData.nodes('event') AS q(EventXml);

Resultado (usando saída vertical):
timestamp     | 2019-10-31 04:03:06.5280000
username      | sa
database_name | Test
sql_text      | SELECT * FROM sys.sql_dependencies;
event_name    | deprecation_announcement
feature       | sql_dependencies
message       | sql_dependencies will be removed in a future version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use it.

Estou usando a saída vertical aqui para facilitar a leitura sem ter que rolar horizontalmente. Isso significa que os títulos das colunas estão à esquerda e os dados à direita. Se você executar isso usando uma GUI, como SSMS ou Azure Data Studio, provavelmente o verá no formato de grade de tabela usual (a menos que tenha especificado o contrário).

Várias linhas para um único recurso obsoleto?


Às vezes, seu arquivo XEL pode obter várias entradas para um único evento. Por exemplo, você executa um único procedimento armazenado reprovado uma vez, apenas para descobrir que 10 ou 11 linhas são retornadas de seu arquivo XEL para essa única instrução.

Aqui está um exemplo:
USE Music;
EXEC sp_depends @objname = 'Artists';

O sp_depends o procedimento armazenado do sistema está obsoleto, então eu definitivamente esperaria ver uma linha para isso. Se eu executar isso agora, posso esperar terminar com 2 linhas no total:1 para o exemplo anterior e 1 para este exemplo.

Mas, como se vê, mais 11 linhas são adicionadas ao meu arquivo XEL:
SELECT
    EventXml.value('(@timestamp)[1]', 'datetime2') AS [timestamp],
    EventXml.value('(action[@name="username"]/value)[1]', 'nvarchar(256)') AS username,
    EventXml.value('(action[@name="database_name"]/value)[1]', 'nvarchar(128)') AS database_name,
    EventXml.value('(action[@name="sql_text"]/value)[1]', 'varchar(4000)') AS sql_text,
    EventXml.value('(@name)[1]', 'varchar(50)') AS event_name,
    EventXml.value('(data[@name="feature"]/value)[1]', 'varchar(255)') AS feature,
    EventXml.value('(data[@name="message"]/value)[1]', 'varchar(max)') AS message
FROM (SELECT CAST(event_data AS XML) AS XmlEventData
    FROM sys.fn_xe_file_target_read_file (
        '/var/opt/mssql/tmp/DeprecationEvents*.xel', 
        null, 
        null, 
        null
    )) AS EventTable
CROSS APPLY EventTable.XmlEventData.nodes('event') AS q(EventXml)
ORDER BY [Timestamp] ASC;

Resultado (usando saída vertical):
-[ RECORD 1 ]-------------------------
timestamp     | 2019-10-31 04:03:06.5280000
username      | sa
database_name | Test
sql_text      | SELECT * FROM sys.sql_dependencies;
event_name    | deprecation_announcement
feature       | sql_dependencies
message       | sql_dependencies will be removed in a future version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use it.
-[ RECORD 2 ]-------------------------
timestamp     | 2019-10-31 04:15:13.9920000
username      | sa
database_name | Music
sql_text      | USE Music;
EXEC sp_depends @objname = 'Artists';
event_name    | deprecation_announcement
feature       | sp_depends
message       | sp_depends will be removed in a future version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use it.
-[ RECORD 3 ]-------------------------
timestamp     | 2019-10-31 04:15:13.9940000
username      | sa
database_name | Music
sql_text      | USE Music;
EXEC sp_depends @objname = 'Artists';
event_name    | deprecation_final_support
feature       | String literals as column aliases
message       | The ability to use string literals as column aliases will be removed in a future version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that 
-[ RECORD 4 ]-------------------------
timestamp     | 2019-10-31 04:15:13.9950000
username      | sa
database_name | Music
sql_text      | USE Music;
EXEC sp_depends @objname = 'Artists';
event_name    | deprecation_final_support
feature       | String literals as column aliases
message       | The ability to use string literals as column aliases will be removed in a future version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that 
-[ RECORD 5 ]-------------------------
timestamp     | 2019-10-31 04:15:13.9950000
username      | sa
database_name | Music
sql_text      | USE Music;
EXEC sp_depends @objname = 'Artists';
event_name    | deprecation_final_support
feature       | String literals as column aliases
message       | The ability to use string literals as column aliases will be removed in a future version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that 
-[ RECORD 6 ]-------------------------
timestamp     | 2019-10-31 04:15:14.0020000
username      | sa
database_name | Music
sql_text      | USE Music;
EXEC sp_depends @objname = 'Artists';
event_name    | deprecation_announcement
feature       | sql_dependencies
message       | sql_dependencies will be removed in a future version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use it.
-[ RECORD 7 ]-------------------------
timestamp     | 2019-10-31 04:15:14.0100000
username      | sa
database_name | Music
sql_text      | USE Music;
EXEC sp_depends @objname = 'Artists';
event_name    | deprecation_announcement
feature       | sql_dependencies
message       | sql_dependencies will be removed in a future version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use it.
-[ RECORD 8 ]-------------------------
timestamp     | 2019-10-31 04:15:14.0100000
username      | sa
database_name | Music
sql_text      | USE Music;
EXEC sp_depends @objname = 'Artists';
event_name    | deprecation_announcement
feature       | sql_dependencies
message       | sql_dependencies will be removed in a future version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use it.
-[ RECORD 9 ]-------------------------
timestamp     | 2019-10-31 04:15:14.0120000
username      | sa
database_name | Music
sql_text      | USE Music;
EXEC sp_depends @objname = 'Artists';
event_name    | deprecation_final_support
feature       | sysdepends
message       | sysdepends will be removed in the next version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use it.
-[ RECORD 10 ]-------------------------
timestamp     | 2019-10-31 04:15:14.0260000
username      | sa
database_name | Music
sql_text      | USE Music;
EXEC sp_depends @objname = 'Artists';
event_name    | deprecation_final_support
feature       | sysdepends
message       | sysdepends will be removed in the next version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use it.
-[ RECORD 11 ]-------------------------
timestamp     | 2019-10-31 04:15:14.0760000
username      | sa
database_name | Music
sql_text      | USE Music;
EXEC sp_depends @objname = 'Artists';
event_name    | deprecation_final_support
feature       | sysdepends
message       | sysdepends will be removed in the next version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use it.
-[ RECORD 12 ]-------------------------
timestamp     | 2019-10-31 04:15:14.0800000
username      | sa
database_name | Music
sql_text      | USE Music;
EXEC sp_depends @objname = 'Artists';
event_name    | deprecation_final_support
feature       | sysdepends
message       | sysdepends will be removed in the next version of SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use it.
(12 rows affected)

O que está acontecendo aqui?

Isso está acontecendo porque o sp_depends próprio procedimento armazenado do sistema usa recursos obsoletos.

Não apenas recebo 1 linha para executar sp_depends . Também recebo 1 linha para cada recurso obsoleto usado por esse procedimento armazenado (seja no procedimento armazenado ou em outro objeto ao qual ele faz referência). Neste caso, recebo 10 linhas extras.

Dei uma olhada rápida em sp_depends 's definição, e vi que ele faz referência (o obsoleto) sysdepends em vários lugares, e essa visão referencia (o obsoleto) sql_dependencies . Também vi que ele usa literais de string como aliases de coluna, uma prática que também está marcada para depreciação. Tudo isso suporta o que estou vendo no arquivo XEL.

Mais detalhes sobre cada recurso obsoleto


Consulte o artigo da Microsoft Recursos do mecanismo de banco de dados preteridos no SQL Server 2017 para obter recomendações sobre como lidar com cada item preterido. Essa lista é exatamente a mesma do SQL Server 2016.

Referência de documentação da Microsoft

  • Início rápido:eventos estendidos no SQL Server
  • CRIAR SESSÃO DO EVENTO
  • ALTERAR SESSÃO DO EVENTO
  • sys.fn_xe_file_target_read_file
  • Lendo os dados do evento 101:o que há com o XML?