Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Używanie zdarzeń rozszerzonych do rejestrowania przestarzałych funkcji używanych w wystąpieniu programu SQL Server (przykład T-SQL)

Wydarzenia rozszerzone to lekki system monitorowania wydajności, który umożliwia użytkownikom zbieranie danych potrzebnych do monitorowania i rozwiązywania problemów w SQL Server.

W tym artykule pokazano, jak można użyć zdarzeń rozszerzonych do utworzenia pliku dziennika zawierającego wszystkie przestarzałe funkcje, które są nadal używane w wystąpieniu programu SQL Server. Dziennik rejestruje wszystkie zdarzenia od momentu rozpoczęcia sesji zdarzenia.

Jeśli chcesz tylko szybko zliczyć, ile razy przestarzała funkcja została użyta od momentu uruchomienia SQL Server, zobacz Najszybszy sposób na znalezienie przestarzałych funkcji, które są nadal używane w instancji SQL Server.

Ale jeśli potrzebujesz bardziej szczegółowego dziennika, który zawiera takie rzeczy; użyta instrukcja SQL zawierająca przestarzałą funkcję, bazę danych, z którą została uruchomiona, użytkownik, który ją uruchomił, czas jej uruchomienia itp., czytaj dalej.

Utwórz rozszerzoną sesję wydarzenia

Pierwszym krokiem jest utworzenie rozszerzonej sesji wydarzenia. Tutaj określamy źródło zdarzeń, cel sesji zdarzenia i opcje sesji zdarzenia.

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

W tym przypadku określam cel /var/opt/mssql/tmp/DeprecationEvents.xel . Oznacza to, że dane zdarzenia zostaną zapisane w tym pliku. Możesz określić dowolną nazwę pliku i ścieżkę.

W tym przykładzie użyto ścieżki pliku systemu Linux, która używa ukośników. Jeśli korzystasz z systemu Windows, musisz użyć ukośników odwrotnych. Na przykład:C:\Temp\DeprecationEvents.xel .

Rozpocznij rozszerzoną sesję wydarzenia

Utworzenie sesji eventowej jej nie rozpoczyna. Użyj ALTER EVENT SESSION zatrzymać i uruchomić. W tym przypadku chcemy go uruchomić:

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

Zrób coś przestarzałego

Teraz, gdy rozpoczęliśmy rozszerzoną sesję zdarzeń, uruchommy przestarzały kod:

SELECT * FROM sys.sql_dependencies;

Ponieważ sys.sql_dependencies jest przestarzałe, ten kod doda dane do pliku XEL, który określiliśmy wcześniej.

Wyświetl plik XEL

Teraz, gdy (prawdopodobnie) dodaliśmy dane do naszego pliku XEL, spójrzmy na to:

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

Wynik:

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

W tym przypadku zwróciłem tylko event_data , ponieważ tam znajdują się wszystkie dane zdarzeń.

Niestety, nie jest to najłatwiejsze dla nas ludzi.

A jeśli go sformatuję?

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

Po sformatowaniu jest nieco łatwiejszy do odczytania, ale możemy zrobić to lepiej.

Przeanalizuj plik XEL

W tym przykładzie analizuję plik XEL, aby móc zobaczyć dane w siatce, tak jak każde inne zapytanie do bazy danych.

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

Wynik (przy użyciu wyjścia pionowego):

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.

Używam tutaj wyjścia pionowego, aby ułatwić czytanie bez konieczności przewijania w poziomie. Oznacza to, że nagłówki kolumn znajdują się po lewej stronie, a dane po prawej. Jeśli uruchomisz to za pomocą graficznego interfejsu użytkownika, takiego jak SSMS lub Azure Data Studio, prawdopodobnie zobaczysz go w zwykłym formacie siatki tabeli (chyba że określiłeś inaczej).

Wiele wierszy dla jednej przestarzałej funkcji?

Twój plik XEL może czasami zawierać wiele wpisów dla jednego zdarzenia. Na przykład wykonujesz pojedynczą przestarzałą procedurę składowaną tylko po to, aby stwierdzić, że z pliku XEL zostało zwróconych 10 lub 11 wierszy dla tej pojedynczej instrukcji.

Oto przykład:

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

sp_depends systemowa procedura składowana jest przestarzała, więc na pewno spodziewałbym się, że zobaczę wiersz. Jeśli wykonam to teraz, mogę oczekiwać, że otrzymam w sumie 2 wiersze:1 dla poprzedniego przykładu i 1 dla tego przykładu.

Ale jak się okazuje, do mojego pliku XEL dodano jeszcze 11 wierszy:

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;

Wynik (przy użyciu wyjścia pionowego):

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

Co się tutaj dzieje?

Dzieje się tak, ponieważ sp_depends Sama procedura składowana systemu używa przestarzałych funkcji.

Nie tylko otrzymuję 1 wiersz do wykonania sp_depends . Otrzymuję również 1 wiersz dla każdej przestarzałej funkcji używanej przez tę procedurę składowaną (czy to w procedurze składowanej, czy w innym obiekcie, do którego się odwołuje). W tym przypadku dostaję 10 dodatkowych rzędów.

Rzuciłem okiem na sp_depends definicji i zobaczyłem, że odwołuje się do (przestarzałego) sysdepends w kilku miejscach i wyświetlają referencje (przestarzałe) sql_dependencies . Widziałem również, że używa literałów ciągów jako aliasów kolumn, co również jest oznaczone jako przestarzałe. Wszystko to obsługuje to, co widzę w pliku XEL.

Więcej szczegółów na temat każdej wycofanej funkcji

Zobacz artykuł firmy Microsoft Przestarzałe funkcje aparatu bazy danych w programie SQL Server 2017, aby uzyskać zalecenia dotyczące postępowania z każdym przestarzałym elementem. Ta lista jest dokładnie taka sama jak ta dla SQL Server 2016.

Dokumentacja Microsoft

  • Szybki start:rozszerzone zdarzenia w SQL Server
  • UTWÓRZ SESJĘ WYDARZENIA
  • ZAMIANA SESJA WYDARZENIA
  • sys.fn_xe_file_target_read_file
  • Odczytywanie danych o zdarzeniach 101:co się dzieje z XML?

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zapytanie ODBC na MS SQL Server zwracające pierwsze 255 znaków tylko w PHP PDO (FreeTDS)

  2. WSTAW WARTOŚCI, GDZIE NIE ISTNIEJĄ

  3. Pobierz lewą część ciągu w SQL Server (T-SQL)

  4. Wersjonowanie bazy danych SQL Server

  5. Jak zachować kolejność wstawiania w SQL Server