Database
 sql >> Baza danych >  >> RDS >> Database

Zrozumienie utraty zdarzeń z rozszerzonymi zdarzeniami

Moja koleżanka, Erin Stellato, ostatnio zadała mi pytanie o to, gdzie i dlaczego utrata zdarzeń może mieć miejsce w przypadku zdarzeń rozszerzonych. Pytanie było wynikiem komentarza, który ktoś napisał w jednym z jej postów na blogu, w którym twierdził, że showplan_xml zdarzenia nie mogą być zbierane przez XE Profiler lub poprzez transmisję „na żywo” zdarzeń z serwera. Zdarza mi się wiedzieć, że to nie jest poprawne, ponieważ rutynowo demonstrowałem negatywny wpływ na wydajność używania zdarzenia post_query_execution_showplan w stosunku do obciążenia produkcyjnego, dodając zdarzenie w interfejsie użytkownika i obserwując dane na żywo, więc rozpoczęło się bardziej dogłębną dyskusję o tym, jak i kiedy Extended Events odrzuci zdarzenie, które zostało wygenerowane podczas zbierania danych.

Rozmiar wydarzenia ma znaczenie

Zdarzenia rozszerzone konfigurują przestrzeń bufora pamięci wewnętrznej dla sesji zdarzeń, gdy jest ona początkowo uruchamiana na serwerze, a konfiguracja opcji sesji zdarzeń określa wielkość buforów pamięci oraz maksymalny rozmiar zdarzenia, które może zebrać sesja zdarzeń. Podczas gdy większość zdarzeń generowanych przez zdarzenia rozszerzone jest stosunkowo lekka i niewielka w formacie binarnym, określone zdarzenia mogą generować znacznie większy ładunek danych, które muszą być buforowane. Domyślne opcje sesji zdarzeń skutkują konfiguracją sesji z trzema wewnętrznymi buforami pamięci do przechowywania zdarzeń o rozmiarze 1 441 587 bajtów. Rozmiar i liczbę buforów pamięci dla sesji zdarzeń można znaleźć w sys.dm_xe_sessions DMV, gdy sesja STATE=START na serwerze:

SELECT s.name, s.total_regular_buffers, s.regular_buffer_size, s.total_large_buffers, s.large_buffer_size, s.total_buffer_sizeFROM sys.dm_xe_sessions AS s;

Zauważ, że nie ma dużych buforów dla każdej sesji zdarzeń zdefiniowanych przez system, a duży rozmiar bufora jest również ustawiony na zero, co jest konfiguracją domyślną. Duże bufory dla sesji zdarzenia są tworzone tylko wtedy, gdy dla sesji zdarzenia jest skonfigurowana opcja sesji MAX_EVENT_SIZE. Wartość domyślna tej opcji to 0, co oznacza, że ​​największym zdarzeniem, jakie może faktycznie wykorzystać sesja zdarzenia, jest rozmiar zwykłego bufora pamięci, czyli 1 441 587 bajtów. W przypadku niektórych zdarzeń, takich jak te, które generują showplan_xml, stosunkowo łatwo jest mieć rozmiar zdarzenia większy niż domyślny rozmiar bufora pamięci dla sesji zdarzeń. W takich przypadkach duże zdarzenie zostałoby w rzeczywistości odrzucone przez sesję zdarzenia, ponieważ nie można go umieścić w buforze pamięci w celu rozesłania.

Kontrolowanie utraty zdarzeń

Istnieją trzy konkretne opcje sesji, które określają, jak duże zdarzenie może faktycznie zebrać sesja zdarzeń, oraz jedna, która kontroluje sposób odrzucania zdarzeń, gdy pamięć buforowa dla sesji zdarzeń jest pełna lub pod presją. Wszystkie te cztery rzeczy mają znaczenie, gdy mówimy o zbieraniu zdarzeń, które mogą generować duży ładunek zdarzenia, i chcemy zminimalizować prawdopodobieństwo, że potencjalnie możemy porzucić zdarzenie. Przykładowa sesja zdarzenia, która byłaby podatna na utratę zdarzenia z powodu obciążenia pamięci w przestrzeni buforowej dla sesji zdarzenia, jest poniżej:

UTWÓRZ SESJĘ ZDARZENIA [Blokady] NA SERWERZE DODAJ ZDARZENIE sqlserver.lock_acquired,DODAJ ZDARZENIE sqlserver.lock_releasedADD TARGET package0.event_file(SET filename=N'Locks',max_file_size=(5),max_rollover_files=(4))WIORYTH (MAX_MEM) =4096 KB,MEMORY_PARTITION_MODE=BRAK,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_EVENT_SIZE=0 KB);

Uwaga:nie jest to sesja zdarzeń, którą kiedykolwiek poleciłbym uruchomić na obciążeniu produkcyjnym – ilość danych, które by wygenerowała, byłaby znacząca, ponieważ śledzi ona każde nabycie i zwolnienie blokady.

Jeśli rozpoczniemy tę sesję, a następnie uruchomimy generator obciążeń AdventureWorks Books Online, który jest dostępny w moim blogu, w odniesieniu do wystąpienia programu SQL Server, sesja zacznie szybko usuwać zdarzenia ze względu na szybkie generowanie zdarzeń i opóźnienie w opróżnianiu buforu do celu event_file który jest skonfigurowany. Liczbę zdarzeń, które zostały porzucone przez sesję zdarzeń, można śledzić w DMV sys.dm_xe_sessions, jeśli opcje sesji zdarzeń zostały skonfigurowane z EVENT_RETENTION_MODE =ALLOW_SINGLE_EVENT_LOSS. Jeśli sesja zdarzenia jest skonfigurowana z EVENT_RETENTION_MODE=ALLOW_MULTIPLE_EVENT_LOSS, wtedy całe bufory pamięci zdarzeń mogą zostać usunięte i liczy się tylko, ile buforów zostało usuniętych, a nie liczbę poszczególnych zdarzeń zawartych w każdym buforze.

SELECT s.name, s.total_regular_buffers, s.regular_buffer_size, s.total_large_buffers, s.large_buffer_size, s.dropped_event_count, s.dropped_buffer_count, s.largest_event_dropped_sizem_sses. 

Tutaj widzimy, że 100 521 zdarzeń zostało usuniętych, a największy rozmiar usuniętego zdarzenia wynosił 176 bajtów, co jest mniejsze niż rozmiar naszego zwykłego miejsca w buforze, więc po prostu osiągamy normalne ciśnienie w pamięci bufora. Jeśli jednak utworzymy sesję zdarzeń, która zbiera dwa zdarzenia showplanu (zobacz ten artykuł, dlaczego wpłynie to negatywnie na wydajność i nie powinno być wykonywane na serwerach produkcyjnych), wraz z wsadowymi zdarzeniami rozpoczynającymi i zakończonymi i generujemy większe planów, możemy spowodować utratę zdarzeń ze względu na wielkość zdarzenia.

UTWÓRZ SESJĘ ZDARZENIA [DropsEvents] NA SERWERZE DODAJ ZDARZENIE sqlserver.query_post_execution_showplan,DODAJ ZDARZENIE sqlserver.query_pre_execution_showplan,DODAJ ZDARZENIE sqlserver.sql_batch_completed,DODAJ ZDARZENIE sqlserver.sql; 

Tutaj widzimy, że największy_event_dropped_size jest większy niż nasz regular_buffer_size, co oznacza, że ​​musimy zmienić konfigurację naszych buforów sesji. Jeśli zwiększymy MAX_MEMORY dla sesji zdarzeń, może to zwiększyć rozmiar naszych zwykłych buforów. Domyślna wartość to tylko 4 MB, skąd pochodzi pokazany powyżej rozmiar bufora 1,4 MB. Jeśli zmienimy to na 64 MB na sesję zdarzenia, regular_buffer_size będzie miał rozmiar 22,4 MB, co pomieści nasze 3,7 MB porzuconego zdarzenia. Inną opcją jest ustawienie opcji MAX_EVENT_SIZE, która zapewnia duży_buffer_size dla dużych wydarzeń i jest dzielony przez dwa dla sesji.

UTWÓRZ SESJĘ ZDARZENIA [CollectsEvents] NA SERWERZE DODAJ ZDARZENIE sqlserver.query_post_execution_showplan,DODAJ ZDARZENIE sqlserver.query_pre_execution_showplan,DODAJ ZDARZENIE sqlserver.sql_batch_completed,DODAJ ZDARZENIE sqlserver=KBMODEEV. 

Tak więc widzimy dwa duże bufory o rozmiarze 33,6 MB i po ponownym uruchomieniu tego samego planu generującego obciążenie robocze nie mamy porzuconych zdarzeń dla naszej nowej sesji CollectsEvents, ale podwoiliśmy porzucone zdarzenia dla naszej sesji DropsEvents przy użyciu wartości domyślnych.

Więc masz to; dlaczego niektóre zdarzenia mogą nie być zbierane przez sesję zdarzeń, jak postępować w przypadku rozwiązywania problemów, gdy zdarzenia są usuwane i jak ustalić, czy przyczyną problemu jest rozmiar zdarzenia. Wiele sesji, które widzę w rzeczywistych zastosowaniach w systemach klienckich, ma domyślne opcje sesji zdarzeń, zwłaszcza jeśli chodzi o pamięć. Jest to jeden obszar, w którym po zrozumieniu mechanizmu buforowania używanego przez zdarzenia rozszerzone, a następnie rozważeniu rozmiaru zdarzeń, które mogą potencjalnie zostać wygenerowane, zaczniesz wprowadzać zmiany w sposobie definiowania opcji sesji, aby zminimalizować możliwość wystąpienia zdarzeń porzucone z powodu ograniczeń miejsca w pamięci lub ograniczeń rozmiaru zdarzenia.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Notacja Barkera

  2. Model danych agencji nieruchomości

  3. Jak używać klauzuli ORDER BY w SQL?

  4. Jak naprawić ORA-12505, TNS:listener nie zna obecnie identyfikatora SID podanego w deskryptorze połączenia

  5. Halloweenowy problem – część 1