RMAN et Data Guard 11g (Part 1) : Active Database Duplication

RMAN et Data Guard sont tellement utiles au quotidien que c’est un vrai plaisir de découvrir leurs nouvelles fonctionnalités. 10g n’avait pas été avare dans ce domaine… 11g continue de nous en offrir toujours plus. Dans ces quelques articles consacrés à RMAN et Data Guard 11g, je vais essayer de vous faire partager mon enthousiasme en commençant par « Active Database Duplication ».

Oracle 11g permet désormais d’utiliser la commande DUPLICATE sans avoir au préalable créé une sauvegarde que nous aurions mis à disposition du serveur sur lequel nous allons créer le clone de la base de données. Configurer des environnements pour des tests ou en vue de construire une standby est encore plus simple. Dans la suite de ce post, nous allons utiliser cette nouvelle possibilité pour créer un nouvel environnement.

1- Créer un fichier de mot de passe le serveur de la copie

Vous aurez besoin de vous connecter à l’instance de votre future base de données. L’essentielle de la configuration nécessaire pour invoquer le script RMAN consiste donc à créer cette instance et à permettre son accès depuis l’instance que l’on veut dupliquer via Oracle Net. Après avoir installé le logiciel Oracle, il faut donc créer le fichier de mots de passe dans le répertoire qui convient. Voici un exemple ci-dessous sous Linux :

orapwd file=orapwCOPY 
password=change_on_install
entries=5

Remarque :
J’ai du mettre le même mot de passe SYS dans les 2 password files. A verifier masi ce ne devrait pas être le cas sur la production

2- Mettre en place la configuration réseau

Il faut pouvoir accéder à l’instance clone alors que celle-ci n’est pas démarrée ; pour cela, il suffit d’utiliser la configuration réseau à la Oracle8, c’est à dire en utilisant le SID. Sur la machine sur laquelle vous aller réaliser la copie, paramétrez le listener avec le SID de votre nouvelle instance enregistrée de manière statique. Pour cela, ajoutez quelque chose comme ceci dans votre fichier listener.ora. Dans l’exemple qui suit, on suppose que le nom du listener est celui par défaut, i.e. LISTENER. L’instance s’appelle GARK :

SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(ORACLE_HOME = /u01/app/oracle/product/11.1.0/db_1)
(SID_NAME = LCRO)
)
)

Rechargez ensuite la configuration du listener (Ou démarrez le si ce n’est pas déjà le cas) :

lsnrctl reload LISTENER

Coté production, modifiez le fichier tnsnames.ora pour pointer vers l’instance clone :

GARK =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)
(HOST = localhost)
(PORT = 1521))
)
(CONNECT_DATA =
(SID = GARK)
)
)

3- Configurer l’instance sur le clone

3 paramètres suffisent pour créer un fichier d’init.ora : db_name, memory_target et processes. Voici un script ci-dessous qui génère ce fichier sous Unix. Vérifiez que vous êtes dans le bon répertoire :

echo "db_name=LCRO">initGARK.ora
echo "memory_target=150M">>initGARK.ora
echo "processes=50">>initGARK.ora

Sous Unix, ajoutez votre instance dans oratab. Sous Windows créez et démarrez le service de base de données avec oradim :

echo "GARK:/u01/app/oracle/product/11.1.0/db_1:N" 
>> /etc/oratab

Remarque :
Le spfile sera copié depuis l’originale et les paramètres directement traduits grâce à l’option PARAMETER_VALUE_CONVERT. Vérifiez donc que les repertoires correspondant aux paramètres xx_dest existent et en particulier dans mon cas, j’ai du créer les répertoires correspondant aux valeurs traduites de :

  • log_archive_dest_n (/u01/app/oracle/oradata/GARK/archives dans mon cas)
  • audit_dump_dest (/u01/app/oracle/admin/GARK/adump dans mon cas)

Les nouveaux répertoires sous « diagnostic_dest » sont quant à eux créés automatiquement.

4- C’est parti…

Vous pouvez vous connecter avec RMAN à votre base de données primaire et la future base clone :

rman
connect target sys@orcl
database Password:
connected to target database: ORCL (DBID=1155453061)

connect auxiliary sys@gark
auxiliary database Password:
connected to auxiliary database: ORCL (not started)

Vous pouvez maintenant démarrer (nomount) l’instance clone :

  startup auxiliary nomount;

Total System Global Area 159019008 bytes

Fixed Size 1297344 bytes
Variable Size 142607424 bytes
Database Buffers 12582912 bytes
Redo Buffers 2531328 bytes

Le script est quant à lui assez simple :

DUPLICATE TARGET DATABASE
TO GARK
FROM ACTIVE DATABASE
DB_FILE_NAME_CONVERT 'ORCL','GARK'
SPFILE
PARAMETER_VALUE_CONVERT 'ORCL',
'GARK'
SET MEMORY_TARGET = '150M'
SET LOG_FILE_NAME_CONVERT 'ORCL',
'GARK';

En substance, ce qu’il y a de nouveau c’est :

  • FROM ACTIVE DATABASE signifie que c’est la base de données qui est elle même utilisée plutôt qu’une sauvegarde pour constituer le clone
  • DB_FILE_NAME_CONVERT définit la correspondance dans les nom de répertoire/fichier entre primaire et clone
  • SPFILE indique que le spfile sera constitue depuis la primaire
  • SET PARAMETER_VALUE_CONVERT change toutes les valeurs des paramètres en fonction des correspondances qui suivent
  • SET MEMORY_TARGET change la valeur de MEMORY_TARGET sur le clone
  • SET LOG_FILE_NAME_CONVERT positionne le parametre dans le spfile de l’instance clone pour que les fichiers log changent de place lorsqu’ils seront recréés

5- Et après ?

Constatez avec plaisir que ça marche et que c’est trop simple :

Starting Duplicate Db at 17-JUL-07
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=42 device type=DISK
allocated channel: ORA_AUX_DISK_2
channel ORA_AUX_DISK_2: SID=41 device type=DISK
allocated channel: ORA_AUX_DISK_3
channel ORA_AUX_DISK_3: SID=40 device type=DISK
allocated channel: ORA_AUX_DISK_4
channel ORA_AUX_DISK_4: SID=39 device type=DISK
allocated channel: ORA_AUX_DISK_5
channel ORA_AUX_DISK_5: SID=38 device type=DISK


contents of Memory Script:
{
backup as copy reuse
file '/u01/app/oracle/product/11.1.0/db_1/dbs/spfileORCL.ora' auxiliary format
'/u01/app/oracle/product/11.1.0/db_1/dbs/spfileGARK.ora' ;
sql clone "alter system set spfile= ''/u01/app/oracle/product/11.1.0/db_1/dbs/spfileGARK.ora''";
}
executing Memory Script

Starting backup at 17-JUL-07
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=136 device type=DISK
allocated channel: ORA_DISK_2
channel ORA_DISK_2: SID=134 device type=DISK
allocated channel: ORA_DISK_3
channel ORA_DISK_3: SID=125 device type=DISK
allocated channel: ORA_DISK_4
channel ORA_DISK_4: SID=132 device type=DISK
allocated channel: ORA_DISK_5
channel ORA_DISK_5: SID=128 device type=DISK
Finished backup at 17-JUL-07

sql statement: alter system set spfile= ''/u01/app/oracle/product/11.1.0/db_1/dbs/spfileGARK.ora''

contents of Memory Script:
{
sql clone "alter system set db_name =
''GARK'' comment=
''duplicate'' scope=spfile";
sql clone "alter system set audit_file_dest =''/u01/app/oracle/admin/GARK/adump'' comment=
'''' scope=spfile";
sql clone "alter system set control_files =
''/u01/app/oracle/oradata/GARK/control01.ctl'', ''/u01/app/oracle/oradata/GARK/control02.ctl'', ''/u01/app/oracle/oradata/GARK/control03.ctl'' comment=
'''' scope=spfile";
sql clone "alter system set dispatchers =
''(PROTOCOL=TCP) (SERVICE=GARKXDB)'' comment=
'''' scope=spfile";
sql clone "alter system set log_archive_dest_1 =
''LOCATION=/u01/app/oracle/oradata/GARK/archives'' comment=
'''' scope=spfile";
sql clone "alter system set MEMORY_TARGET =
150M comment=
'''' scope=spfile";
sql clone "alter system set LOG_FILE_NAME_CONVERT =
''ORCL'', ''GARK'' comment=
'''' scope=spfile";
shutdown clone immediate;
startup clone nomount ;
}
executing Memory Script

sql statement: alter system set db_name = ''GARK'' comment= ''duplicate'' scope=spfile

sql statement: alter system set audit_file_dest = ''/u01/app/oracle/admin/GARK/adump'' comment= '''' scope=spfile

sql statement: alter system set control_files = ''/u01/app/oracle/oradata/GARK/control01.ctl'', ''/u01/app/oracle/oradata/GARK/control02.ctl'', ''/u01/app/oracle/oradata/GARK/control03.ctl'' comment= '''' scope=spfile

sql statement: alter system set dispatchers = ''(PROTOCOL=TCP) (SERVICE=GARKXDB)'' comment= '''' scope=spfile

sql statement: alter system set log_archive_dest_1 = ''LOCATION=/u01/app/oracle/oradata/GARK/archives'' comment= '''' scope=spfile

sql statement: alter system set MEMORY_TARGET = 150M comment= '''' scope=spfile

sql statement: alter system set LOG_FILE_NAME_CONVERT = ''ORCL'', ''GARK'' comment= '''' scope=spfile

Oracle instance shut down

connected to auxiliary database (not started)
Oracle instance started

Total System Global Area 159019008 bytes

Fixed Size 1297344 bytes
Variable Size 138413120 bytes
Database Buffers 16777216 bytes
Redo Buffers 2531328 bytes

contents of Memory Script:
{
set newname for datafile 1 to
"/u01/app/oracle/oradata/GARK/system01.dbf";
set newname for datafile 2 to
"/u01/app/oracle/oradata/GARK/sysaux01.dbf";
set newname for datafile 3 to
"/u01/app/oracle/oradata/GARK/undotbs01.dbf";
set newname for datafile 4 to
"/u01/app/oracle/oradata/GARK/users01.dbf";
set newname for datafile 5 to
"/u01/app/oracle/oradata/GARK/example01.dbf";
backup as copy reuse
datafile 1 auxiliary format
"/u01/app/oracle/oradata/GARK/system01.dbf" datafile
2 auxiliary format
"/u01/app/oracle/oradata/GARK/sysaux01.dbf" datafile
3 auxiliary format
"/u01/app/oracle/oradata/GARK/undotbs01.dbf" datafile
4 auxiliary format
"/u01/app/oracle/oradata/GARK/users01.dbf" datafile
5 auxiliary format
"/u01/app/oracle/oradata/GARK/example01.dbf" ;
sql 'alter system archive log current';
}
executing Memory Script

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

Starting backup at 17-JUL-07
using channel ORA_DISK_1
using channel ORA_DISK_2
using channel ORA_DISK_3
using channel ORA_DISK_4
using channel ORA_DISK_5
channel ORA_DISK_1: starting datafile copy
input datafile file number=00001 name=/u01/app/oracle/oradata/ORCL/system01.dbf
channel ORA_DISK_2: starting datafile copy
input datafile file number=00002 name=/u01/app/oracle/oradata/ORCL/sysaux01.dbf
channel ORA_DISK_3: starting datafile copy
input datafile file number=00005 name=/u01/app/oracle/oradata/ORCL/example01.dbf
channel ORA_DISK_4: starting datafile copy
input datafile file number=00003 name=/u01/app/oracle/oradata/ORCL/undotbs01.dbf
channel ORA_DISK_5: starting datafile copy
input datafile file number=00004 name=/u01/app/oracle/oradata/ORCL/users01.dbf
output file name=/u01/app/oracle/oradata/GARK/system01.dbf tag=TAG20070717T210231 RECID=0 STAMP=0
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:03:08
output file name=/u01/app/oracle/oradata/GARK/example01.dbf tag=TAG20070717T210231 RECID=0 STAMP=0
channel ORA_DISK_3: datafile copy complete, elapsed time: 00:02:09
output file name=/u01/app/oracle/oradata/GARK/undotbs01.dbf tag=TAG20070717T210231 RECID=0 STAMP=0
channel ORA_DISK_4: datafile copy complete, elapsed time: 00:01:16
output file name=/u01/app/oracle/oradata/GARK/sysaux01.dbf tag=TAG20070717T210231 RECID=0 STAMP=0
channel ORA_DISK_2: datafile copy complete, elapsed time: 00:02:53
output file name=/u01/app/oracle/oradata/GARK/users01.dbf tag=TAG20070717T210231 RECID=0 STAMP=0
channel ORA_DISK_5: datafile copy complete, elapsed time: 00:00:28
Finished backup at 17-JUL-07

sql statement: alter system archive log current
sql statement: CREATE CONTROLFILE REUSE SET DATABASE "GARK" RESETLOGS ARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 292
LOGFILE
GROUP 1 ( '/u01/app/oracle/oradata/GARK/redo01.log' ) SIZE 50 M REUSE,
GROUP 2 ( '/u01/app/oracle/oradata/GARK/redo02.log' ) SIZE 50 M REUSE,
GROUP 3 ( '/u01/app/oracle/oradata/GARK/redo03.log' ) SIZE 50 M REUSE
DATAFILE
'/u01/app/oracle/oradata/GARK/system01.dbf'
CHARACTER SET WE8MSWIN1252


contents of Memory Script:
{
backup as copy reuse
archivelog like "/u01/app/oracle/oradata/ORCL/archives/1_16_627672327.dbf" auxiliary format
"/u01/app/oracle/oradata/GARK/archives/1_16_627672327.dbf" ;
catalog clone archivelog "/u01/app/oracle/oradata/GARK/archives/1_16_627672327.dbf";
switch clone datafile all;
}
executing Memory Script

Starting backup at 17-JUL-07
using channel ORA_DISK_1
using channel ORA_DISK_2
using channel ORA_DISK_3
using channel ORA_DISK_4
using channel ORA_DISK_5
channel ORA_DISK_1: starting archived log copy
input archived log thread=1 sequence=16 RECID=3 STAMP=628203968
output file name=/u01/app/oracle/oradata/GARK/archives/1_16_627672327.dbf RECID=0 STAMP=0
channel ORA_DISK_1: archived log copy complete, elapsed time: 00:00:01
Finished backup at 17-JUL-07

cataloged archived log
archived log file name=/u01/app/oracle/oradata/GARK/archives/1_16_627672327.dbf RECID=1 STAMP=628203994

datafile 2 switched to datafile copy
input datafile copy RECID=1 STAMP=628203994 file name=/u01/app/oracle/oradata/GARK/sysaux01.dbf
datafile 3 switched to datafile copy
input datafile copy RECID=2 STAMP=628203994 file name=/u01/app/oracle/oradata/GARK/undotbs01.dbf
datafile 4 switched to datafile copy
input datafile copy RECID=3 STAMP=628203994 file name=/u01/app/oracle/oradata/GARK/users01.dbf
datafile 5 switched to datafile copy
input datafile copy RECID=4 STAMP=628203994 file name=/u01/app/oracle/oradata/GARK/example01.dbf

contents of Memory Script:
{
set until scn 1014560;
recover
clone database
delete archivelog
;
}
executing Memory Script

executing command: SET until clause

Starting recover at 17-JUL-07
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=148 device type=DISK
allocated channel: ORA_AUX_DISK_2
channel ORA_AUX_DISK_2: SID=152 device type=DISK
allocated channel: ORA_AUX_DISK_3
channel ORA_AUX_DISK_3: SID=150 device type=DISK
allocated channel: ORA_AUX_DISK_4
channel ORA_AUX_DISK_4: SID=151 device type=DISK
allocated channel: ORA_AUX_DISK_5
channel ORA_AUX_DISK_5: SID=153 device type=DISK

starting media r ecovery

archived log for thread 1 with sequence 16 is already on disk as file /u01/app/oracle/oradata/GARK/archives/1_16_627672327.dbf
archived log file name=/u01/app/oracle/oradata/GARK/archives/1_16_627672327.dbf thread=1 sequence=16
media recovery complete, elapsed time: 00:00:01
Finished recover at 17-JUL-07

contents of Memory Script:
{
shutdown clone immediate;
startup clone nomount ;
}
executing Memory Script

database dismounted
Oracle instance shut down

connected to auxiliary database (not started)
Oracle instance started

Total System Global Area 159019008 bytes

Fixed Size 1297344 bytes
Variable Size 142607424 bytes
Database Buffers 12582912 bytes
Redo Buffers 2531328 bytes
sql statement: CREATE CONTROLFILE REUSE SET DATABASE "GARK" RESETLOGS ARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 292
LOGFILE
GROUP 1 ( '/u01/app/oracle/oradata/GARK/redo01.log' ) SIZE 50 M REUSE,
GROUP 2 ( '/u01/app/oracle/oradata/GARK/redo02.log' ) SIZE 50 M REUSE,
GROUP 3 ( '/u01/app/oracle/oradata/GARK/redo03.log' ) SIZE 50 M REUSE
DATAFILE
'/u01/app/oracle/oradata/GARK/system01.dbf'
CHARACTER SET WE8MSWIN1252


contents of Memory Script:
{
set newname for tempfile 1 to
"/u01/app/oracle/oradata/GARK/temp01.dbf";
switch clone tempfile all;
catalog clone datafilecopy "/u01/app/oracle/oradata/GARK/sysaux01.dbf";
catalog clone datafilecopy "/u01/app/oracle/oradata/GARK/undotbs01.dbf";
catalog clone datafilecopy "/u01/app/oracle/oradata/GARK/users01.dbf";
catalog clone datafilecopy "/u01/app/oracle/oradata/GARK/example01.dbf";
switch clone datafile all;
}
executing Memory Script

executing command: SET NEWNAME

renamed tempfile 1 to /u01/app/oracle/oradata/GARK/temp01.dbf in control file

cataloged datafile copy
datafile copy file name=/u01/app/oracle/oradata/GARK/sysaux01.dbf RECID=1 STAMP=628204020

cataloged datafile copy
datafile copy file name=/u01/app/oracle/oradata/GARK/undotbs01.dbf RECID=2 STAMP=628204020

cataloged datafile copy
datafile copy file name=/u01/app/oracle/oradata/GARK/users01.dbf RECID=3 STAMP=628204020

cataloged datafile copy
datafile copy file name=/u01/app/oracle/oradata/GARK/example01.dbf RECID=4 STAMP=628204020

datafile 2 switched to datafile copy
input datafile copy RECID=1 STAMP=628204020 file name=/u01/app/oracle/oradata/GARK/sysaux01.dbf
datafile 3 switched to datafile copy
input datafile copy RECID=2 STAMP=628204020 file name=/u01/app/oracle/oradata/GARK/undotbs01.dbf
datafile 4 switched to datafile copy
input datafile copy RECID=3 STAMP=628204020 file name=/u01/app/oracle/oradata/GARK/users01.dbf
datafile 5 switched to datafile copy
input datafile copy RECID=4 STAMP=628204020 file name=/u01/app/oracle/oradata/GARK/example01.dbf

contents of Memory Script:
{
Alter clone database open resetlogs;
}
executing Memory Script

database opened
Finished Duplicate Db at 17-JUL-07

Remarques :

  • Vous pouvez facilement vérifier les différentes étapes du DUPLICATE et sans doute pouvez-vous faire mieux… Mais difficilement plus simple à mettre en œuvre, non ?
  • Vous devriez pouvoir faire la même chose avec une base de données en mode NOARCHIVELOG à condition que la base de donnees origine soit « MOUNTED ». Je vous laisse essayer.

Voila qui va simplifier un peu plus votre vie. Je vous promets 9 autres posts sur ce thème bientôt.

-Grégory!