sql >> Base de Datos >  >> RDS >> Sqlserver

Uso de eventos extendidos para registrar funciones obsoletas que se usan en una instancia de SQL Server (ejemplo de T-SQL)

Eventos extendidos es un sistema ligero de supervisión del rendimiento que permite a los usuarios recopilar los datos necesarios para supervisar y solucionar problemas en SQL Server.

Este artículo demuestra cómo se pueden usar los eventos extendidos para crear un archivo de registro que contenga todas las características obsoletas que aún se usan en una instancia de SQL Server. El registro registra todas las ocurrencias desde que se inició la sesión del evento.

Si solo desea un recuento rápido de cuántas veces se ha utilizado una función en desuso desde que se inició SQL Server, consulte la forma más rápida de encontrar funciones en desuso que todavía se utilizan en una instancia de SQL Server.

Pero si necesita un registro más detallado que incluya cosas como; la instrucción SQL utilizada que contiene la función obsoleta, la base de datos contra la que se ejecutó, el usuario que la ejecutó, la hora en que se ejecutó, etc., siga leyendo.

Crear la sesión de evento extendida

El primer paso es crear la sesión de eventos extendida. Aquí especificamos el origen de los eventos, el destino de la sesión del evento y las opciones de la sesión del 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
    );

En este caso, especifico un objetivo de /var/opt/mssql/tmp/DeprecationEvents.xel . Esto significa que los datos del evento se almacenarán en ese archivo. Puede especificar cualquier nombre de archivo y ruta.

Este ejemplo usa una ruta de archivo de Linux, que usa barras diagonales. Si está en Windows, necesitará usar barras invertidas. Por ejemplo:C:\Temp\DeprecationEvents.xel .

Iniciar la Sesión de Evento Extendido

La creación de la sesión del evento no la inicia. Usar ALTER EVENT SESSION para detenerlo y comenzarlo. En este caso queremos iniciarlo:

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

Hacer algo obsoleto

Ahora que comenzamos la sesión de eventos extendida, ejecutemos un código obsoleto:

SELECT * FROM sys.sql_dependencies;

Porque sys.sql_dependencies está en desuso, ese código agregará datos al archivo XEL que especificamos anteriormente.

Ver el archivo XEL

Ahora que (presuntamente) hemos agregado datos a nuestro archivo XEL, echemos un vistazo:

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>

En este caso, solo devolví event_data , porque ahí es donde residen todos los datos de eventos.

Desafortunadamente, no es el más fácil de leer para los humanos.

¿Qué sucede si lo formateo?

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

Es un poco más fácil de leer cuando está formateado, pero podemos hacerlo mejor que eso.

Analizar el archivo XEL

En este ejemplo, analizo el archivo XEL para poder ver los datos en una cuadrícula, como cualquier otra consulta de base de datos.

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

Estoy usando la salida vertical aquí para que sea más fácil de leer sin tener que desplazarse horizontalmente. Esto significa que los encabezados de las columnas están a la izquierda y los datos a la derecha. Si ejecuta esto usando una GUI como SSMS o Azure Data Studio, probablemente lo verá en el formato de cuadrícula de tabla habitual (a menos que haya especificado lo contrario).

¿Múltiples filas para una sola característica obsoleta?

En ocasiones, su archivo XEL puede obtener múltiples entradas para un solo evento. Por ejemplo, ejecuta un solo procedimiento almacenado en desuso una vez, solo para descubrir que se devuelven 10 u 11 filas de su archivo XEL para esa sola declaración.

He aquí un ejemplo:

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

El sp_depends El procedimiento almacenado del sistema está en desuso, por lo que definitivamente esperaría ver una fila para eso. Si ejecuto eso ahora mismo, podría esperar terminar con 2 filas en total:1 para el ejemplo anterior y 1 para este ejemplo.

Pero resulta que se agregaron 11 filas más a mi archivo 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 salida 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)

¿Qué está pasando aquí?

Esto sucede porque sp_depends El propio procedimiento almacenado del sistema utiliza funciones obsoletas.

No solo obtengo 1 fila para ejecutar sp_depends . También obtengo 1 fila por cada función obsoleta que usa ese procedimiento almacenado (ya sea en el procedimiento almacenado o en otro objeto al que hace referencia). En este caso obtengo 10 filas extra.

Eché un vistazo rápido a sp_depends 's definición, y vi que hace referencia (lo obsoleto) sysdepends en varios lugares, y esa vista hace referencia (la obsoleta) sql_dependencies . También vi que usa literales de cadena como alias de columna, una práctica que también está marcada como obsoleta. Todo eso respalda lo que veo en el archivo XEL.

Más detalles sobre cada función obsoleta

Consulte el artículo de Microsoft Funciones obsoletas del motor de base de datos en SQL Server 2017 para obtener recomendaciones sobre cómo tratar cada elemento obsoleto. Esa lista es exactamente la misma que la de SQL Server 2016.

Referencia de documentación de Microsoft

  • Inicio rápido:eventos extendidos en SQL Server
  • CREAR SESIÓN DE EVENTO
  • CAMBIAR LA SESIÓN DEL EVENTO
  • sys.fn_xe_file_target_read_file
  • Lectura de datos de eventos 101:¿Qué pasa con el XML?