Une opération «ALTER INDEX ALL REBUILD» sur SQL Server 2012 a échoué car le journal des transactions manquait d'espace. Les index n'ont jamais été réorganisés ou reconstruits, la fragmentation est donc supérieure à 80% sur presque tous.
La base de données utilise un modèle de récupération simple. J'ai supposé qu'après chaque opération d'indexation effectuée par le formulaire "ALL" de la commande, les données du journal des transactions seraient vidées avant la prochaine reconstruction d'index. Est-ce ainsi que cela fonctionne réellement, ou les reconstructions d'index sont-elles enregistrées comme si elles faisaient partie d'une seule transaction?
En d'autres termes, pourrais-je réduire la croissance du journal des transactions en écrivant un script pour effectuer chaque reconstruction individuellement? Y a-t-il d'autres facteurs à considérer?
la source
Réponses:
1) Purge du journal: le modèle de récupération SIMPLE n'efface pas le journal après chaque transaction, mais aux points de contrôle. ( lien pour plus d'informations)
2a) RECONSTRUIRE TOUT: oui, RECONSTRUIRE TOUT fonctionne comme une transaction unique. Les reconstructions d'index à l'intérieur ont leurs propres transactions, mais l'opération globale n'est pas entièrement validée jusqu'à la fin. Alors oui, vous pouvez limiter la croissance des fichiers journaux en reconstruisant des index individuels (et éventuellement en émettant des commandes CHECKPOINT).
2b) La preuve! Ici, ayez un script de démonstration. (Construit en 2016 dev) Tout d'abord, configurez une base de données de test, avec table et index:
Vous pouvez maintenant comparer l'activité du journal entre RECONSTRUIRE TOUT et reconstruire individuellement
Notez que la première transaction ouverte (ID de transaction 0000: 000002fa pour moi) n'est pas validée jusqu'à la fin de la RECONSTRUCTION TOUT, mais pour les reconstructions index par index, elles sont validées successivement.
la source
En l'état, il s'agit d'une transaction unique.
la source
La question est triviale pour une reconstruction hors ligne . Bien sûr, il s'agit d'une seule transaction. Imaginez les ravages qui s'ensuivraient si l'opération divisait chaque index en sa propre transaction, car elle devrait libérer les verrous lors de la validation , puis les réacquérir. Alors que le verrou critique de table SCH-M a été libéré, les index peuvent être supprimés et de nouveaux index peuvent être créés, comment l'instruction traiterait-elle de tels cas? Sans oublier que la table peut être supprimée, voire recréée entre les deux transactions! Y compris le cas où la table est supprimée et une table différente est créée avec le même identifiant d'objet (oui, cela peut arriver) ...
Que faire si vous augmentez la question pour dire ce qui se passe si la reconstruction d'index est une reconstruction en ligne ? S'agit-il d'une seule transaction ou de plusieurs? La réponse est complexe, car plusieurs transactions internes sont en fait impliquées . Cependant, le point clé est qu'il existe une transaction d'archivage globale qui couvre toute l'opération (l'instruction ALTER) et cela épingle le journal en place (ne peut pas être tronqué), donc l'opération doit être planifiée en conséquence pour permettre ~ 1,6x de données taille pour le mode de récupération FULL, ou taille de données 0,2x pour le mode BULK_LOGGED / SIMPLE. Voir le papier lié pour plus de détails.
Vous pouvez dire que la génération hors ligne n'utilise pas les mêmes transactions internes que le mode en ligne et divise l'opération? Les problèmes que j'ai mentionnés à propos de la table étant modifiée / supprimée entre les opérations d'index individuelles (c'est-à-dire la `` stabilité du schéma '' de la table) nécessiteraient toujours une transaction englobante qui contient un SCH-S sur la table pendant toute la durée de l'instruction. Étant donné que cette transaction doit également contenir le SCH-S pendant la récupération, elle doit être enregistrée et, en tant que tel, un enregistrement de journal BEGIN XACT épinglera le journal et empêchera la troncature pendant toute la durée de l'instruction. Je sais que ce problème particulier a été résolu dans le délai SQL 2016-2017 (en raison de problèmes de taille de journal SQL Azure),
mais je ne suis pas sûr de la progression. On dirait que c'est en aperçu maintenant:La reconstruction d'index en ligne pouvant être reprise est en avant-première publique pour SQL Server 2017 CTP 2.0 .la source
Oui, j'ai eu ce même problème avec une très grande table. Chaque fois que j'émettais ALTER INDEX ALL, le journal des transactions augmentait beaucoup, mais s'il était émis ALTER INDEX individuellement, l'utilisation de l'espace du journal serait plus petite.
la source
La réponse précédente de Remus selon laquelle l'indexation en ligne nécessite 1,6 fois la taille de l'index en mode de récupération COMPLÈTE n'est pas correcte. La proportion d'espace de journalisation des transactions requise pour reconstruire un index en ligne sous FULL peut être beaucoup plus élevée et nous avons observé plusieurs fois la taille de l'index, en particulier lorsque l'index en cours de reconstruction est compressé car la journalisation des transactions n'est pas compressée. Cela seul devrait indiquer clairement que la journalisation des transactions lors d'une reconstruction en ligne sous FULL peut être au moins quelques fois la taille de l'index. Ajouter un surcoût d'enregistrement de journal qui n'est pas entièrement documenté par Microsoft mais est souvent estimé à 60 octets par ligne et la taille proportionnelle de la journalisation pendant une reconstruction d'index en ligne sous récupération complète peut être plusieurs fois la taille de l'index en cours de reconstruction, surtout si l'index est compressé
la source
Rdfozz est correct, c'est la meilleure façon de décider si votre plus grand index peut être reconstruit en fonction du stockage actuel. Exécutez simplement
dm_exec_requests
pendant que l'opération se produit (ou SQL Profiler) pour voir si tous les index sont en cours de reconstruction. J'envisagerais également de remplacer le modèle de récupération par un enregistrement en masse. C'est ce que je fais et il y a encore des sauvegardes du journal des transactions pendant la fenêtre. Voir l'article ci-dessous https://technet.microsoft.com/en-us/library/ms191484(v=sql.105).aspxla source