2 mots à propos du recover PITR d'une base Oracle !

La documentation Oracle sans doute le meilleur des livres à propos de la base de données. En plus, il y a un nombre impressionnant de livres, plus de 100, ce qui est intarissable même pour les plus passionnés… Même si vous êtes assidu, le temps que vous les terminiez et la prochaine version n’est pas loin ;-).

Et pourtant, il y a quelques rares coquilles qui traînent. Ce post est à propos de l’une d’entre-elles lorsque vous effectuez un Database Point in Time Recovery (PITR). Suivez-le lien est vous noterez ce qui suit :

  • Cette section illustre un PITR de la base de données en utilisant le fichier de contrôle courant. Voici ce qui est écrit :

The control file is current. If you need to restore a backup control file, then see « Performing Recovery with a Backup Control File ».

  • Oracle vous recommande (point 6) d’ouvrir la base de données en read-only pour valider qu’il n’y a pas de corruption logique :

6. Open the database read-only in SQL*Plus and perform queries as needed to ensure that the effects of the logical corruption have been reversed.

En fait, si vous êtes amené à effectuer un PITR de votre base de données, c’est peut-être justement parce que vos données ont été modifiées et dans ce cas l’ouvrir en lecture pourrait être une bonne idée, si seulement c’était possible :

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> alter database open read only;
alter database open read only
*
ERROR at line 1:
ORA-16005: database requires recovery

Et voila ! La documentation est fausse; vous ne pouvez pas ouvrir la base de données en read-only à partir du fichier de contrôle courant (cf la note #399276.1 pour plus de détails). Ou plutôt vous pouvez, si vous utilisez la commande FLASHBACK… ou si vous contournez le problème !

Alors, comment ouvrir la base de données en READ ONLY ?

Si vous mettez bout à bout le contenu de la note et ce que vous savez de la base de données, vous arriverez sûrement à la solution qui suit ou une solution approchante :

Etape 1 :
Créez un fichier « sauvegarde » du controlfile et montez la base de données sur ce fichier. On supposera que vous avez effectué votre recover de base de données à partir du current controlfile. Dans ce cas, votre instance est montée sur le fichier de contrôle :

  • Connectez-vous avec SQL*Plus,
  • Faites une copie du fichier de contrôle,
  • *Important* Notez la valeur courante du paramètre control_files
  • Changez le fichier spfile pour de manière à pointer sur la sauvegarde du fichier de contrôle
  • Arrêtez et redémarrez l’instance en mode MOUNT
$ sqlplus / as sysdba

SQL*Plus: Release 11.1.0.6.0 - Production on Wed Apr 9 21:01:10 2008

Copyright (c) 1982, 2007, Oracle. All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> alter database
backup controlfile
to '+DGBLUJ/bluj/controlfile/backup.ctl';

Database altered.

SQL> show parameter control_files

NAME TYPE VALUE
------------- ------ -------------------------------------------------
control_files string '+DGBLUJ/bluj/controlfile/current.268.651365597',
'+DGBLUJ/bluj/controlfile/current.265.651365599'

SQL> alter system
set control_files='+DGBLUJ/bluj/controlfile/backup.ctl'
scope=spfile;

System altered.

SQL> startup force mount;
ORACLE instance started.

Total System Global Area 313860096 bytes
Fixed Size 1299624 bytes
Variable Size 268438360 bytes
Database Buffers 37748736 bytes
Redo Buffers 6373376 bytes
Database mounted.

Etape 2 :
Déterminez le premier SCN auquel vous pouvez faire votre recover pour positionnez le SCN du fichier de contrôle. Etant donné que vous avez fait déjà fait le recover des fichiers de données, cette information est dans les entêtes des fichiers de données. Vous pouvez déterminer cette première valeur avec la requête ci-dessous :

SQL> select CHECKPOINT_CHANGE# 
from v$datafile_header;

CHECKPOINT_CHANGE#
------------------
1308788
1308788
1308788
1308788

Toutes les lignes (1 par fichier de données) doivent avoir la même valeur : Celle du SCN que vous aller utiliser…

Etape 3 :
Effectuez le recover du fichier de contrôle ; vous n’avez besoin pour cela que du fichier d’archivelog qui contient le dit SCN. Pour cette opération, utilisez SQL*Plus comme dans l’exemple ci-dessous :

SQL> recover database            -
using backup controlfile -
until change 1308788

ORA-00279: change 1308788 generated at 04/09/2008 18:54:43 needed for thread 1
ORA-00289: suggestion :
/u01/app/oracle/flash_recovery_area/BLUJ/archivelog/2008_04_09/o1_mf_1_8_3ztl9sv
1_.arc
ORA-00280: change 1308788 for thread 1 is in sequence #8

Specify log: {=suggested | filename | AUTO | CANCEL}

Log applied.
Media recovery complete.

Et voila, vous pouvez ouvrir la base de données en lecture comme ci-dessous :

SQL> alter database open read only;

Database altered.

Etape 4 :
Avec le nouveau fichier de contrôle, vous devrez utilisez OPEN RESETLOGS pour ouvrir votre base de données et ceci, même si vous décidez de faire le recover de vos fichiers d’archive et de redo logs jusqu’au bout. Pour éviter ce problème, vous pouvez ré-utiliser le fichier de contrôle courant comme ci-dessous :

SQL> alter system 
set control_files='+DGBLUJ/bluj/controlfile/current.268.651365597',
'+DGBLUJ/bluj/controlfile/current.265.651365599'
scope=spfile;

System altered.

SQL> startup force mount;

Et vous voila revenu à votre point de départ ! On tourne en rond, quoique.