Comment reproduire «Impossible de continuer la numérisation avec NOLOCK en raison du mouvement des données»


10

J'obtiens parfois "Impossible de continuer l'analyse avec en NOLOCKraison du mouvement des données" avec certains gros travaux, qui ont WITH (NOLOCK)sur les requêtes sélectionnées.

Je comprends que cela a quelque chose à voir avec la tentative de sélection de données lorsqu'il y a eu un fractionnement de page qui a fait que les données ne sont plus là où elles étaient censées être - je suppose que c'est ce qui se passe dans mon environnement.

Comment pourrais-je reproduire cela?

J'essaie de contourner l'erreur à court terme et de réessayer lorsque cela se produit, mais je ne peux pas le tester si je ne peux pas le reproduire. Existe-t-il un moyen raisonnablement fiable de provoquer cela?

Lorsque cela se produit, l'exécution de la requête à nouveau aboutit - donc je n'ai pas vraiment de soucis concernant la corruption permanente des données ou de la base de données. Certaines des tables de la requête (ainsi que leurs index) sont souvent supprimées, recréées et repeuplées, donc je suppose que c'est quelque chose lié à cela.

La suppression NOLOCKest mon problème à long terme. La raison a NOLOCKété avancée en premier lieu parce que les requêtes sont si mauvaises qu'elles bloquaient les transactions au jour le jour, tout NOLOCKcomme un pansement pour arrêter les blocages (qui fonctionnaient). J'ai donc besoin d'un pansement sur un pansement jusqu'à ce que nous puissions trouver une solution permanente.

Si je pouvais le reproduire avec un Hello World, j'envisagerais probablement de placer le pansement dans le travail en moins d'une heure. Impossible de supprimer la recherche et le remplacement NOLOCK, car je recommencerais à récupérer les blocages de l'application, ce qui est pire pour moi qu'un échec occasionnel.

L'utilisation de l'isolement des instantanés validés en lecture est une bonne possibilité - je vais devoir travailler avec notre équipe de base de données pour obtenir plus de détails à ce sujet. Une partie de notre problème est que nous n'avons pas d'expert SQL Server pour gérer ce genre de choses, et je ne comprends pas assez bien les niveaux d'isolement pour effectuer ce changement en ce moment.


1
Avez-vous envisagé de simplement supprimer NOLOCKces emplois? 601 devrait être le moindre de vos soucis si les résultats de ces requêtes sont censés être exacts . Paul White montre un exemple particulièrement terrible de lecture de données qui ne devrait pas être possible ici .
Aaron Bertrand

3
Vous pouvez définir DEADLOCK_PRIORITYà LOWdes emplois, de sorte que s'il y a des blocages, les emplois échouent, et non les applications. Après cela, vous pouvez rechercher les blocages et découvrir pourquoi ils se produisent, et résoudre ce problème. Cela pourrait être une solution très simple, comme permuter l'ordre de deux instructions. Quel que soit le problème, ce NOLOCKn'est pas la solution , alors arrêtez d'essayer de le forcer juste parce que c'est le plus simple.
Aaron Bertrand

@AaronBertrand Merci, je ne connaissais pas DEADLOCK_PRIORITY - je vais vérifier cela. Nous avons essayé de rechercher les blocages, mais ceux-ci se sont produits à divers moments apparemment aléatoires, et seulement une ou deux fois par jour, et ne sont jamais reproductibles à la demande - nos travaux planifiés exécutent des dizaines de milliers de requêtes toutes les heures, et notre application exécute des centaines de requêtes chaque fois qu'il charge simplement une page ou enregistre quelque chose, et nous n'avons pas trouvé quelle requête de chaque côté est impliquée dans l'impasse. Je n'avais pas l'intention de laisser NOLOCK là pour toujours, c'est pourquoi nous recherchons de meilleures solutions à long terme.
wookie23

1
Vous avez mentionné que vous aviez du mal à retrouver les impasses. Étant donné que vous êtes en 2008 R2, vous pouvez regarder ici: sqlservercentral.com/articles/deadlock/65658 Jonathan Kehayias passe en revue les informations de blocage du tampon en anneau.
Kenneth Fisher

Les réponses et les commentaires abordent bien le problème sous-jacent, mais êtes-vous toujours intéressé à trouver un moyen de reproduire cela comme un exercice intellectuel?
James L

Réponses:


8

Puisqu'un «pansement» potentiel aux problèmes de NOLOCK consiste à cesser d'utiliser NOLOCK et à commencer à utiliser l'isolement READ_COMMITTED_SNAPSHOT, je tiens à vous signaler l'article de blog sur http://www.brentozar.com par Kendra Little: mise en œuvre d'un instantané ou lecture validée Isolement de capture instantanée dans SQL Server: un guide .

Kendra fournit pas mal de détails sur les avantages et les risques liés à l'utilisation du niveau d'isolement READ_COMMITTED_SNAPSHOT.

  1. Ce niveau d'isolement devient le niveau d'isolement par défaut du code de base de données.
  2. Vous devez avoir un seul utilisateur dans la base de données pour effectuer la modification au niveau d'isolement READ_COMMITTED_SNAPSHOT.
  3. Même si vous utilisez l'isolement READ_COMMITTED_SNAPSHOT, vous devrez toujours supprimer les indications NOLOCK car elles remplacent la valeur par défaut.
  4. Certains de vos codes peuvent présenter des problèmes qui doivent être traités.

Il y a quelques années, nous avons implémenté l'isolement READ_COMMITTED_SNAPSHOT sur une base de données qui souffrait gravement de blocage . Mais une fois que nous avons changé le niveau d'isolement, nous avons commencé à avoir des blocages dans quelques zones critiques.

Pourquoi est-ce arrivé? Étant donné que le niveau d'isolement précédent provoquait un blocage important, le code ne pouvait «jamais» atteindre le point de blocage. Cependant, avec l'isolement READ_COMMITTED_SNAPSHOT, les requêtes pourraient continuer à avancer. Cependant, un certain pourcentage des transactions qui n'attendent plus n'ont pas abouti à un blocage.

Heureusement, notre cas a été résolu rapidement en déterminant les points de blocage et en ajustant les index sur quelques tables pour avoir un ordre de colonne plus rationnel. Cela a considérablement réduit nos problèmes de verrouillage.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.