Tout au long de ma carrière en tant que professionnel des données, à la fois au sein de Microsoft et en tant que consultant, j'ai découvert que l'une des parties les plus mal comprises d'une base de données SQL Server est le journal des transactions. Le manque de connaissances sur le fonctionnement et la gestion du journal des transactions, ou simplement de simples idées fausses, peut entraîner toutes sortes de problèmes de production, notamment :
- Le journal des transactions devient incontrôlable et risque de manquer d'espace
- Problèmes de performances liés à la réduction répétée du journal des transactions
- Problèmes de performances liés à un problème connu sous le nom de fragmentation VLF , dont j'ai parlé dans cet article
- L'impossibilité de récupérer à un moment donné à l'aide des sauvegardes du journal des transactions
- L'impossibilité d'effectuer une sauvegarde de la fin du journal pendant la reprise après sinistre (voir ici pour une explication des sauvegardes de la fin du journal)
- Divers problèmes liés aux basculements et aux performances de restauration
Avec cet article, je commence une série occasionnelle sur le journal des transactions et comment il fonctionne et doit être géré, et j'aborderai tous les problèmes ci-dessus au cours de son parcours. Dans cet article, j'expliquerai ce qu'est la journalisation et pourquoi elle est nécessaire.
Terminologie de base autour de la journalisation
Quand je parle de n'importe quel mécanisme dans SQL Server, je trouve qu'il y a un problème de poule et d'œuf où je dois utiliser un mot ou une phrase avant de l'avoir expliqué. Pour éviter ce problème dans cette série, je vais commencer par expliquer certains termes qui doivent être utilisés lors de la discussion sur la journalisation, et je développerai bon nombre de ces termes au fur et à mesure que la série progresse.
Transaction, validation et restauration
Une transaction englobe une modification ou un ensemble de modifications apportées à une base de données. Il a un début défini et une fin définie. Le début se produit lorsqu'une instruction BEGIN TRANSACTION est utilisée ou que SQL Server démarre automatiquement une transaction pour vous. La fin peut être l'une des quatre choses suivantes :
- La transaction est validée lorsqu'une instruction COMMIT TRANSACTION est exécutée
- La transaction est validée lorsque SQL Server valide automatiquement la transaction dans le cas d'une transaction de validation automatique
- La transaction se termine après l'exécution d'une instruction ROLLBACK TRANSACTION
- La transaction se termine après qu'un problème se soit produit et SQL Server a automatiquement annulé la transaction
Lorsqu'une transaction est validée, les modifications apportées par la transaction sont finalisées dans la base de données et sont durables dans le journal des transactions SQL Server sur disque. Notez que j'ai dit "dans le journal des transactions". Les modifications réelles apportées aux pages du fichier de données en mémoire ne sont *pas* écrites sur le disque lorsque la transaction est validée. Il n'est pas nécessaire de les rendre durables dans les fichiers de données, car les modifications sont déjà durables dans le journal des transactions. Finalement, les pages du fichier de données seront écrites sur le disque par une opération de point de contrôle.
Inversement, lorsqu'une transaction est annulée, les modifications de données effectuées par la transaction ne sont plus présentes dans la base de données. Il y aura toujours des modifications physiques dans la base de données, car l'annulation d'une transaction signifie effectuer davantage de modifications, mais vous pouvez considérer qu'une transaction annulée n'a pas affecté les données de la base de données.
Les points de contrôle et les opérations de restauration sont des sujets dignes de leurs propres publications, je les expliquerai donc plus tard dans la série.
J'aborde ces trois termes beaucoup plus en profondeur dans le tutoriel Introduction aux transactions SQL Server sur le blog SentryOne.
Journalisation, enregistrements de journaux et journal des transactions SQL Server
La journalisation signifie simplement créer une description durable d'une modification apportée à une base de données, presque toujours dans le contexte d'une transaction. Lorsqu'une modification est apportée, la modification est décrite dans un enregistrement de journal. Un enregistrement de journal contient généralement suffisamment d'informations pour permettre la relecture de la modification dans la base de données ou son annulation dans la base de données si nécessaire.
Cet enregistrement de journal sera initialement en mémoire et peut être écrit sur le disque avant la validation de la transaction, mais doit absolument être écrit sur le disque avant la transaction peut terminer la validation, sinon la transaction ne serait pas durable. Une exception à cette règle est lorsque la durabilité retardée est activée, dont Aaron Bertrand parle dans cet article.
Les enregistrements de journal sont stockés dans le journal des transactions (un ou plusieurs fichiers journaux sur disque), qui a une architecture interne quelque peu complexe, et j'en parlerai et bien plus sur les enregistrements de journal dans le prochain article de la série.
Reprise sur incident
Un plantage se produit lorsque SQL Server s'est arrêté de manière inattendue et que les différentes bases de données modifiées n'ont pas pu être fermées correctement (en s'assurant que toutes les pages de fichiers de données modifiées sont écrites sur le disque et que la base de données est marquée comme arrêtée proprement).
Lorsque SQL Server démarre, il vérifie toutes les bases de données pour voir si certaines n'ont pas été marquées comme arrêtées proprement. S'il en trouve un, cette base de données doit passer par une récupération sur incident. Cela garantit ce qui suit :
- Pour toute transaction qui a été validée avant le plantage, assurez-vous que toutes les modifications apportées à la transaction sont reflétées dans la base de données (c'est-à-dire, relisez la transaction)
- Pour toute transaction qui n'a pas été validée avant le plantage, assurez-vous qu'aucune des modifications apportées à la transaction n'est reflétée dans la base de données (c'est-à-dire, annulez la transaction)
En d'autres termes, la récupération sur incident rend une base de données cohérente sur le plan transactionnel au moment où l'accident s'est produit. La récupération après crash est utilisée :
- Lorsque SQL Server démarre et trouve une base de données qui doit être récupérée
- Lors d'un basculement vers une copie secondaire d'une base de données
- À la fin d'une séquence de restauration impliquant des sauvegardes (voir ici)
La récupération après un crash est un processus complexe et nécessite quelques articles supplémentaires dans la série avant que je puisse l'expliquer en profondeur.
Pourquoi la journalisation est-elle nécessaire ?
La raison la plus fondamentale de la journalisation est de permettre à la base de données SQL Server de rendre les transactions durables, afin qu'elles puissent être récupérées lors de la récupération après incident ou annulées si nécessaire pendant les opérations normales de la base de données. S'il n'y avait pas de journalisation, une base de données serait transactionnellement incohérente et éventuellement structurellement corrompue après un crash.
Sans la journalisation, une foule d'autres fonctionnalités de SQL Server ne seraient pas possibles, notamment :
- Sauvegardes de données pouvant être restaurées de manière cohérente
- Sauvegardes du journal des transactions SQL Server pouvant être utilisées lors d'une opération de restauration et pour mettre en œuvre l'envoi de journaux
- La réplication, qui repose sur la possibilité de récolter des transactions à partir du journal des transactions
- Change Data Capture, qui utilise l'agent de lecture du journal de réplication transactionnelle pour collecter les modifications à partir du journal des transactions
- Mise en miroir de bases de données et groupes de disponibilité, qui reposent sur l'envoi d'enregistrements de journaux vers des copies secondaires de la base de données pour relecture
SQL Server (et tous les serveurs de bases de données similaires) utilise ce qu'on appelle la journalisation en écriture anticipée . Cela signifie que les descriptions des modifications doivent être écrites sur le disque avant les modifications elles-mêmes afin de garantir la possibilité de restaurer correctement une base de données en cas de panne. Si une modification était écrite dans un fichier de données avant que les enregistrements du journal ne la décrivent et que SQL Server se bloque, il n'y aurait aucun moyen de savoir quoi annuler et la base de données serait incohérente. Cet ordre est un invariant, quel que soit le niveau d'isolement, le type de transaction ou si la fonctionnalité de durabilité différée est utilisée. Enregistrez d'abord les enregistrements, puis les pages de données.
Juste la pointe de l'iceberg
Comme vous pouvez le voir dans cet article d'introduction, une quantité énorme va dans le journal des transactions et se connecte à une base de données SQL Server, et tout ce que j'ai fait jusqu'à présent est de définir une terminologie de haut niveau et d'expliquer pourquoi la journalisation est nécessaire. J'espère que vous vous joindrez à moi alors que je me diversifie et que j'approfondis au fur et à mesure que la série progresse !