sql >> Databasteknik >  >> RDS >> Sqlserver

Använda utökade händelser för att logga föråldrade funktioner som används i en SQL Server-instans (T-SQL-exempel)

Utökade händelser är ett lättviktigt prestandaövervakningssystem som gör det möjligt för användare att samla in data som behövs för att övervaka och felsöka problem i SQL Server.

Den här artikeln visar hur utökade händelser kan användas för att skapa en loggfil som innehåller alla föråldrade funktioner som fortfarande används i en instans av SQL Server. Loggen registrerar alla händelser sedan händelsesessionen startade.

Om du bara vill ha en snabb räkning av hur många gånger en föråldrad funktion har använts sedan SQL Server startades, se Snabbaste sättet att hitta föråldrade funktioner som fortfarande används i en SQL Server-instans.

Men om du behöver en mer detaljerad logg som innehåller saker som; den använda SQL-satsen som innehåller den föråldrade funktionen, databasen den kördes mot, användaren som körde den, tiden då den kördes, etc, läs vidare.

Skapa den utökade händelsesessionen

Första steget är att skapa den utökade händelsesessionen. Här anger vi källan till händelserna, målet för händelsesessionen och alternativen för händelsesessionen.

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

I det här fallet anger jag ett mål för /var/opt/mssql/tmp/DeprecationEvents.xel . Detta innebär att händelsedata kommer att lagras i den filen. Du kan ange vilket filnamn och sökväg som helst.

Det här exemplet använder en Linux-filsökväg, som använder snedstreck. Om du använder Windows måste du använda snedstreck. Till exempel:C:\Temp\DeprecationEvents.xel .

Starta den utökade händelsesessionen

Att skapa händelsesessionen startar inte den. Använd ALTER EVENT SESSION att stoppa och starta den. I det här fallet vill vi starta det:

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

Gör något föråldrat

Nu när vi har startat den utökade händelsesessionen, låt oss köra lite föråldrad kod:

SELECT * FROM sys.sql_dependencies;

Eftersom sys.sql_dependencies är utfasad kommer den koden att lägga till data till XEL-filen som vi angav tidigare.

Visa XEL-filen

Nu när vi (förmodligen) har lagt till data till vår XEL-fil, låt oss ta en titt på den:

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

Resultat:

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

I det här fallet returnerade jag bara event_data , eftersom det är där all händelsedata finns.

Tyvärr är det inte det lättaste för oss människor att läsa.

Vad händer om jag formaterar det?

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

Det är lite lättare att läsa när det är formaterat, men vi kan göra bättre än så.

Parse XEL-filen

I det här exemplet analyserar jag XEL-filen så att jag kan se data i ett rutnät, precis som alla andra databasfrågor.

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

Resultat (med vertikal utdata):

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.

Jag använder vertikal utdata här för att göra det lättare att läsa utan att behöva rulla horisontellt. Det betyder att kolumnrubrikerna är till vänster och data till höger. Om du kör detta med ett grafiskt användargränssnitt som SSMS eller Azure Data Studio, kommer du förmodligen att se det i det vanliga tabellformatet (om du inte har angett något annat).

Flera rader för en enstaka utfasad funktion?

Din XEL-fil kan ibland få flera poster för en enda händelse. Till exempel, du kör en enstaka föråldrad lagrad procedur en gång, bara för att upptäcka att 10 eller 11 rader returneras från din XEL-fil för den enstaka satsen.

Här är ett exempel:

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

sp_depends Systemlagrad procedur är utfasad, så jag skulle definitivt förvänta mig att se en rad för det. Om jag kör det just nu kan jag förvänta mig att få 2 rader totalt:1 för föregående exempel och 1 för det här exemplet.

Men som det visar sig, läggs ytterligare 11 rader till i min XEL-fil:

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;

Resultat (med vertikal utdata):

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

Vad händer här?

Detta händer eftersom sp_depends den systemlagrade proceduren i sig använder föråldrade funktioner.

Jag får inte bara 1 rad för att köra sp_depends . Jag får också 1 rad för varje utfasad funktion som används av den lagrade proceduren (oavsett om det är i den lagrade proceduren eller i ett annat objekt som den refererar till). I det här fallet får jag 10 extra rader.

Jag tittade snabbt på sp_depends s definition, och jag såg att den refererar till (den föråldrade) sysdepends på flera ställen, och att vyreferenser (de föråldrade) sql_dependencies . Jag såg också att den använder strängliterals som kolumnalias, en praxis som också är markerad för utfasning. Allt detta stöder det jag ser i XEL-filen.

Mer information om varje utfasad funktion

Se Microsofts artikel Utfasade databasmotorfunktioner i SQL Server 2017 för rekommendationer om hur man hanterar varje utfasad artikel. Den listan är exakt densamma som den för SQL Server 2016.

Microsoft Documentation Reference

  • Snabbstart:Utökade händelser i SQL Server
  • SKAPA EVENT SESSION
  • ÄNDRAR HÄNDELSESESSION
  • sys.fn_xe_file_target_read_file
  • Läsa händelsedata 101:Vad är det med XML?

  1. SQL Server Escape ett understreck

  2. Bind arrayparam till inbyggd fråga

  3. Hybrid OLTP/Analytics Databas Workloads i Galera Cluster med asynkrona slavar

  4. Hur spolar jag PRINT-bufferten i TSQL?