Undo et Redo et Recovery en quelques mots, par Jonathan Lewis

Cet article est la traduction d’un article de Jonathan Lewis publié sur son blog. L’article original en anglais se trouve ici.

Lorsque vous modifiez un bloc de donnée, en modifiant une ligne d’une table par exemple, ou en marquant une entrée d’index comme supprimée, voici ce que fait Oracle:

  1. génération d’information redo sous forme d’un vecteur de modification (change vector pour décrire les modifications qui doivent être faites sur le bloc
  2. génération d’information undo pour décrire l’ancienne version des données qui vont changer.
    Cet undo est en réalité une information redo (un autre change vector) qui décrit comment créer cette information undo
  3. écriture de ces informations dans le buffer de journalisation (redo log buffer)
    Ces 2 change vectors sont regroupés (celui de l’undo est toujours en premier) en un seul enregistrement redo record
  4. la modification sur le bloc d’undo est effectuée
  5. la modification sur le bloc de données (table ou index) est effectuée

Le redo doit être écrit sur disque avant que le bloc de donnée et le bloc d’undo ne le soient. [voir note ci-dessous]
Le bloc d’undo et le bloc de donnée seront écrits sur disque plus tard, et ce même si la transaction n’est pas encore commitée.

Question: Si l’instance se plante avant que la transaction ne soit commitée, comment Oracle va pouvoir récupérer l’ancienne version des données, puisque elle a été écrasée par la nouvelle version non commitée ?

Réponse: Après le plantage, le processus de récupération (instance recovery) connait l’heure du dernier checkpoint de chaque fichier de données (datafile) et va appliquer le redo sur les fichiers de la tablespace d’undo, de la même manière qu’il le fait sur les autres fichiers des tablespaces ‘permanentes’.

A partir de là, la base est à jour, et le processus de recovery voit alors voir les dernières versions aussi bien pour les blocs de données que pour les blocs d’undo.

La tablespace d’undo contient la table des transactions (transaction table) dans le bloc d’entête du segment d’undo (undo segment header) et, comme elle est maintenant à jour, le processus de recovery peur détecter que la transaction n’a pas été commitée. Il peut alors faire un rollback, en utilisant les informations contenues dans les blocs d’undo afin de récupérer les anciennes données de la table.

Notes:

Cette description d’une modification de donnée est un schéma général général. Il y a des cas particuliers qui rendent ce mécanisme un peu plus complexe. Entre autres, il y a un traitement particulier quand le changement est fait juste au début de la transaction: en 10g les quelques premières modifications que fait une transaction vont utiliser un mécanisme spécial – à condition qu’il n’y ait qu’une seule instance (donc pas en RAC). Ce mécanisme est optimisé en utilisant la gestion de l’undo en mémoire (private redo threads et in-memory undo)

Voire aussi le glossaire undo à propos du undo segment header et de la transaction table


Oracle s’assure toujours que lorsque les modifications faites en mémoire (dans le buffer cache) sont écrites sur disque (dans les datafiles), alors le redo associé qui a été écrit en mémoire (dans le log buffer) a auparavant été flushé sur disque, dans les fichiers redo log.
Si besoin DBWR (database writer) va attendre que LGWR (log writer) ait terminé cette écriture.
C’est ce mécanisme (écriture du log en premier – connu comme le protocole Write Ahead Log) qui assure que les journaux (redo logs) ont toujours l’information nécessaire pour défaire (undo) les modifications écrites sur disque.

Laisser un commentaire