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

Brug af udvidede hændelser til at logge forældede funktioner, der bruges i en SQL Server-instans (T-SQL-eksempel)

Udvidede begivenheder er et let ydelsesovervågningssystem, der gør det muligt for brugere at indsamle data, der er nødvendige for at overvåge og fejlfinde problemer i SQL Server.

Denne artikel viser, hvordan udvidede hændelser kan bruges til at oprette en logfil, der indeholder alle forældede funktioner, der stadig bruges i en forekomst af SQL Server. Loggen registrerer alle hændelser siden begivenhedssessionen blev startet.

Hvis du blot vil have en hurtig optælling af, hvor mange gange en forældet funktion er blevet brugt, siden SQL Server blev startet op, se Hurtigste måde at finde forældede funktioner, der stadig bruges i en SQL Server-instans.

Men hvis du har brug for en mere detaljeret log, der inkluderer ting som; den anvendte SQL-sætning, der indeholder den forældede funktion, databasen den blev kørt imod, brugeren der kørte den, tidspunktet den blev kørt osv., læs videre.

Opret den udvidede begivenhedssession

Første trin er at oprette den udvidede begivenhedssession. Her angiver vi kilden til begivenhederne, målet for begivenhedssessionen og mulighederne for begivenhedssessionen.

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 dette tilfælde angiver jeg et mål for /var/opt/mssql/tmp/DeprecationEvents.xel . Det betyder, at hændelsesdataene vil blive gemt i denne fil. Du kan angive et hvilket som helst filnavn og sti.

Dette eksempel bruger en Linux-filsti, som bruger skråstreger. Hvis du er på Windows, skal du bruge omvendte skråstreg. For eksempel:C:\Temp\DeprecationEvents.xel .

Start den udvidede begivenhedssession

Oprettelse af begivenhedssessionen starter den ikke. Brug ALTER EVENT SESSION at stoppe og starte den. I dette tilfælde ønsker vi at starte det:

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

Gør noget forældet

Nu hvor vi har startet den udvidede begivenhedssession, lad os køre noget forældet kode:

SELECT * FROM sys.sql_dependencies;

Fordi sys.sql_dependencies er forældet, vil den kode tilføje data til XEL-filen, som vi tidligere har angivet.

Se XEL-filen

Nu hvor vi (formentlig) har tilføjet data til vores XEL-fil, lad os tage et kig på det:

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 dette tilfælde returnerede jeg kun event_data , fordi det er der alle begivenhedsdata ligger.

Desværre er det ikke det nemmeste for os mennesker at læse.

Hvad hvis jeg formaterer 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 er lidt nemmere at læse, når det er formateret, men vi kan gøre det bedre end det.

Parse XEL-filen

I dette eksempel analyserer jeg XEL-filen, så jeg kan se dataene i et gitter, ligesom enhver anden databaseforespørgsel.

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 (ved hjælp af lodret output):

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.

Jeg bruger lodret output her for at gøre det nemmere at læse uden at skulle rulle vandret. Det betyder, at kolonneoverskrifterne er til venstre, og dataene er til højre. Hvis du kører dette ved hjælp af en GUI såsom SSMS eller Azure Data Studio, vil du sandsynligvis se det i det sædvanlige tabelgitterformat (medmindre du har angivet andet).

Flere rækker til en enkelt forældet funktion?

Din XEL-fil kan nogle gange få flere poster for en enkelt begivenhed. For eksempel udfører du en enkelt forældet lagret procedure én gang, kun for at finde ud af, at 10 eller 11 rækker returneres fra din XEL-fil for den enkelte sætning.

Her er et eksempel:

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

sp_depends den systemlagrede procedure er forældet, så det ville jeg bestemt forvente at se en række for. Hvis jeg udfører det lige nu, kan jeg forvente at ende med 2 rækker i alt:1 for det forrige eksempel og 1 for dette eksempel.

Men som det viser sig, er der tilføjet 11 rækker mere til 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 (ved hjælp af lodret output):

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

Hvad sker der her?

Dette sker, fordi sp_depends selve den systemlagrede procedure bruger forældede funktioner.

Ikke kun får jeg 1 række til at udføre sp_depends . Jeg får også 1 række for hver forældet funktion, der bruges af den lagrede procedure (uanset om det er i den lagrede procedure eller i et andet objekt, som det refererer til). I dette tilfælde får jeg 10 ekstra rækker.

Jeg kiggede hurtigt på sp_depends 's definition, og jeg så, at den refererer til (den forældede) sysdepends flere steder, og den visningsreferencer (de forældede) sql_dependencies . Jeg så også, at den bruger strenge bogstaver som kolonnealiaser, en praksis, der også er markeret for udfasning. Alt det understøtter det, jeg ser i XEL-filen.

Flere detaljer om hver forældet funktion

Se Microsofts artikel Forældede databasemotorfunktioner i SQL Server 2017 for anbefalinger til, hvordan man håndterer hvert forældet element. Den liste er nøjagtig den samme som den for SQL Server 2016.

Microsoft Documentation Reference

  • Hurtigstart:Udvidede hændelser i SQL Server
  • OPRET BEGIVENHEDSSESSION
  • ÆNDR BEGIVENHEDSSESSION
  • sys.fn_xe_file_target_read_file
  • Læsning af hændelsesdata 101:Hvad sker der med XML?

  1. Rediger materialiseret visningsforespørgsel

  2. Sådan slipper du en begrænsning i SQL Server (T-SQL)

  3. SQL Server 2008 personsøgningsmetoder?

  4. Sådan returnerer du måneds- og dagnavne på et andet sprog i MariaDB