Définitions Undo, Rollback Segment et Table de transactions , par Jonathan Lewis

Cet article une traduction du glossaire de Jonathan Lewis publié sur son blog. L’article original en anglais se trouve ici.

  • Bloc d’entête de segment (‘Segment Header Block’ ou simplement ‘Segment Header’)
  • L’entête des segments undo (‘Undo Segment Header’)
  • Table des transactions (‘Transaction Table’)
  • Undo
  • Rollback


Bloc d’entête de segment (Segment Header Block ou simplement Segment Header):

Historiquement, c’est le premier bloc du premier extent d’un segment, celui qui maintient les information critiques sur la taille du segment, le nombre et l’emplacement des extents, et des informations de contrôle à propos de l’espace libre du segment.
Dans les versions récentes d’Oracle, il peut y avoir quelques blocs juste avant ce bloc d’entête, utilisés pour la gestion de l’espace libre. Cette variante vient de l’implémentation des tablespaces ASSM (Automatic Segment Space Management – gestion automatique de l’espace libre des segments)

La vue DBA_EXTENTS vous donne le fichier et le numéro de block (file_id et block_id) du premier extent, et la vue DBA_SEGMENTS vous donne la position du block d’entête segment header dans cet extent.

Les segments d’undo ont une particularité: le bloc d’entête de segment contient des informations supplémentaires (la table des transactions – transaction table) qui sont spécifiques au mécanisme d’undo d’Oracle.

L’entête des segments undo (Undo Segment Header):

C’est un cas particulier du bloc segment header. La différence principale, c’est qu’il contient la table des transactions (transaction table). C’est une liste, de taille fixe, des transactions les plus récentes, portant l’information concernant leur statut, leurs SCN, et des pointeurs vers les enregistrements d’undo (undo records) associés à la transaction.
Le undo segment header, dans le cas de la gestion automatique des undo, contient aussi une Retention Map qui note le commit SCN de chaque extent, et permet à Oracle de savoir quand un extent a dépassé la période de rétention undo_retention.

Table des transactions (Transaction Table):

Chaque bloc d’undo segment header a une place pour la table des transactions. Lorsque une transaction débute, elle choisit le segment d’undo qu’elle va utiliser, puis prends la plus ancienne entrée (transaction header ‘slot’) dans cette table des transactions.

Cette entrée (ce ‘slot‘) sera l’identifiant de la transaction, et cette information sera visible de deux manières:

  1. Comme identifiant de transaction dans V$TRANSACTION
  2. Comme verrou de type TX (transaction) et mode 6 (exclusif) dans V$LOCK, posé par la session qui execute la transaction

Dans les deux cas, la transaction est identifiée par les triplet:

  • undo segment number: le numéro du segment d’undo qui contient la table des transactions. C’est la colonne XIDUSN de V$TRANSACTION
  • slot number:le numéro d’entrée dans cette table. C’est la colonne XIDSLOT de V$TRANSACTION
  • sequence number: le nombre d’entrées dans la table étant limitée, chaque fois qu’une entrée est réutilisée, ce numéro de sequence est incrémenté. C’est la colonne XIDSQN de V$TRANSACTION

Au début de la transaction, le ‘start SCN’ est écrit dans cette table. Lorsque la transaction est commitée, il est remplacé par le ‘commit SCN’ [voir la définition du SCN ici]

Donc une entrée de la table des transaction, c’est à dire un ‘transaction table slot‘ représente une seule transaction. Dans V$TRANSACTION, l’identifiant est sur trois colonnes XIDUSN, XIDSLOT et XIDSQN. Sur les versions les plus récentes d’Oracle, l’identifiant est aussi repris en une seule colonne XID de type RAW(8).
Dans V$LOCK un verrou a deux colonnes pour son identification (ID1 et ID2). Les verrous de type TX ont les informations USN (décalé de 2 octets à gauche) et SLOT dans ID1 et SQN dans ID2

Undo: (aussi appelé information de rollback):

C’est l’information qui décrit comment revenir en arrière sur les modifications d’un block (‘db block change’). L’undo est stocké dans les segments d’undo, qui sont créés dans les tablespaces d’undo, et chacun de ces segments possède son ‘catalogue’ (la table des transactions) qui pointe versà l’endroit où la transaction a écrit son premier enregistrement d’undo.

Dans les versions plus anciennes, le DBA devait décider combien de segments undo (appelés rollback segments à l’époque) il devait créer et où les mettre. Dans les versions récentes, le DBA doit seulement créer une tablespace d’undo par instance (une seule tablespace undo étant active) et laisser Oracle décider dynamiquement de combien de segments d’undo il a besoin. A l’exception de quelques cas particuliers, chaque modification d’un bloc est précédée par la création d’un enregistrement d’undo.

On entend souvent dire que c’est l’image complète du bloc qui est copiée dans les enregistrements d’undo. C’est faux, et cette idée vient probablement d’un ancien comportement d’Oracle, en version 5.0, qui utilisait une ‘image avant’ pour garder une copie du bloc. En fait, une enregistrement d’undo contient normalement un taille fixe de 80 octets, plus l’information minimale qui permet de faire revenir un bloc à son état avant la modification.

A partir de la 10.2, le mécanisme d’undo a changé, avec l’introduction des ‘private redo threads‘ et de l’undo en mémoire (‘in-memory undo‘). On peut dire que celà n’a modifié que le moment où ces enregistrements d’undo sont écrits dans les blocs d’undo. Si on regarde les blocs d’undo après que la transaction ait été comittée, il n’est pas possible de savoir si la transaction a utilisé les ‘in-memory undo’ ou le mécanisme classique.

Rollback:

Ce terme est utilisé comme synonyme d’undo, mais c’est aussi la commande qui indique à Oracle que les modifications qui ont été effectuées par la transaction active courante doivent être défaites. Lorsque vous faites un rollback, votre session va remonter toute la chaine des enregistrements d’undo qu’elle a généré, et se servir de chacun pour faire un retour arrière sur la modification précédente. Elle va aussi flagger l’enregistrement undo comme ‘appliqué par l’utilisateur’.
Chaque modification effectuée durant ce retour arrière va à son tour générer du redo, ce qui veut dire que le rollback peut être aussi couteux que la modification initiale. Il faut donc éviter d’écrire du code qui va écrire des données temporairement avec l’intention de les rollbacker à la fin.

Enfin, la dernière étape du rollback est un commit, qui va appeler le log writer pour synchroniser les fichiers redo à partir du log buffer.

Laisser un commentaire