web-dev-qa-db-fra.com

Comment empêcher le journal des transactions de se remplir pendant la réorganisation de l'index?

Nous avons plusieurs machines sur lesquelles nous avons pré alloué la taille du journal des transactions à 50 Go. La taille de la table que j'essaye de réorganiser est de 55 à 60 Go mais va augmenter continuellement. La principale raison pour laquelle je souhaite réorganiser est de récupérer de l'espace et tout avantage de performance à cause de cela est un bonus supplémentaire.

Le niveau de fragmentation du tableau est de 30 à 35%. Sur certaines de ces machines, j'obtiens l'erreur "journal des transactions plein" et la réorganisation échoue. La taille du journal des transactions atteint jusqu'à 48 Go. Quelle est la bonne façon de contrer cela? Nous n'avons pas activé l'incrémentation automatique et je suis réticent à le faire.

Je peux augmenter la taille du journal à une valeur plus élevée, mais comme la taille de la table augmente à l'avenir, la valeur peut ne pas être suffisante. De plus, cela va à l'encontre de l'objectif de la réorganisation pour récupérer de l'espace si je veux augmenter la taille du journal de manière égale. Avez-vous des idées sur la façon de lutter efficacement contre cela? L'utilisation du mode groupé n'est pas une option car la perte de données n'est pas acceptable.

19
Sriram Subramanian

REORGANIZE (comme dans ALTER INDEX ... REORGANIZE) est une opération très rapide (enfin, surtout ...), qui nécessite une petite quantité de journal, peut être interrompue à tout moment et reprise plus tard, et fonctionne en interne en petites transactions par lots :

la défragmentation est effectuée comme une série de transactions courtes, donc un journal volumineux n'est pas nécessaire si les sauvegardes de journaux sont effectuées fréquemment ou si le paramètre du modèle de récupération est SIMPLE.

Êtes-vous sûr de ne pas parler d'une reconstruction ? Un index REBUILD est lent, coûteux, consomme une énorme quantité de journal (s'il n'est pas hors ligne et ne peut pas être connecté de manière minimale , la reconstruction en ligne ne peut pas être journalisée de manière minimale), est une transaction géante unique et ne peut pas être interrompue sans perdre tout le travail.

Il me semble que vous faites une reconstruction, ce qui est une opération vraiment exceptionnelle que vous ne devriez pas faire à moins d'avoir une raison extrêmement bien pensée. Pour quel type de récupération d'espace souhaitez-vous? Tout ce que DBCC CLEANTABLE ne gérera pas? Avez-vous vérifié la structure physique de la table, a-t-elle dérivé de la structure logique (voir colonnes de table SQL Server sous le capot pour plus de détails)?

Si vous vraiment devez reconstruire la table, je crains que vous n'ayez pas d'autre choix que de mordre la balle et d'allouer le journal nécessaire. Ne le laissez pas croître automatiquement, cela ne fera que ralentir le processus. Prépare-le à 2,5 fois la taille de la table.

Si la table est partitionnée, vous pouvez reconstruire hors ligne (et réorganiser) une partition à la fois. La reconstruction en ligne ne peut être effectuée qu'au niveau de la table entière.

7
Remus Rusanu

Meilleure pratique est de REORGANIZE en dessous d'environ 30% de fragmentation et REBUILD au-dessus de cela. Simplement, REBUILD fait une copie propre, REORGANIZE le fait in situ.

Vérifiez ce que vous faites réellement: vous n'avez pas de plan de maintenance pour les deux, n'est-ce pas?

Sur des tables plus grandes (une table de 50 Go y arrive), j'ai vu REORGANIZE consommer tout l'espace du journal des transactions si vous suivez cette règle. Pas souvent: un seul système avec un certain schéma de charge. REORGANIZE vient de s'exécuter jusqu'à ce que le journal se développe et consomme tout l'espace disque.

Nous sommes passés à REBUILD à la place sans plus de problèmes, mais nous avons ignoré la fragmentation en dessous de 25%. Cela a mieux fonctionné pour nous: vous devrez voir si cela fonctionne pour vous.

REBUILD peut affecter les performances plus que REORGANIZE en production, mais cela peut parfois être atténué avec l'option ONLINE (édition Enterprise requise).

7
gbn

J'ai déjà eu ce problème.

  • Vous avez une grande base de données et un petit lecteur de journaux. Vous souhaitez vous réorganiser (pour diverses raisons).
  • Lorsque vous essayez cela sur une grande table fragmentée, le journal se remplit jusqu'à ce que le lecteur de journal soit plein, puis la commande s'interrompt.
  • S'il est en mode simple, d'autres transactions peuvent échouer jusqu'à ce que le journal soit effacé au prochain point de contrôle, et s'il est en mode complet, d'autres transactions peuvent échouer jusqu'à la prochaine sauvegarde du journal. Coupure!
  • Si vous êtes en mode complet, vous augmentez la fréquence de sauvegarde de vos journaux, mais cela n'aide pas à éviter le problème car la réorganisation est effectuée dans une transaction implicite, le journal n'est pas effacé jusqu'à ce que cette transaction se termine ou s'interrompe ou soit arrêtée.
  • Et vous voulez vraiment que la réorganisation se termine.

C'est un peu contre-intuitif car vous savez que si vous abandonnez la réorganisation, elle peut continuer là où elle s'était arrêtée, c'est simplement qu'un abandon valide la transaction plutôt que d'annuler.

Voici ce que vous faites. C'est un peu long mais simple.

  • Prépare votre fichier journal à une taille relativement grande, mais pas au maximum. Fondamentalement, vous voulez laisser suffisamment d'espace pour effectuer un travail utile, ainsi que pour certaines petites croissances si elles se produisent, afin que les opérations normales ne s'arrêtent pas.
  • Créez un travail pour exécuter la réorganisation de votre index ("Réorganiser").
  • Créez une alerte WMI d'agent ("Réorganiser la soupape de décharge") sur une condition de performance.

    • Objet: SQLServer: bases de données
    • Compteur: journal de pourcentage utilisé
    • Instance: (votre grand nom de base de données)
    • Alerte si le compteur dépasse: 80
    • Réponse: exécuter le travail ("Réorganiser le contrôle")
  • Créer un emploi ("Réorganiser le chèque")

    • Dans la tâche, vérifiez msdb.dbo.sysjobactivity pour voir si la tâche "Réorganiser" est en cours d'exécution. Et si c'est le cas ...
    • Arrêtez le travail et interrogez jusqu'à ce qu'il s'arrête. Cela peut prendre quelques secondes.
    • (Si vous êtes en mode complet) Déclenchez votre travail de sauvegarde du journal et confirmez quand il se termine.
    • Vérifiez à nouveau les sys.dm_os_performance_counters que votre compteur d'espace libre de journal a réduit en dessous de votre seuil.
    • Démarrez le travail de "réorganisation".
  • Testez tout cela quelque part, même un bac à sable de développement, pour vous assurer qu'il fonctionne correctement avant de le coller sur votre serveur de production.

Ce que vous verrez, c'est que le travail de "réorganisation" commence et commence à remplir le journal. Lorsque le journal atteint un pourcentage plein, il déclenche l'alerte WMI (dans les 30 secondes environ) qui exécute votre autre travail qui voit que le travail "Réorganiser" est en cours d'exécution et donc probablement en faute. Il arrête ensuite "Réorganiser", effectue une sauvegarde, confirme que l'espace libre du journal est de retour à une valeur raisonnable, puis redémarre votre travail "Réorganiser" qui reprendra là où il s'était arrêté.

Donc, comme vous le pouvez, la raison pour laquelle vous avez prédéfini votre journal à un chiffre raisonnable dans ce scénario est de réduire le nombre de croissance/déclencheur/travail/arrêt/redémarrage, afin qu'il puisse être plus efficace et également conserver suffisamment d'espace pour la croissances occasionnelles qui ne sont pas prises à temps.

C'est une sorte de scénario étrange. Je suis presque sûr que j'aurais reculé devant cela il y a quelques années et, évidemment, il y a ici des problèmes fondamentaux sous-jacents. Mais si vous traitez des centaines de serveurs, quelques cas Edge comme celui-ci surgiront qui ne peuvent être traités en aucune façon, pour quelque raison que ce soit, sauf par MacGyvering, une solution temporaire qui fait le travail.

Tant qu'il est sûr, logique, testé et bien documenté, il ne devrait y avoir aucun problème.

6
Cody Konior

C'est ce que je faisais d'habitude (j'ai aussi quelques tables de 80 + Go de large chacune) pour la réorganisation d'index (car la réorganisation d'index peut être arrêtée à tout moment sans perdre le travail de réorganisation précédent).

  1. Pendant la réorganisation de l'index, j'augmenterai la sauvegarde du journal de mes fréquences habituelles de 30 minutes à toutes les 10 minutes
  2. J'ai une autre session faisant la vérification de l'espace libre de tlog toutes les 1 min, et si l'espace libre de tlog est inférieur à un seuil, j'arrêterai la session de réorganisation d'index et démarrer (ou attendre) la sauvegarde de tlog. Redémarrez ensuite la réorganisation de l'index.

Dans mon cadre de maintenance d'index, je classe les index en deux groupes, l'un pour la reconstruction d'index et l'autre pour la réorganisation d'index. Pour la reconstruction d'index, j'utiliserai une approche quelque peu différente car je ne veux pas arrêter une session de reconstruction d'index (ce qui entraînera une restauration et perdra tout le travail précédent). Pendant la reconstruction de l'index, si ma session de surveillance remarque un scénario d'utilisation d'espace libre du fichier tlog, la session de surveillance pré-augmentera automatiquement le fichier tlog, et dans le pire des cas (c'est-à-dire que le disque est plein), ma session de surveillance créera un autre fichier journal ( mais plus tard, je le déposerai) sur un autre lecteur (le lecteur de sauvegarde)

1
jyao

J'ai eu le même problème que l'auteur de la question, et en regardant ses commentaires, je peux dire que j'avais la même configuration. Pendant que j'essayais de faire un REORGANIZE, le journal grandit, quelle que soit sa taille, voire plusieurs fois la taille de la table entière.

Le problème était dû à réplication transactionnelle. Apparemment, le journal ne peut pas être sauvegardé tant que l'opération REORGANIZE n'est pas terminée. J'ai lu quelque part que c'était un problème connu de Microsoft, mais je ne sais pas où.

Une fois que j'ai désactivé la réplication transactionnelle, les sauvegardes de journaux ont à nouveau fonctionné normalement, et les sauvegardes de journaux toutes les 30 secondes lors de la réorganisation ont bien fonctionné pour moi.

1
IUmpierrez

Je suppose que vous exécutez quelque chose dans le sens de:

ALTER INDEX SUR LA RÉORGANISATION

Malheureusement, il n'y a aucun moyen d'exécuter une organisation partielle (la façon dont vous pouvez réduire partiellement un fichier journal par exemple). Les façons dont je peux penser autour de ces problèmes sont:

1) définissez la base de données en mode de récupération simple pendant que vous exécutez la réorganisation, mais vous avez dit que ce n'était pas acceptable

2) partitionner l'index - si vous pouvez penser à un moyen de partitionner l'index pour obtenir des partitions de taille approximativement égale, vous pourrez alors réorganiser (ou reconstruire avec l'option en ligne) chaque partition indépendamment et limiter ainsi la croissance du fichier journal

Je suis sûr que vous faites cela, mais si vous ne l'êtes pas, vous voudrez peut-être lancer une sauvegarde du fichier journal avant et après avoir effectué des optimisations d'index, ce qui lui permettra de récupérer l'espace utilisé.

0
voutmaster