12c: possibilité de ne plus générer de redo sur les GTT

Sur une Global Temporary Table, il n’est pas nécessaire de générer du redo car les données ne sont pas persistantes. Les données (table et index) sont dans un tablespace temporaire sur lequel il n’y a pas de recovery.
Par contre le undo est nécessaire, pas pour des raisons de consistent reads (puisque les données ne sont pas partagées avec d’autres sessions), mais simplement parce qu’on peut faire un rollback dans notre session.

Et malheureusement cet undo est généré dans le tablespace UNDO qui est permanent, donc protégé par du redo.

En 12c, c’est toujours le comportement par défaut, mais on a la possibilité de faire en sorte que le UNDO généré par des opérations sur des GTT soit écrit dans le tablespace temporaire Et donc de ne plus générer de redo du tout (Sauf un minimum, pour les modifications du dictionnaire par exemple).

Il suffit de positionner le paramètre suivant:

alter session set temp_undo_enabled =true;

Cette fonctionnalité a été introduite pour pouvoir utiliser les GTT dans une standby Active DataGuard (où les datafiles sont ouverts en read-only seulement). Le paramètre est par défaut à FALSE sur une base primaire.

J’ai repris une demo complète qui mesure le redo généré par chaque opération sur une table permanentes et sur une table temporaire. Si on laisse temp_undo_enabled à sa valeur par défaut, il n’y a pas de différence entre le redo généré en 11g et en 12c sur toutes les opérations de cette demo.

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 ?
Lire la suite