Configurer une "Managed Standby" en 4 étapes

A cause d’un misérable problème avec un broker Data Guard sur un de ces systèmes exotiques, je suis revenu à la bonne vieille « managed standby ». J’avais le souvenir de quelque chose de beaucoup plus compliqué. J’en suis presque déçu ! Enfin toujours est-il que, comme je manque cruellement d’imagination en cette période hivernal, voici les éléments de configuration de ma plateforme. A ce propos, si vous avez des idées pour des articles à propos d’Oracle n’hésitez pas.

Mettons d’abord les choses au claire : Ce qui suit vient d’un esprit tordu; dans la vraie vie, vous préfèrerez faire un « duplicate for standby from active database » ou simplement « duplicate » et surtout vous configurerez le broker. A ce propos, je vous invite à lire cet excellent article intitulé « 4 steps to create a Physical Standby Database ».

Mais revenons à mon propos. Ma base de données d’origine est BLACK; dans ce qui suit, je vais créer une base WHITE avec une sauvegarde/restauration. Je configurerai ensuite une managed standby sans broker…

Notes:

  • Il y a beaucoup de changements autour de RMAN et il est probable que cette procédure ne fonctionne pas de la même manière avec une 11.1 et en tout cas pas avec une 10.2.
  • A partir d’Oracle 11.2, il n’est plus nécessaire de configurer fal_client pour les bases de données.

Etape 1. Sauvegarde et SCP

Tout commence souvent par une sauvegarde. Au moins dans les histoires qui se terminent bien 😉 ! Comme je vais mettre en place une managed standby, c’est le log transport qui se chargera de synchroniser les archivelogs. J’ai donc décidé ci-dessous de ne prendre que le strict minimum, à savoir le spfile sous la forme d’un init.ora, les datafiles, le controlfile for standby :

mkdir -p /u01/app/oracle/backup/BLACK

rman target /

host 'rm /u01/app/oracle/backup/BLACK/spfile.ora';
run {
allocate channel c1 device type disk format '/u01/app/oracle/backup/BLACK/%U';
sql "create pfile=''/u01/app/oracle/backup/BLACK/init.ora'' from spfile";
backup as compressed backupset database;
backup as compressed backupset current controlfile for standby;
}

La sortie du script ci-dessous est la suivante, noter en particulier le nom du controlfile pour le restaurer ensuite :

rm: cannot remove `/u01/app/oracle/backup/spfile.ora': No such file or directory
host command complete
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-06135: error executing host command: Additional information: 256

using target database control file instead of recovery catalog
allocated channel: c1
channel c1: SID=19 device type=DISK

sql statement: create pfile=''/u01/app/oracle/backup/BLACK/init.ora'' from spfile

Starting backup at 17-DEC-10
channel c1: starting compressed full datafile backup set
channel c1: specifying datafile(s) in backup set
input datafile file number=00001 name=/u01/app/oracle/oradata/BLACK/datafile/o1_mf_system_6fb1h7pc_.dbf
input datafile file number=00002 name=/u01/app/oracle/oradata/BLACK/datafile/o1_mf_sysaux_6fb1h7tr_.dbf
input datafile file number=00003 name=/u01/app/oracle/oradata/BLACK/datafile/o1_mf_undotbs1_6fb1h7wf_.dbf
input datafile file number=00005 name=/u01/app/oracle/oradata/BLACK/datafile/o1_mf_example_6fb1kl7p_.dbf
input datafile file number=00004 name=/u01/app/oracle/oradata/BLACK/datafile/o1_mf_users_6fb1h7y1_.dbf
channel c1: starting piece 1 at 17-DEC-10
channel c1: finished piece 1 at 17-DEC-10
piece handle=/u01/app/oracle/backup/BLACK/0nlvpnuc_1_1 tag=TAG20101217T135731 comment=NONE
channel c1: backup set complete, elapsed time: 00:01:25
channel c1: starting compressed full datafile backup set
channel c1: specifying datafile(s) in backup set
including current control file in backup set
including current SPFILE in backup set
channel c1: starting piece 1 at 17-DEC-10
channel c1: finished piece 1 at 17-DEC-10
piece handle=/u01/app/oracle/backup/BLACK/0olvpo11_1_1 tag=TAG20101217T135731 comment=NONE
channel c1: backup set complete, elapsed time: 00:00:01
Finished backup at 17-DEC-10

Starting backup at 17-DEC-10
channel c1: starting compressed full datafile backup set
channel c1: specifying datafile(s) in backup set
including standby control file in backup set
channel c1: starting piece 1 at 17-DEC-10
channel c1: finished piece 1 at 17-DEC-10
piece handle=/u01/app/oracle/backup/BLACK/0plvpo16_1_1 tag=TAG20101217T135901 comment=NONE
channel c1: backup set complete, elapsed time: 00:00:01
Finished backup at 17-DEC-10
released channel: c1

Pour mettre un peu de piment, on supposera que l’arborescence sur le serveur distant est différente. Je vous laisse gérer les droits et les répertoires et pousse les fichiers à distance à l’aide d’un SCP ou de la commande de votre choix :

cd /u02/app/oracle/backup/BLACK
scp * white-server:/u01/app/oracle/backup/WHITE

Etape 2 : Préparer Instance et listeners

Contrairement au cas du broker, il n’est pas nécessaire de configurer les listeners pour des enregistrements statiques des instances; en effet, vous pouvez toujours arrêter et démarrer les bases de données depuis SQL*Plus en local. Evidemment, il faut que :

  • oratab (ou les services Windows) soit configuré
  • les mots de passe SYS (ou REDO_TRANSPORT_USER) correspondent sur les 2 serveurs ainsi que le paramètre ignorecase=Y|N

Le script ci-dessous effectue ces opérations :

echo "WHITE:/u01/app/oracle/product/11.2.0/db_1:N" >> /etc/oratab
export ORACLE_SID=WHITE
export ORAENV_ASK=NO
. oraenv

cd $ORACLE_HOME/dbs
orapwd file=orapwWHITE entries=5 ignorecase=Y

Modifiez ensuite le fichier init.ora pour contenir les bon paramètres ; pour éviter une erreur, on copiera le fichier init.ora au préalable :

cd /u02/app/oracle/backup/WHITE
cp init.ora initWHITE.ora

Modifiez ensuite les paramètres qui vont bien; dans mon cas, j’ai modifié les 3 lignes suivantes :

*.audit_file_dest='/u01/app/oracle/admin/WHITE/adump'
*.control_files='/u01/app/oracle/oradata/WHITE/controlfile/control01.ctl'
*.log_archive_dest_1='location=/u01/app/oracle/oradata/WHITE/archivelog'

J’ai créé les répertoires correspondant à l’init.ora mais également aux destinations des datafiles, tempfiles, controlfiles, redologs et archivelogs:

mkdir -p /u01/app/oracle/admin/WHITE/adump
mkdir -p /u01/app/oracle/oradata/WHITE/controlfile
mkdir -p /u01/app/oracle/oradata/WHITE/onlinelog
mkdir -p /u01/app/oracle/oradata/WHITE/datafile
mkdir -p /u01/app/oracle/oradata/WHITE/tempfile
mkdir -p /u01/app/oracle/oradata/WHITE/archivelog
  • le paramètre db_name doit évidemment rester identique
  • Il est probable que vous deviez modifier d’autres paramètres existants comme local_listener, remote_listener, etc

Il faut enfin ajouter des paramètres et notamment les 3 suivants :

*.db_unique_name='WHITE'
*.log_file_name_convert='BLACK','WHITE'
*.db_file_name_convert='BLACK','WHITE'

Créez le spfile puis démarrez la nouvelle instance :

export ORACLE_SID=WHITE
export ORAENV_ASK=NO
. oraenv
sqlplus / as sysdba
create spfile from pfile='/u01/app/oracle/backup/WHITE/initWHITE.ora';
startup nomount;
exit

Etape 3. Restaurer la base de données

L'étape est simple, il s'agit d'utiliser RMAN pour
  • restaurer le controlfile de standby
  • Monter la base de données
  • Supprimer les références aux sauvegardes de BLACK (sauf si les répertoires sont identiques)
  • Cataloguer les sauvegardes dans le controlfile
  • Restaurer la base de données
restore standby controlfile from '/u01/app/oracle/backup/WHITE/0plvpo16_1_1';
alter database mount;
crosscheck backup device type disk;
delete expired backup;
catalog start with '/u01/app/oracle/backup/WHITE';
restore database;
report schema;
exit;

Etape 4. Configurer le transport et vérifier la synchro

Nous voilà à la fin... Il suffit désormais de configurer le transport; sur la base de données WHITE, configurer les paramètres associés et démarrer l'application des LOG. Pour simplifier on utilisera une syntaxe EZCONNECT :

alter system set 
log_archive_config='dg_config=(BLACK,WHITE)';
alter system set fal_server='black-server:1521/BLACK';
alter database
recover managed standby database
disconnect from session;

Sur la base d'origine positionnez également les paramètres pour le transport :

alter system set 
log_archive_config='dg_config=(BLACK,WHITE)';
alter system set fal_server='white-server:1521/WHITE'; 
alter system set log_archive_dest_2=
'service=white-server:1521/WHITE async noaffirm valid_for=(online_logfile,primary_role) reopen=60 db_unique_name=WHITE';
alter system set log_archive_dest_state_2=enable;
alter system archive log current;

Voilà, vous pouvez vérifier que les logs sont envoyés par la base primaire :

col destination format a50
select destination, status, archived_thread#, archived_seq#
from v$archive_dest_status
where status not in ('DEFERRED', 'INACTIVE');

DESTINATION STATUS ARCHIVED_THREAD# ARCHIVED_SEQ#
---------------------------------------- ------ ---------------- -------------
/u01/app/oracle/oradata/BLACK/archivelog VALID 1 6
WHITE VALID 1 6

Vous pouvez également vérifier que sur la standby (WHITE), le processus MRP est en cours d'application du log :

select process, client_process, thread#, sequence#, status
from v$managed_standby;

PROCESS CLIENT_P THREAD# SEQUENCE# STATUS
------- -------- ---------- ---------- ------------
ARCH ARCH 0 0 CONNECTED
ARCH ARCH 0 0 CONNECTED
ARCH ARCH 0 0 CONNECTED
ARCH ARCH 0 0 CONNECTED
RFS ARCH 0 0 IDLE
RFS LGWR 1 7 IDLE
RFS UNKNOWN 0 0 IDLE
MRP0 N/A 1 7 WAIT_FOR_LOG

Idéalement créez des fichiers de standby redo et préparez-vous à basculer en mode normal ou en mode panique !