Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Utilizzo di eventi estesi per registrare funzionalità obsolete utilizzate in un'istanza di SQL Server (esempio T-SQL)

Eventi estesi è un sistema di monitoraggio delle prestazioni leggero che consente agli utenti di raccogliere i dati necessari per monitorare e risolvere i problemi in SQL Server.

Questo articolo illustra come utilizzare gli eventi estesi per creare un file di registro che contiene tutte le funzionalità deprecate che vengono ancora utilizzate in un'istanza di SQL Server. Il registro registra tutte le occorrenze dall'avvio della sessione dell'evento.

Se desideri semplicemente un conteggio rapido di quante volte una funzionalità deprecata è stata utilizzata dall'avvio di SQL Server, consulta il modo più rapido per trovare le funzionalità deprecate ancora in uso in un'istanza di SQL Server.

Ma se hai bisogno di un registro più dettagliato che includa cose come; l'istruzione SQL utilizzata che contiene la funzionalità deprecata, il database su cui è stata eseguita, l'utente che l'ha eseguita, l'ora in cui è stata eseguita, ecc., continua a leggere.

Crea la sessione evento estesa

Il primo passaggio consiste nel creare la sessione di eventi estesa. Qui specifichiamo l'origine degli eventi, la destinazione della sessione dell'evento e le opzioni della sessione dell'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
    );

In questo caso specifico un target di /var/opt/mssql/tmp/DeprecationEvents.xel . Ciò significa che i dati dell'evento verranno archiviati in quel file. Puoi specificare qualsiasi nome di file e percorso.

Questo esempio utilizza un percorso di file Linux, che utilizza le barre in avanti. Se sei su Windows, dovresti usare le barre inverse. Ad esempio:C:\Temp\DeprecationEvents.xel .

Inizia la sessione estesa dell'evento

La creazione della sessione dell'evento non la avvia. Usa ALTER EVENT SESSION per fermarlo e avviarlo. In questo caso vogliamo avviarlo:

ALTER EVENT SESSION [Deprecation Events] ON SERVER STATE = START;

Fai qualcosa di deprecato

Ora che abbiamo avviato la sessione di eventi estesa, eseguiamo del codice deprecato:

SELECT * FROM sys.sql_dependencies;

Perché sys.sql_dependencies è deprecato, quel codice aggiungerà i dati al file XEL che abbiamo specificato in precedenza.

Visualizza il file XEL

Ora che abbiamo (presumibilmente) aggiunto dati al nostro file XEL, diamo un'occhiata:

SELECT event_data 
FROM sys.fn_xe_file_target_read_file (
    '/var/opt/mssql/tmp/DeprecationEvents*.xel', 
    null, 
    null, 
    null
    );  

Risultato:

<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>

In questo caso, ho restituito solo event_data , perché è lì che risiedono tutti i dati dell'evento.

Sfortunatamente, per noi umani non è il più facile da leggere.

E se lo formatto?

<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>

È leggermente più facile da leggere quando è formattato, ma possiamo fare di meglio.

Analizza il file XEL

In questo esempio, analizzo il file XEL in modo da poter vedere i dati in una griglia, proprio come qualsiasi altra query di database.

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);

Risultato (usando l'output verticale):

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.

Sto usando l'output verticale qui per rendere più facile la lettura senza dover scorrere orizzontalmente. Ciò significa che le intestazioni delle colonne sono a sinistra e i dati a destra. Se lo esegui utilizzando una GUI come SSMS o Azure Data Studio, probabilmente lo vedrai nel consueto formato a griglia di tabella (a meno che tu non abbia specificato diversamente).

Più righe per una singola funzione obsoleta?

Il tuo file XEL a volte potrebbe ricevere più voci per un singolo evento. Ad esempio, esegui una singola stored procedure deprecata una volta, solo per scoprire che 10 o 11 righe vengono restituite dal tuo file XEL per quella singola istruzione.

Ecco un esempio:

USE Music;
EXEC sp_depends @objname = 'Artists';

Il sp_depends la procedura memorizzata di sistema è deprecata, quindi mi aspetterei sicuramente di vedere una riga per quello. Se lo eseguo in questo momento, potrei aspettarmi di ottenere 2 righe in totale:1 per l'esempio precedente e 1 per questo esempio.

Ma a quanto pare, vengono aggiunte altre 11 righe al mio file 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;

Risultato (usando l'output verticale):

-[ 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)

Cosa sta succedendo qui?

Questo sta accadendo perché sp_depends la stessa procedura memorizzata di sistema utilizza funzionalità deprecate.

Non solo ottengo 1 riga per l'esecuzione di sp_depends . Ottengo anche 1 riga per ogni funzionalità deprecata utilizzata da quella stored procedure (sia nella stored procedure che in un altro oggetto a cui fa riferimento). In questo caso ottengo 10 righe in più.

Ho dato una rapida occhiata a sp_depends 's definizione e ho visto che fa riferimento (deprecato) a sysdepends in diversi punti, e quella vista fa riferimento (il deprecato) a sql_dependencies . Ho anche visto che usa stringhe letterali come alias di colonna, una pratica che è anche contrassegnata per la deprecazione. Tutto ciò supporta ciò che vedo nel file XEL.

Maggiori dettagli su ciascuna funzione obsoleta

Vedere l'articolo di Microsoft Funzionalità del motore di database obsoleto in SQL Server 2017 per consigli su come gestire ogni elemento obsoleto. Tale elenco è esattamente lo stesso di SQL Server 2016.

Riferimento alla documentazione Microsoft

  • Avvio rapido:eventi estesi in SQL Server
  • CREA SESSIONE EVENTO
  • SESSIONE ALTER EVENTO
  • sys.fn_xe_file_target_read_file
  • Lettura dei dati dell'evento 101:che succede con l'XML?