Dans un groupe de disponibilité de 3 nœuds, une réplique secondaire deviendra souvent soumise à la décalage de refonte en raison des causes couvertes dans la documentation de Microsoft:
De mon expérience, les problèmes que je vois le plus souvent semblent être:
Une transaction à long terme sur la réplique principale empêche les mises à jour d'être lues sur la réplique secondaire.
et
Le thread de Redo sur la réplique secondaire est bloqué à partir de modifications de la langue de définition de données (DDL) par une requête en lecture seule. Le thread de Redo doit être débloqué avant de pouvoir créer d'autres mises à jour disponibles pour la charge de travail en lecture.
Je peux l'observer en examinant la session d'événements prolongée "Alwayon Health":
Lorsqu'une application permet de lire uniquement des requêtes sur la réplique secondaire, si une opération fortement enregistrée (comme optimisation de l'index) est en cours d'exécution sur le décalage de synchronisation primaire, se fait prononcer et je vois un énorme arriéré dans des enregistrements de journal non engagés sur le secondaire, comme c'est décrit. dans les documents ci-dessus.
La question que j'ai est la raison pour laquelle je vois CMemTrhead attend la réplique secondaire lorsque la réorganisation de l'index a lieu sur le primaire:
Est-ce ce comportement normal/attendu ou autre chose?
Bien qu'il y ait une activité de lecture sur la réplique secondaire, ces requêtes sont le plus souvent <1 seconde en heure, avec la requête de moins de 10 secondes occasionnelle. Utilisation de la CPU environ 5%.
Output of @@VERSION: Microsoft SQL Server 2016 (SP1-CU10-GDR) (KB4293808) -
13.0.4522.0 (X64) Jul 17 2018 22:41:29 Copyright (c) Microsoft Corporation
Enterprise Edition: Core-based Licensing (64-bit) on Windows Server 2012 R2
Standard 6.3 <X64> (Build 9600: ) (Hypervisor)
Mise à jour: Je viens de repérer cette attente survenant à nouveau lors de l'optimisation de l'index. J'ai tué le travail d'index et cela a évidemment arrêté le décalage de la synchronisation de l'augmentation, mais l'attente CMEMTrhead a continué et que Redo semblait assez lent. J'ai également remarqué une occasioinale paralleling_redo_flow_control attend sur le fil de redro, donc je suis simplement exécuté DBCC TRACEON (3459, -1)
et soudainement redro vitesse augmentée et l'arriéré a commencé à effacer extrêmement rapidement.
Vous pouvez voir que j'ai arrêté l'optimisation de l'index à 13h20 et a appliqué le drapeau de trace à 13h45. Notez que le graphique d'attente SQLSentryone est dans UTC tandis que ce dernier graphique est en BST.
Je viens de constater ce comportement exact sur une réplique ASYNC
réplique avec rien d'exécution. Le même drapeau de trace résolut à nouveau. Je suis surpris que j'avais pensé que cela a été causé par des requêtes en lecture seule, ce qui a entraîné une contention sur SYNC
réplicas avec des opérations fortement enregistrées (comme la maintenance de l'index) sur le primaire. A cette occasion, nous avons une maintenance de l'indice sur le primaire, une réplique SYNC
sans problème de Redo, mais une réplique ASYNC
avec ce problème. Ici, vous pouvez voir les WAIT
stats montrant CMEMThread et le point lorsque le drapeau de trace a été activé, l'attente CMEMThead est partie et la conflit de Redo est résolue.
Je n'ai pas accès à un groupe de disponibilité secondaire qui fait vraiment cuire :-)
mais je peux partager certaines choses qui vous mèneront un peu plus loin.
Lorsque vous avez le rétablissement parallèle sur le secondaire, une activité comme Redo de la maintenance de l'indice lourd est accompagnée de CMEMTrhead attend. Ceux-ci disparaissent lorsque le drapeau de trace 3459 est activé dans le monde entier. Et vous vous demandez si le comportement d'attente CMEMTrhead est dû à un bug.
Il est peu probable que le comportement d'attente CMEMThead soit dû à un bug.
La publication ci-dessous est de quelques années, mais toujours mon préféré en expliquant l'intention de CmemThead attend le contrôle de la série de sérialisation de l'objet mémoire. Bob explique que ces objets de mémoire avec accès potentiellement contrôlé par CMEMThead Waits peuvent être globaux, partitionnés par nœud numa ou partitionné par cpu.
Comment ça marche: cmemThread et les débogage de Bob Dorr & Rohit Nayak 2012 20 décembre https://techcommunity.microsoft.com/t5/sql-server-support/how-it-works-cmemThead-and-debugging-and-debugging- eux/ba-p/317488
L'une des améliorations importantes de SQL Server 2016 a été l'introduction de partitionnement d'objets de mémoire dynamique. Avant SQL Server 2016, la conflit a été observée comme une question importante sur des objets de mémoire globaux individuels, les drapeaux de trace individuels permettraient de partitionnement de cet objet par Numa noeud (drapeau de trace 1236 en est un exemple). Et le drapeau de trace 8048 favoriserait de nombreux objets de mémoire partitionnés au niveau du nœud Numa pour être partitionné au niveau de la CPU.
Dans SQL Server 2016, de nombreux objets de mémoire sont devenus éligibles à la partition d'objet dynamique: ils commencaient avec une seule partition globale, mais comme la conflit a été détectée, ils seraient promus au nœud Numa partitionné. Si une autre conflit est détectée, l'objet serait à nouveau promu à la CPU partitionné.
Plus sur cela dans ce blog post.
Objet de mémoire dynamique Ajay Jagannathan 2016 27 juin https://techcommunity.microsoft.com/t5/sql-server/dynamic-memory-Object-scaling/ba-p/384755
Ainsi, tandis que lorsque l'activité de Redo parallèle constate que High CmemTrhead attend, la surveillance des résultats de la requête ci-dessous au fil du temps révélera quels objets de mémoire sont sous-tendance. Je pense que c'est probablement un objet global qui n'est pas admissible à une partition dynamique.
SELECT omo.type, memory_node_id, omo.pages_in_bytes, omo.partition_type, omo.partition_type_desc,
omo.waiting_tasks_count, omo.exclusive_access_count, omo.contention_factor
FROM sys.dm_os_memory_objects omo
WHERE omo.waiting_tasks_count > 0
ORDER BY omo.waiting_tasks_count DESC;
Ainsi, permettre à Global Trace Drapeau 3459 atténue le temps d'attente CMEMTrhead. Dans ce cas, cela doit être attendu. Global Trace Drapeau 3459 désactive le rétablissement parallèle, laissant le secondaire AG avec une série de série. Avec un seul fil de rétablissement pour l'activité de rétablissement secondaire du groupe de disponibilité, la conflit de l'objet de la mémoire présent avec le parallèle Redo est soudainement parti.
Quel que soit l'objet de la mémoire sous conflit dans ce scénario, celui-ci peut est possible (- === -) être possible pour une amélioration pour permettre de promouvoir de manière dynamique autant d'autres objets, ce qui atténuerait La CmemTrhead attend même avec un refait parallèle. Mais certains travaux sont plus difficiles ou plus chers à la partition que pour accomplir comme un seul objet global.