Database
 sql >> Base de données >  >> RDS >> Database

Comprendre la perte d'événement avec les événements étendus

Ma collègue, Erin Stellato, m'a récemment posé une question sur où et pourquoi la perte d'événements pourrait se produire avec les événements étendus. La question était le résultat d'un commentaire que quelqu'un avait fait sur l'un de ses articles de blog qui affirmait que showplan_xml les événements ne peuvent pas être collectés par XE Profiler ou via un flux « en direct » des événements à partir du serveur. Je sais que ce n'est pas correct car j'ai régulièrement démontré les impacts négatifs sur les performances de l'utilisation de l'événement post_query_execution_showplan contre une charge de travail de production en ajoutant l'événement dans l'interface utilisateur et en le faisant regarder les données en direct, donc cela a commencé une discussion plus approfondie comment et quand les événements étendus supprimeront un événement qui a été généré pendant la collecte de données.

La taille de l'événement compte

Les événements étendus configurent l'espace de la mémoire tampon interne pour une session d'événements lors de son démarrage initial sur le serveur, et la configuration des options de session d'événements détermine la taille des mémoires tampons et la taille maximale de l'événement que la session d'événements peut collecter. Alors que la plupart des événements générés par les événements étendus sont relativement légers et petits au format binaire, des événements spécifiques peuvent générer une charge utile de données beaucoup plus importante qui doit être mise en mémoire tampon. Les options de session d'événements par défaut donnent une configuration de session avec trois mémoires tampons internes pour contenir des événements d'une taille de 1 441 587 octets. La taille et le nombre de tampons de mémoire pour une session d'événements peuvent être trouvés dans le DMV sys.dm_xe_sessions pendant que la session STATE=START sur le serveur :

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

Notez qu'il n'y a aucun tampon volumineux pour chacune des sessions d'événements définies par le système et que la taille du tampon volumineux est également définie sur zéro, ce qui correspond à la configuration par défaut. Les tampons volumineux d'une session d'événements ne sont créés que lorsque l'option de session MAX_EVENT_SIZE est configurée pour la session d'événements. La valeur par défaut de cette option est 0, ce qui signifie que l'événement le plus important que la session d'événements peut réellement consommer est la taille d'une mémoire tampon normale, qui est de 1 441 587 octets. Pour certains événements, comme ceux qui produisent le showplan_xml, il est en fait relativement facile d'avoir une taille d'événement supérieure à la taille de la mémoire tampon par défaut pour la session d'événements. Dans ces cas, le grand événement serait en fait rejeté par la session d'événements car il ne peut pas être placé dans une mémoire tampon pour être distribué.

Contrôle de la perte d'événements

Il existe trois options de session spécifiques qui déterminent la taille d'un événement qu'une session d'événements peut réellement collecter, et une qui contrôle la manière dont les événements sont supprimés lorsque la mémoire tampon de la session d'événements est pleine ou sous pression. Ces quatre éléments sont importants lorsque nous parlons de collecter des événements qui pourraient générer une charge utile d'événements importante et nous voulons minimiser le risque que nous puissions potentiellement supprimer un événement. Un exemple de session d'événement qui serait sujette à la perte d'événements en raison de la pression de mémoire dans l'espace tampon pour la session d'événement est ci-dessous :

CREATE EVENT SESSION [Locks] ON SERVER 
ADD EVENT sqlserver.lock_acquired,
ADD EVENT sqlserver.lock_released
ADD TARGET package0.event_file(SET filename=N'Locks',max_file_size=(5),max_rollover_files=(4))
WITH (MAX_MEMORY=4096 KB,
MEMORY_PARTITION_MODE=NONE,
EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,
MAX_EVENT_SIZE=0 KB);

Remarque :Il ne s'agit pas d'une session d'événement que je recommanderais d'exécuter sur une charge de travail de production ; le volume de données qu'elle générerait serait important, car elle suit chaque acquisition et libération de verrou.

Si nous démarrons cette session, puis exécutons le générateur de charge de travail AdventureWorks Books Online disponible sur mon blog sur une instance de SQL Server, la session commencera rapidement à supprimer des événements en raison de la génération rapide d'événements et du retard de vidage de la mémoire tampon vers la cible event_file. qui est configuré. Le nombre d'événements supprimés par une session d'événements peut être suivi dans la DMV sys.dm_xe_sessions si les options de session d'événements ont été configurées avec EVENT_RETENTION_MODE =ALLOW_SINGLE_EVENT_LOSS. Si la session d'événements est configurée avec EVENT_RETENTION_MODE=ALLOW_MULTIPLE_EVENT_LOSS, des mémoires tampons entières d'événements peuvent être supprimées et cela ne compte que le nombre de tampons supprimés et non le nombre d'événements individuels contenus dans chaque tampon.

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_size
FROM sys.dm_xe_sessions AS s;

Ici, nous pouvons voir que 100 521 événements ont été supprimés et que la plus grande taille d'un événement supprimé était de 176 octets, ce qui est inférieur à la taille de notre espace tampon normal. Nous atteignons donc simplement la pression normale de l'espace mémoire tampon. Cependant, si nous créons une session d'événements qui collecte les deux événements showplan (voir cet article pour savoir pourquoi cela affectera gravement les performances et ne devrait pas être fait sur les serveurs de production), ainsi que les événements de démarrage et d'achèvement du lot et générer des événements plus importants plans, nous pouvons déclencher une perte d'événement en raison de la taille de l'événement.

CREATE EVENT SESSION [DropsEvents] ON SERVER 
ADD EVENT sqlserver.query_post_execution_showplan,
ADD EVENT sqlserver.query_pre_execution_showplan,
ADD EVENT sqlserver.sql_batch_completed,
ADD EVENT sqlserver.sql_batch_starting;

Ici, nous pouvons voir que le plus grand_event_dropped_size est supérieur à notre regular_buffer_size, cela signifie donc que nous devons modifier la configuration de nos tampons de session. Si nous augmentons le MAX_MEMORY pour la session d'événements, cela peut augmenter la taille de nos tampons réguliers. La valeur par défaut n'est que de 4 Mo, d'où provient la taille de mémoire tampon de 1,4 Mo indiquée ci-dessus. Si nous modifions cela pour qu'il soit de 64 Mo pour la session d'événement, le regular_buffer_size aura une taille de 22,4 Mo, ce qui conviendra à notre événement abandonné de 3,7 Mo. L'autre option consiste à définir l'option MAX_EVENT_SIZE qui fournit le large_buffer_size pour les grands événements et est divisé par deux pour la session.

CREATE EVENT SESSION [CollectsEvents] ON SERVER 
ADD EVENT sqlserver.query_post_execution_showplan,
ADD EVENT sqlserver.query_pre_execution_showplan,
ADD EVENT sqlserver.sql_batch_completed,
ADD EVENT sqlserver.sql_batch_starting
WITH (MAX_MEMORY=65536 KB,MAX_EVENT_SIZE=65536 KB,MEMORY_PARTITION_MODE=NONE);

Nous pouvons donc voir ici les deux grands tampons d'une taille de 33,6 Mo et après avoir exécuté à nouveau le même plan générant une charge de travail, nous n'avons aucun événement abandonné pour notre nouvelle session CollectsEvents, mais nous avons doublé les événements abandonnés pour notre session DropsEvents en utilisant les valeurs par défaut.

Donc, voilà; pourquoi certains événements peuvent ne pas être collectés par une session d'événements, comment procéder pour résoudre les problèmes lorsque des événements sont supprimés et comment déterminer si c'est la taille de l'événement qui est à l'origine du problème. La plupart des sessions que je vois en cours d'utilisation sur les systèmes clients ont les valeurs par défaut pour les options de session d'événement, en particulier en ce qui concerne la mémoire. Il s'agit d'un domaine dans lequel, une fois que vous aurez compris le mécanisme de mise en mémoire tampon utilisé par les événements étendus, puis que vous aurez pris en compte la taille des événements susceptibles d'être générés, vous commencerez à modifier la façon dont les options de session sont définies pour minimiser le potentiel d'événements. supprimées en raison de limites d'espace mémoire ou de contraintes de taille d'événement.