Histoire de journal : Les différentes phases d’exécution d’une session de récupération avec SQL Server

Vous vous levez, vous commencez le travail par une belle journée et tout va bien. Cependant une coupure électrique provoque l’extinction brusque d’un de vos serveurs de bases de données (et l’onduleur il ne fonctionne pas ??? !!). Votre serveur SQL redémarre et tout rentre dans l’ordre, les bases de données sont à nouveau en ligne et les pertes de données sont minimes . ouf !!! Cependant ne vous êtes vous jamais demandé comment SQL Server pouvait revenir à un état stable après une coupure aussi brusque ? C’est ce que nous allons voir dans ce billet.


Tout d’abord il est important de commencer par le journal des transactions qui est l’élément centrale d’une reprise des données après un crash du serveur SQL. (Entendez ici par crash un arrêt volontaire ou non du serveur SQL). SQL Server se sert du journal de chaque bases de données pendant une session de récupération. Pour comprendre les différentes étapes exécutées lors du redémarrage du serveur SQL, il faut d’abord comprendre les différents mécanismes de journalisation d’une base de données.

A chaque fois qu’un changement est opéré sur les données d’une table un enregistrement est d’abord effectué dans le journal des transactions. L’écriture physique de ces changements est en réalité asynchrone (du moins en partie). En effet, lorsqu’une transaction est initiée l’enregistrement des changements du journal s’effectue d’abord dans un cache. Le contenu de ce cache est ensuite écrit sur disque lorsqu’une transaction est validée (ou annulée). A ce moment précis le thread utilisateur est obligé d’attendre l’acquittement de l’écriture de validation (COMMIT) sur disque pour s’assurer qu’aucun problème n’a eu lieu et qui garantit qu’une transaction soit inscrite de manière permanente sur disque.

L’écriture des pages de données sur disque est, quant à elle, purement asynchrone et s’effectue toujours après celle des données du journal. Les pages de données sont d’abord modifiées en mémoire (dans un cache) et un CHECKPOINT permet ensuite d’écrire à intervalle régulier les pages données modifiées (dirty pages) de ce cache sur disque. Ce processus n’a nullement besoin d’être synchrone parce qu’il est possible de rejouer les enregistrements du journal sur les pages de données pour arriver à un état cohérent. Il est important savoir également qu’un CHECKPOINT écrit les enregistrements présents dans le cache des données du journal sur disque, ce qui signifie que si une transaction n’est pas validée (ou ouverte) au moment du CHECKPOINT alors les pages de données non validées (dirty pages) et les enregistrements du journal correspondants qui sont présents en cache seront inscrites dans leurs fichier de bases de données respectifs. SQL Server sait qu’une transaction n’est pas validée car elle ne possède pas d’enregistrement de ROLLBACK ou de COMMIT dans le journal des transactions.

Architecture physique du processus de journalisation

buffer

 

Ce mode de fonctionnement décrit ci-dessus est en fait celui du protocole WAL (Write-Ahead Logging) utilisé par SQL Server pour être en accord avec les propriétés ACID d’une transaction. Cet ensemble de propriétés, pour rappel, garantit que les transactions d’une base de données soient traités de manière fiable.

Ce mode de fonctionne implique la gestion de deux scénarios distincts :

1- serveur SQL est arrêté avant qu’une transaction soit validée. Dans ce cas si un CHECKPOINT est effectué avant l’arrêt du serveur SQL les données modifiées et les enregistrements dans le journal sont enregistrés sur disque. Au redémarrage SQL Server doit annuler les changements associés à des transactions incomplètes (pour lesquelles il n’existe aucun enregistrement COMMIT ou ROLLBACK dans le journal).

log_redo_undo

2- Le serveur SQL est arrêté après qu’une transaction soit validée mais avant que les pages de données modifiées soient elles mêmes inscrites sur disque. (Rappel : la validation ou l’annulation d’une transaction force l’écriture des données du cache du journal sur disque). Dans ce cas il existe une déphasage entre les données du journal et les pages de données.

log_redo_undo_2

 

Les phases d’une session de récupération (au redémarrage de SQL Server)

Nous y sommes .. au redémarrage du serveur une session de restauration comprend les phases suivantes dans l’ordre :

1- Phase d’analyse : Une analyse est effectuée à partir du dernier enregistrement CHECKPOINT dans le journal pour la simple et bonne raison qu’avant un CHECKPOINT les pages de données sont déjà écrites sur disque. Il n’est donc pas nécessaire de revenir avant ce point de référence. De plus durant cette analyse 2 tables virtuelles sont créées : Une table DTP (Dirty Table Page) et une table des transactions non validées au moment de l’arrêt du serveur SQL.

2- Phase REDO : Cette phase permet de restaurer par progression les données qui n’auraient pas été écrites sur disque. Pour cela le point de référence est le minLSN enregistrée dans la table virtuelle DPT. Ce minLSN correspond à la 1ère page pour laquelle il est nécessaire de rejouer les enregistrements du journal des transactions par progression. Cependant SQL Server est obligé de revenir jusqu’à plus ancienne transaction encore ouverte pour pouvoir réacquérir les verrous nécessaires sur les objets concernés. A ce stade il peut exister des transactions encore ouvertes pouvant laisser la base de données dans un état inconsistant. C’est la raison pour laquelle qu’une phase supplémentaire existe.

3- Phase UNDO : Cette phase permet d’annuler les transactions encore ouvertes et référencées dans la table virtuelle créée durant la phase d’analyse en rejouant à l’envers les données du journal.

log_redo_undo_3

 

David BARBARIN (Mikedavem)
Elève ingénieur CNAM

Laisser un commentaire