Erreurs RMAN et ORA lors du clonage d'une base de données

Le clonage des bases de données Oracle est un processus communément utilisé pour rafraichir des bases de préproduction à partir d’une base de production, ou pour initialiser une base de secours dans le cadre d’une mise en œuvre de réplication dataguard ou goldengate.

Cette technique de clonage s’appuie bien souvent sur la commande RMAN DUPLICATE et s’utilise avec tant de facilité que l’on finit avec le temps par en oublier les rudiments.
Vous souvenez vous par exemple du rôle du process CKPT (checkpoint) , qui pour garantir à chaque instant l’intégrité des données de la base, va inscrire le dernier numéro de transaction (SCN ou System Change Number) dans les control files ainsi que dans l’entête de chacun des « datafiles » constituant la base ?
Pour vous remémorer le rôle de ce process ainsi que les mécanismes internes utilisés lors des opérations de sauvegarde et restauration, je vous relate dans cet article un incident que j’ai rencontré sur un clonage de base qui semblait au départ tout à fait commun, sauf qu’il s’agissait d’un clone d’une base précédemment clonée et dont la base source contenait des tablespaces en lecture seule.
La première opération de clonage (RMAN DUPLICATE) comme on a tous l’habitude de le constater, se déroule sans embuches.
Si l’on regarde attentivement la log du DUPLICATE, on remarque tout de même que RMAN a détecté la présence de tablespaces en lecture seule et semble avoir effectué un traitement particulier sur ces derniers.

contents of Memory Script:
{
   Alter clone database open resetlogs;
}
executing Memory Script
database opened
contents of Memory Script:
{
   catalog clone datafilecopy  "/u02/oradata/orclA/example01.dbf";
   switch clone datafile  5 to datafilecopy
 "/u02/oradata/orclA/example01.dbf";
   #online the readonly tablespace
   sql clone "alter tablespace  EXAMPLE online";
}
executing Memory Script
cataloged datafile copy
datafile copy file name=/u02/oradata/orclA/example01.dbf RECID=4 STAMP=877780712
datafile 5 switched to datafile copy
input datafile copy RECID=4 STAMP=877780712 file name=/u02/oradata/orclA/example01.dbf
sql statement: alter tablespace  EXAMPLE online
Finished Duplicate Db at 23-APR-15

Passons maintenant à la seconde opération de clonage (clonage de la base clonée et contenant un ou plusieurs tablespaces en lecture seule).
En fonction des options choisies dans l’ordre RMAN DUPLICATE, cette fois le clonage tombe en erreur.
Dans le cas d’un clone classique ( RMAN DUPLICATE TARGET DATABASE), l’opération se plante avec le message suivant :

RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of Duplicate Db command at 04/23/2015 13:54:56
RMAN-05501: aborting duplication of target database
RMAN-03015: error occurred in stored script Memory Script
RMAN-06094: datafile 5 must be restored
  Ou
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of Duplicate Db command at 04/23/2015 14:32:08
RMAN-05501: aborting duplication of target database
RMAN-03015: error occurred in stored script Memory Script
RMAN-06136: ORACLE error from auxiliary database: ORA-01152: file 5 was not restored from a sufficiently old backup
ORA-01110: data file 5: '/u02/oradata/orclB/example01.dbf'

Dans le cas d’une opération d’initialisation de base de secours (RMAN DUPLICATE TARGET DATABASE FOR STANDBY), le process RMAN se plante également mais cette fois-ci avec un message du type :

RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of Duplicate Db command at 04/23/2015 14:13:58
RMAN-05501: aborting duplication of target database
RMAN-03015: error occurred in stored script Memory Script
RMAN-06136: ORACLE error from auxiliary database: ORA-19698: /u02/oradata/orclB/example01.dbf is from different database: id=1379753442, db_name=ORCL

Face à cette situation bloquante puisque le DUPLICATE tombe systématiquement en erreur, je me pose deux questions :
1) pourquoi le premier DUPLICATE est passé correctement ?
2) que faire pour aller jusqu’au bout du second DUPLICATE ?
Pour tenter de répondre à ces questions , il faut revenir au rôle du process CKPT qui vient écrire dans l’entête des datafiles le SCN , et également des informations techniques plus poussées comme le DBID de la base , ou les infos du dernier RESETLOGS.
Lorsqu’un tablespace passe en mode lecture seule, le process CKPT stoppe alors ses écritures dans les entêtes de datafiles et execute un checkpoint (ALTER SYSTEM CHECKPOINT) pour figer les dernières informations techniques de la base sur les entêtes des datafiles appartenant au tablespace.
Du coup, lorsque plus tard on clone cette base, on se retrouve avec certains fichiers ayant un SCN très ancien et sur lesquels on ne peut plus appliquer d’archives de redologs (trop anciennes et probablement supprimées depuis ce temps), ou alors ayant un DBID ne correspondant pas au DBID de la base après clonage.
Bien que le premier DUPLICATE se soit déroulé correctement (probablement un défaut dans l’outil RMAN ?), cela explique pourquoi le second DUPLICATE plante sur le traitement d’un datafile appartenant à un tablespace en lecture seule.
Si un jour vous êtes confronté à une situation similaire, voici la solution au problème : sur la base source et avant de démarrer l’exécution du RMAN DUPLICATE, exécutez simplement les commandes SQL suivantes :

SQL> alter tablespace <nom du tablespace> read write ;
Tablespace altered.
SQL> alter tablespace <nom du tablespace> read only ;
Tablespace altered.
SQL> alter system checkpoint ;

Ces quelques commandes suffisent à écraser les entêtes des datafiles avec les dernières informations connues de la base source (DBID, SCN , etc…) et permettent ainsi d’aller jusqu’au bout de votre opération de clonage.