Dataguard... en gros

  • Imprimer

[EDIT : MAJ 14/10/2013 : rajout apport des flashbacks]

[EDIT : MAJ 12/10/2013 : rajout broker]

 Cet article traite de dataguard pour une 11gR2. Il peut être appliqué à une 10gR2, excepté sur certains  points techniques qui seront signalés. Normalement il doit aussi pouvoir s’appliquer à une 12cR1.

L’article a pour objectif de présenter dataguard de l’installation à sa gestion tout au long d’un enchainement logique de manipulation. Il peut être lu comme un TP.

Dans cet article nous allons commencer par configurer une dataguard, mais avec une petite subtilité, la base primaire initiale est sous ASM alors que la base standby sera sous filesystem. Cela permettra de couvrir la création puis la vie d’un datagaurd en rajoutant le facteur deux arborescences différentes, mais aussi deux systèmes de fichier différent et voir que cela est possible et fonctionne sans aucuns soucis.

Ensuite nous allons faire le classique switchover, inversion de rôle qui validera que la dataguard est bien fonctionnel dans les deux sens de réplication. Puis le failover pour montrer comment cela fonctionne et ce que cela implique au niveau dataguard par la suite.

Cela étant, nous enchainerons avec  la gestion des archivelog, quand et comment peuvent-ils être supprimés.

Nous enchainerons par la mise en place du broker, l’outil d’administration facultatif de dataguard mais qui peut simplifier l’administration.

Et pour finir, nous mettrons en place les flashbacks pour montrer l’intérêt de ceux-ci après un failover.

 

Rappel... ou pas

Dataguard est une solution de Disaster Recovery. C’est une infrastructure de la base de données qui automatise la création et la maintenance d’une ou de plusieurs copies de la base principale (ou primary database) définie sous le nom de base de secours (ou standby database).

Si la base principale devient indisponible alors la base de secours peut être activée et devenir à son tour principale.

Dataguard est une fonctionnalité inclue dans la version d’Oracle : Entreprise Edition.

Il existe 2 types de dataguard : les physiques (bases identiques niveau blocs) et les logiques (bases partiellement ou entièrement identiques au niveau données applicatives).

Un dataguard physique peut être configuré selon 3 modes de protection différents.

Mode

Risque de perte de données

Transport des logs

Comportement du mécanisme

MaxProtection

(Protection maximum)

« Zéro » Perte de données

SYNC

Blocage du site de production jusqu’à la réception de l’acquittement de la standby

MaxAvailability

(Disponibilité maximum)

« Zéro » perte de données

Non garantie

SYNC

Décrochage de la Primaire jusqu’à réception de l’acquittement ou à l’expiration du timeout – Puis reprise du traitement

MaxPerformance

(Performance maximum)

Perte de données possible

ASYNC

Le site Primaire n’attend jamais l’acquittement de la standby

La bases de secours ne sont pas ouvertes, elles sont en mode mount cela signifie que l’on ne peut pas les consulter. Mais depuis la 11g, il existe en plus une option payante appelée Active Dataguard, qui permet de maintenir les base de secours en mode READ ONLY, c'est-à-dire que l’on peut se connecter sur ces bases et lire les données. C’est d’ailleurs, ce que nous allons utiliser dans la présentation ci-dessous. La base de standby sera toujours ouverte (et pas mount).

Oracle dataguard prend en charge des opérations de changement de rôle de la base de données : switchover et failover :

Un switchover est une permutation de rôle entre des bases dataguard synchronisées. Une base primaire devient standby et une standby devient primaire. Le switchover est non destructif, une fois le switchover fini, il peut être fait dans l’autre sens. Suivant le mode protection il peut être fait que si au moins une ou toutes les bases standby sont synchronisées. Il est généralement utilisé pour des raisons de maintenance du site principal.

Un failover est un changement de rôle d’un standby en primaire avec une perte définitive de la primaire. Les bases standby n’ont pas besoin d’être synchronisées avec la primaire lors de ce basculement. Il peut donc entraîner une perte de donnée. La perte de donnée dépendant du mode de sécurité mis dans la configuration du dataguard. Il est utilisé en cas d’incident majeur.

 

Pré-requis

Pour suivre cet article comme un TP, il faut 2 serveurs dans le même réseau.

 Ici je me suis servi d’un nœud RAC pour installer une base de données en standalone sur ASM. Le serveur vient de l’installation faite dans : testbed : 11gR2 RAC ASM. Il se nomme racdb1.

Pour le deuxième serveur, celui qui va héberger la base en filesystem, j’ai pris un serveur dont j’ai installé le même OS que sur le serveur RAC, mais le moteur Oracle est installé en standalone pas en RAC. Le serveur se nomme oradbm1.

Les deux moteurs Oracle doivent être à la même version, ici c’est la version Entreprise 11.2.0.3.4.

La base qui va être dataguardée, a été installée sur le serveur avec ASM avec l’outil dbca. Rien de particulier si ce n’est qu’il ne faut pas la mettre en mode archivelog et ne pas sélectionner de flash recovery area.

Pour faciliter la compréhension des commandes à exécuter sur l’un ou l’autre des serveurs, le tableau ci-dessous synthétise les informations à retenir :

 

Nom du serveur

Adresse IP

Prompt shell

Prompt sqlplus

Prompt RMAN

Nom de la base

Nom de l’ »unique name »

Base sous ASM

racdb1

10.10.0.10

PRI>  

SQL-P>

RMAN-P>

TROLL

TROLL1

Base sous filesystem

oradbm1

10.10.0.61

STB>

SQL-S>

RMAN-S>

TROLL

TROLL2

C’est parti…

 

 

Création de la dataguard

Avant de créer notre dataguard il faut s’occuper de la base primaire, il faut la préparer pour qu’elle puisse se répliquer.

 Il faut que la base soit en force logging, c'est-à-dire que tout doit être loggé dans les redolog et archivelog. Pour cela :

SQL-P> alter database force logging;
SQL-P> select force_logging from v$database;
FOR
---
YES

Ensuite ce n’est pas obligatoire mais tellement plus simple, mettez la base en spfile.

En revanche c’est obligatoire le db_unique_name doit être setté, c’est ce paramètre qui va permettre de différencier les bases. Comme dans le tableau d’introduction, la base initialement primaire va prendre comme db_unique_name TROLL1 :

SQL-P> show parameter unique
NAME                                                       TYPE VALUE
------------------------------------ ----------- ------------------------------
db_unique_name                                               string               TROLL

SQL-P> alter system set db_unique_name='TROLL1' scope=spfile;

SQL-P> show parameter unique
NAME                                                       TYPE VALUE
------------------------------------ ----------- ------------------------------
db_unique_name                                               string               TROLL1

Obligatoire aussi, le password file doit exister et être copié sur le serveur secondaire :

PRI>  scp $ORACLE_HOME/dbs/orapwTROLL oracle@oradbm1:/oracle/11.2.0.3/database/dbs

Il permet aux bases de se connecter entre elles en sys en remote et donc le paramètre remote_login_passwordfile ne doit pas être en NONE mais EXCLUSIVE sur la base :

SQL-P> show parameter remote_login_passwordfile
NAME                                                       TYPE VALUE
------------------------------------ ----------- ------------------------------
remote_login_passwordfile           string               EXCLUSIVE

(Si il est à NONE changez le)

 

Si les bases doivent se connecter entre elles c’est qu’elles doivent connaître les chemins réseaux, donc mise à jour du tnsnames.ora 

PRI> vi $ORACLE_HOME/network/admin/tnsnames.ora
TROLL2 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = oradbm1.localdomain)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = TROLL2)
    )
  )

 STB> vi $ORACLE_HOME/network/admin/tnsnames.ora
TROLL1 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = racdb1.localdomain)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = TROLL1)
    )
  )

Un petit test:

STB> tnsping troll1

TNS Ping Utility for Linux: Version 11.2.0.2.0 - Production on 05-JUL-2013 21:22:51
Copyright (c) 1997, 2010, Oracle.  All rights reserved.
Used parameter files:

Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = racdb1.localdomain)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = TROLL)))
OK (50 msec)

Ni-Cr en bon chimiste de formation, je m'exclame!!!

Pour démarrer la nouvelle instance sur le serveur oradbm1, il faut préparer un init qui va bien et pour cela sur le serveur racdb1, nous générons le init de TROLL1 et modifions comme suit:

SQL-P> create pfile='/oracle/backup/TROLL/initTROLL.ora' from spfile;

PRI> vi /oracle/backup/TROLL/initTROLL.ora
TROLL.__db_cache_size=339738624
TROLL.__java_pool_size=4194304
TROLL.__large_pool_size=4194304
TROLL.__pga_aggregate_target=339738624
TROLL.__sga_target=507510784
TROLL.__shared_io_pool_size=0
TROLL.__shared_pool_size=150994944
TROLL.__streams_pool_size=0
*.audit_file_dest='/oracle/oraBase/admin/TROLL/adump'
*.audit_trail='db'
*.compatible='11.2.0.0.0'
*.control_files='+DATA2/TROLL/control01.ctl','+DATA2/TROLL/control02.ctl'
*.control_files='/oradata/TROLL/control01.ctl','/oradata/TROLL/control02.ctl'
*.db_block_size=8192
*.db_domain=''
*.db_name='TROLL'
*.db_unique_name='TROLL1'
*.db_unique_name='TROLL2'
*.diagnostic_dest='/oracle/oraBase'
*.log_archive_dest_1='LOCATION=+DATA2'
*.log_archive_dest_1='LOCATION=/oradata/TROLL/arch'
*.log_archive_format='%t_%s_%r.dbf'
*.memory_target=846200832
*.open_cursors=300
*.processes=150
*.remote_login_passwordfile='EXCLUSIVE'
*.undo_tablespace='UNDOTBS1'

Et rajoutons:

*.db_file_name_convert=('+DATA2/troll','/oradata/TROLL','+DATA1/troll','/oradata/TROLL')
*.log_file_name_convert =('+DATA2/troll','/oradata/TROLL','+DATA1/troll','/oradata/TROLL')
*.log_archive_config='dg_config=(TROLL1,TROLL2)'
*.log_archive_dest_2='service=TROLL1 valid_for=(online_logfiles,primary_role) db_unique_name=TROLL1'
*.standby_file_management='AUTO'

Pour connaître les chemins à convertir sur TROLL1, nous avons exécuté : select NAME from v$datafile; select MEMBER from v$logfile; et select name from v$tempfile;

Et sur oradbm1, il faut préparer l’arborescence:

STB> mkdir -p/oracle/oraBase/admin/TROLL/adump
STB> mkdir -p /oradata/TROLL/arch
STB> mkdir -p /oradata/TROLL/datafile
STB> mkdir -p /oradata/TROLL/tempfile

Maintenant nous pouvons passer aux choses sérieuses, dupliquer la base TROLL. Celle-ci est sous ASM, nous allons la backuper sous filesystem puis copier le backup sur l’autre serveur. Vous pouvez aussi pour gagner du temps faire un backup sur un filesystem partagé entre les 2 serveurs, un partage NFS par exemple. Nous pourrions aussi utiliser la commande

“duplicate target database for standby from active database” qui permet à partir du seveur de standby de générer directement la dataguard sans passer par un fichier de backup intermédiaire. Cette commande est seulement disponible à partir de la 11gR1.

Avant le backup, pensez à vérifier et/ou à mettre l’autobackup du controlfile, sinon il faudra le backuper manuellement après le backup.

PRI> rman target /
RMAN-P>CONFIGURE CONTROLFILE AUTOBACKUP ON;

RMAN-P>CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '/oracle/backup/TROLL/%F';

RMAN-P> backup  format '/oracle/backup/TROLL/full_rman_%s' full database plus archivelog;

Tous nos backups se trouvent donc sous /oracle/backup/TROLL, il faut donc les copier sur le serveur oradbm1:

PRI> scp /oracle/backup/TROLL/* oracle@oradbm1:/oracle/backup/TROLL
oracle@oradbm1's password:
c-2412750592-20130705-00                                                                                                    100% 9600KB   9.4MB/s   00:00  
full_rman_1                                                                                                                 100%   13MB  12.6MB/s   00:00  
full_rman_2                                                                                                                 100%  727MB  18.2MB/s   00:40  
full_rman_3                                                                                                                 100% 4608     4.5KB/s   00:00  
initTROLL.ora                                                                                                               100%  750     0.7KB/s   00:00

Pour démarrer TROLL2, il faut penser à copier le initTROLL.ora dans $ORACLE_HOME/dbs puis

STB> export ORACLE_SID=TROLL
STB> sqlplus / as sydba
SQL-S> startup nomount

C'est parti pour une duplication en règle:

STB>  rman target sys/motdepasse@TROLL1 auxiliary sys/motdepasse

Recovery Manager: Release 11.2.0.3.0 - Production on Sat Jul 6 19:11:10 2013
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

connected to target database: TROLL (DBID=2412750592)
connected to auxiliary database: TROLL (not mounted)

RMAN-S> duplicate target database for standby  NOFILENAMECHECK ;

Le duplicate fonctionne car les backups se trouvent dans la même arborescence sur les deux serveurs. Nous nous sommes connectés à la base TROLL1 et au moment du duplicate RMAN cherche les fichiers de backup dans l’arborescence de racdb1 mais en local sur oradbm1.

La base est clonée et presque prête à être activé en dataguard, il manque les redolog standby. Une règle Oracle dit : pour 1 thread le nombre de redolog standby doit être égal au nombre redolog plus 1. Comme nous ne sommes pas en RAC il n’y a qu’un thread.

SQL-P> select a.group#,b.thread#, a.member, b.BYTES/1024 from v$logfile a, v$log b  where a.group#=b.group# order by 1;
    GROUP#    THREAD# MEMBER                                                                    B.BYTES/1024
---------- ---------- ---------------------------------------- ------------
                 1                1 +DATA2/troll/redo01.log                                           51200
                 2                1 +DATA2/troll/redo02.log                                           51200
                 3                1 +DATA2/troll/redo03.log                                           51200

Donc 4 redologs standby à créer sur TROLL2:

SQL-S> ALTER DATABASE ADD STANDBY LOGFILE  GROUP 11 '/oradata/TROLL/sby_redo01.log' size 51200K reuse;
SQL-S> ALTER DATABASE ADD STANDBY LOGFILE  GROUP 12 '/oradata/TROLL/sby_redo02.log' size 51200K reuse;
SQL-S> ALTER DATABASE ADD STANDBY LOGFILE  GROUP 13 '/oradata/TROLL/sby_redo03.log' size 51200K reuse;
SQL-S> ALTER DATABASE ADD STANDBY LOGFILE  GROUP 14 '/oradata/TROLL/sby_redo04.log' size 51200K reuse;

 

Il faut aussi sur la primaire créer les redolog standby pour quand celle-ci deviendra standby à son tour suite à un switchover:

SQL-P> ALTER DATABASE ADD STANDBY LOGFILE  GROUP 11 '+DATA2' size 51200K reuse;
SQL-P> ALTER DATABASE ADD STANDBY LOGFILE  GROUP 12 '+DATA2' size 51200K reuse;
SQL-P> ALTER DATABASE ADD STANDBY LOGFILE  GROUP 13 '+DATA2' size 51200K reuse;
SQL-P> ALTER DATABASE ADD STANDBY LOGFILE  GROUP 14 '+DATA2' size 51200K reuse;

Nous allons maintenant dire à notre dataguard de démarrer le processus de recover (le MRP) même si notre base primaire n’envoie pas encore de redolog et d’archivelog :

SQL-S> ALTER DATABASE recover managed standby database using current logfile disconnect from session;

Et nous allons informer TROLL1 qu’il faut envoyer les archivelogs et les redologs (redo suivant le mode de protection voir rappel différent mode de protection) :

SQL-P> alter system set log_archive_config='dg_config=(TROLL1, TROLL2)' scope=both;
SQL-P> alter system set log_archive_dest_2='service=TROLL2 lgwr sync AFFIRM db_unique_name=TROLL2 valid_for=(online_logfiles,primary_role)' scope=both;

Aussi nous l’informons que si elle devient à son tour base secondaire il faudra convertir les noms des noms de datafiles et redolog :

SQL-P> alter system set standby_file_management=auto scope=both;
SQL-P>alter system set db_file_name_convert='/oradata/TROLL','+DATA2/troll','/oradata/TROLL','+DATA1/troll'  scope=spfile;
SQL-P>alter system set log_file_name_convert ='/oradata/TROLL','+DATA2/troll','/oradata/TROLL','+DATA1/troll' scope=spfile;

Donc maintenant la primaire envoie les redologq sur la secondaire et la secondaire les applique? C’est bien cela ?... oui, vérifions :

SQP-S> alter session set nls_date_format='yyyy/mm/dd hh24:mi:ss';
SQL-S> select name,creator,sequence#,applied,completion_time from v$archived_log where completion_time>sysdate-1/24 or applied='NO' order by sequence#;

NAME                                                                                    CREATOR  SEQUENCE# APPLIED
-------------------------------------------------- ------- ---------- ---------
COMPLETION_TIME
------------------
[...]
/oradata/TROLL/arch/1_30_819412224.dbf                          ARCH                    30 YES
2013/07/06 21:30:55

/oradata/TROLL/arch/1_31_819412224.dbf                          ARCH                    31 YES
2013/07/06 21:30:54

/oradata/TROLL/arch/1_32_819412224.dbf                          ARCH                    32 YES
2013/07/06 21:30:55

/oradata/TROLL/arch/1_33_819412224.dbf                          ARCH                    33 IN-MEMORY
2013/07/06 21:30:53

 

Notre standby n’est pas ouverte elle n’est qu’en état mount, on ne peut donc pas lire les données qui se réplique en temps réel !!! Pas de soucis nous allons l’ouvrir et réactiver l’application des logs. Attention, cela s’appelle Active Dataguard et nécessite d’avoir payé une licence supplémentaire en plus de la licence Entreprise Edition pour avoir du Dataguard.

Pour cela :

SQL-S> -- arrêt du MRP
SQL-S> alter database RECOVER MANAGED STANDBY DATABASE CANCEL immediate nowait;
SQL-S> -- ouverture de la dataguard
SQL-S> alter database open;
SQL-S> -- relance du MRP
SQL-S> alter database recover managed standby database using current logfile disconnect from session;

Remarque : Vérifier votre mode de protection et éventuellement forcer le en Maximum Performance (facultatif):

SQL-P> select PROTECTION_MODE from v$database;
PROTECTION_MODE
--------------------
MAXIMUM PERFORMANCE

SQL-P> ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE AVAILABILITY;

SQL-P> select PROTECTION_MODE from v$database;
PROTECTION_MODE
--------------------
MAXIMUM AVAILABILITY  

 

 

Switchover

Maintenant que nous avons une dataguard qui fonctionne, c’est bien beau, mais il faudrait faire des transitions de rôle pour la mettre un peu l’épreuve.

Nous allons commencer par le plus dur : le switchover… si le switchover fonctionne  alors un failover aurait fonctionné.

Avant de commencer un switch nous vérifions que les bases sont prêtes, et oui… un switch est une opération propre, prévu à l’avance normalement. Les rôles sont permutés et les deux bases doivent être donc au même niveau.

Vérifions à partir de primaire

SQL-P> SELECT SWITCHOVER_STATUS FROM V$DATABASE;
SWITCHOVER_STATUS
--------------------
TO STANDBY

To standby, cela signifie que c’est tout bon ! Sinon nous aurions par exemple RESOLVABLE GAP ou pire…

Alors quand il faut y aller, faut y aller…

SQL-P> alter database commit to switchover to physical standby WITH SESSION SHUTDOWN;
SQL-P> startup nomount
SQL-P> ALTER DATABASE MOUNT STANDBY DATABASE;

Vite vite, allons sur l’ancienne standby lui dire que maintenant c’est elle la cheftaine !

SQL-S> RECOVER MANAGED STANDBY DATABASE CANCEL ;
ORA-16136: Managed Standby Recovery not active  

SQL-S> ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
SQL-S>alter database open;
SQL-S> shutdown immediate
SQL-S> startup

parfait...

Vérifions maintenant que la nouvelle primaire est prête à redevenir une standby si oui, alors c’est que les 2 bases sont bien synchro… que le dataguard fonctionne bien

SQL-S> SELECT SWITCHOVER_STATUS FROM V$DATABASE;
SWITCHOVER_STATUS
--------------------
RESOLVABLE GAP

 … et bien non, il y a un gap entre les deux bases… c’est normal nous n’avons pas relancé le MRP sur la nouvelle standby, elle n’a donc appliqué aucun redolog :

SQL-P> alter database recover managed standby database using current logfile disconnect from session;

Maintenant revérifions que la primaire est prête pour une éventuelle switch…

SQL-S> SELECT SWITCHOVER_STATUS FROM V$DATABASE
SWITCHOVER_STATUS
--------------------
TO STANDBY

 … oui cette fois.

Nous avons réussi notre premier switchover

 

 

Failover

Nous allons faire un failover sur notre ancienne primaire. Cette opération va définitivement casser la dataguard. Le failover est une opération d’urgence, nous avons perdu la primaire et la production doit coute que coute reprendre sur la standby. L’opération est irréversible. Après un failover il ne reste plus qu’à recréer une standby à partir d’un backup… sauf si nous avons mis des flashbacks en place mais nous verrons cela plus tard chaque chose en son temps.

Pour faire un failover pas de chichi, pas de vérification ou autres... nous avons l'aval de la hiérarchie.. priorité production… le temps c’est de l’argent :

SQL-P> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH FORCE;
SQL-P> ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
SQL-P> ALTER DATABASE OPEN;

(rappel : ici SQL-P, P comme primaire, mais nous sommes bien sur une standby, SQL-P c’est le prompt SQL de notre serveur primaire du départ qui est devenu standby)

La standby est définitivement morte, on ne fait pas d’omelette sans casser des œufs. Il faut la reconstruire comme dans le paragraphe « création d’une dataguard«. Il faut recommencer le backup-restore i tutti quanti.

Juste avant le « ALTER DATABASE ADD STANDBY LOGFILE…. », il faut faire …

SQL-S> alter database drop standby logfile group 11;
SQL-S> alter database drop standby logfile group 12;
SQL-S> alter database drop standby logfile group 13;
SQL-S> alter database drop standby logfile group 14;

… car cette fois-ci la primaire à déjà des redo standby.

 

 

Gestion des archivelogs

Sans la FRA

Les archivelogs deviennent un point sensible dans une dataguard. Les redo se jouent en temps réel si vous avez mis max protection, ils se jouent aussi en temps réel si vous avez mis max availability et qu’ils n’y a pas de problème réseau. Mais si un problème réseau ou bien le mode max performance est activé, les archivelog sont vitales dans la vie de la dataguard, il ne faut pas en perdre une seul !!! Car ils sont appliqués pour synchroniser la dataguard, si un est perdu… fini plus de dataguard synchronisée.

Mais que ce passe-t-il si on essaie d’effacer un archivelog avec RMAN alors qu’il n’a pas été transféré ? Faisons le test :

Arrêtons la standby puis sur la primaire un petit switch de logfile pour générer un archivelog.

SQL-P> aleter system switch logfile ;

Le redo courant vient donc d’être archivé, et vous pouvez vérifier il n’a pas été transféré. Maintenant backupons nos archivelog avec un delete input à la fin (delete des archivelog juste après backup)

RMAN-P>  backup  format '/oracle/backup/TROLL/archivelog_all_%s'  archivelog all delete input;

Nous obtenons des erreurs sur le delete pour certains archivelog:

RMAN-08137: WARNING: archived log not deleted, needed for standby or upstream capture process
archived log file name=+DATA2/troll1/archivelog/2013_07_10/thread_1_seq_8.280.820444909 thread=1 sequence=8
RMAN-08137: WARNING: archived log not deleted, needed for standby or upstream capture process
archived log file name=+DATA2/troll1/archivelog/2013_07_10/thread_1_seq_9.275.820445325 thread=1 sequence=9
Finished backup at 10-JUL-13

Oracle a détecté que les deux archivelogq ci-dessus n’avait pas été transportéq sur la standby et donc il n’a pas effacé ces deux archivelog… ouf.

Et maintenant si les archivelogs sont transportés mais pas appliqués ; est-ce que Oracle détecte cela et empêche le delete? … Testons.

Après s’être rassuré que le MRP tourne bien sur la standby et que les archivelogs sont bien appliqué, nous coupons le MRP.

SQL-S> alter database recover managed standby database cancel;

Puis sur la primaire, quelques switch de logfile:

SQL-P>  alter system switch logfile;
SQL-P>  alter system switch logfile;

Nous vérifions que les archivelogs sont bien transférés sur la standby et aussi non appliqués :

STB>  ls -ltr
total 10560
[…]
-rw-r-----. 1 oracle oinstall   14848 Jul 10 21:39 1_11_820273293.dbf
-rw-r-----. 1 oracle oinstall  121856 Jul 10 21:43 1_12_820273293.dbf
-rw-r-----. 1 oracle oinstall   27648 Jul 10 21:43 1_13_820273293.dbf

SQL-S> select name,creator,sequence#,applied,completion_time from v$archived_log
where completion_time>sysdate-1/24 or applied='NO' order by sequence#;

NAME                                                                                    CREATOR  SEQUENCE# APPLIED
-------------------------------------------------- ------- ---------- ---------
COMPLETION_TIME
-------------------
[...]
/oradata/TROLL/arch/1_11_820273293.dbf                          ARCH                    11 YES
2013/07/10 21:39:00

/oradata/TROLL/arch/1_12_820273293.dbf                          ARCH                    12 NO
2013/07/10 21:43:00

/oradata/TROLL/arch/1_13_820273293.dbf                          ARCH                    13 NO
2013/07/10 21:43:53

Puis backupons les archivelog avec un petit delete input des familles :

RMAN-P> backup  format '/oracle/backup/TROLL/archivelog_all_%s'  archivelog all delete input;

Cette fois-ci aucun alerte Oracle supprime tous les archivelogs.

Vous me direz ce n’est pas grave puisqu’ils ont été transférés sur le nœud de la standby et aussi nous avons un backup des archivelogs. Oui c’est vrai, mais maintenant si il y a eu une erreur humaine, quelqu’un qui ne comprenait pas pourquoi le filesystem se remplissait et à tout supprimé… un admin system quoi… à vous de voir et de méditer dessus.

Il existe aussi une autre problématique c’est la purge des archivelogs sur la standby. Il faut bien les purger mais seulement quand ils ont été appliqués.

Vous pouvez faire un script qui vérifie dans la base si les archivelogs ont été appliqués avec la vue v$archived_log par exemple puis les effacer.

Ou alors faire un delete archivelog all comme dans l’exemple ci-dessous, mais vous aurez des warning sous RMAN pour vous dire que certain archivelog ne peuvent être supprimé car nécessaire (no-applied) et gérer ces erreurs comme normal… mais ce n’est pas très professionnel tout cela. En plus si vous scriptez cela vous n’avez pas le choix c’est force (no prompt): on delete tout ou alors on n’efface rien si une erreur… donc pas trop de solution.

RMAN-S> delete archivelog all;

using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=17 device type=DISK
RMAN-08137: WARNING: archived log not deleted, needed for standby or upstream capture process
archived log file name=/oradata/TROLL/arch/1_15_820273293.dbf thread=1 sequence=15
RMAN-08137: WARNING: archived log not deleted, needed for standby or upstream capture process
archived log file name=/oradata/TROLL/arch/1_16_820273293.dbf thread=1 sequence=16
RMAN-08137: WARNING: archived log not deleted, needed for standby or upstream capture process
archived log file name=/oradata/TROLL/arch/1_17_820273293.dbf thread=1 sequence=17

Alors comment faire ?... mettre la FRA en place tout simplement !

 

Avec la FRA

Mettre en place la FRA, va permettre d’utiliser de nouvelles features… mais içi ce n’est que la gestion des archivelogs sur la standby qui nous intéresse.

Pour activer la FRA ce n’est que deux paramètres à setter, rien de plus. db_recovery_file_dest qui indique le chemin de l’espace de stockage de la FRA, et db_recovery_file_dest_size qui indique sa taille (sous-entendu à ne pas dépasser).

Nous settons donc la FRA sur la standby et la primaire. Nous settons volontairement des tailles différentes et en particulier une petite taille pour la standby pour mettre en pratique facilement ce que veut dire la gestion des archivelogs par la FRA dans notre « TP » :

SQL-S> alter system set DB_RECOVERY_FILE_DEST_SIZE=100m scope=both;
SQL-S> alter system set db_recovery_file_dest='/oradata/FRA/TROLL' scope=both;

SQL-P> alter system set DB_RECOVERY_FILE_DEST_SIZE=2000m scope=both;
SQL-P> alter system set db_recovery_file_dest='+FRA' scope=both;

A partir d’ici la FRA est active mais ce n’est pas fini pour ce que nous voulons faire.

Il faut maintenant que les archivelogs s’écrivent et s’enregistrent dans la FRA, il faut donc modifier le paramètre log_archive_dest_1 pour lui dire que nous voulons utilisez la FRA :

SQL-P> alter system set LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST' scope=both;

SQL-S> alter system set LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST' scope=both;

Quelques petits switch logfile, pour générer de l’archivelog et puis sur la primaire et la standby on vérifie l’écriture des archivelogs dans la FRA :

PRI> # avec le compte grid
PRI> export ORACLE_SID=+ASM1
PRI> asmcmd -p
ASMCMD [+] > cd +FRA/TROLL1/ARCHIVELOG/2013_07_14
ASMCMD [+FRA/TROLL1/ARCHIVELOG/2013_07_14] > ls -l
Type        Redund  Striped  Time             Sys  Name
ARCHIVELOG  UNPROT  COARSE   JUL 14 14:00:00  Y    thread_1_seq_20.322.820766653

STB> cd /oradata/FRA/TROLL/TROLL2/archivelog/2013_07_14
STB>  ls -l
total 4080
-rw-r-----. 1 oracle oinstall 3893760 Jul 14 14:40 o1_mf_1_18_8y572hmm_.arc
-rw-r-----. 1 oracle oinstall  180224 Jul 14 14:40 o1_mf_1_19_8y572kp2_.arc
-rw-r-----. 1 oracle oinstall  101888 Jul 14 14:44 o1_mf_1_20_8y578wpc_.arc

Sur la primaire et la stanby, Oracle a créé tout seul l’arborescence sous la racine de la FRA UNIQUE_NAME/ARCHIVELOG/YYYY_MM_DD

Important: C’est grâce à LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST' que les archivelogs sont considérés comme étant dans la FRA. Si vous mettez LOG_ARCHIVE_DEST_1='+FRA' (ou bien /oradata/FRA/TROLL) par exemple alors il s écriront bien dans la FRA mais ils ne seront pas considéré par Oracle comme étant dans la FRA et l’arborescence nommé ci-avant ne sera pas créé.

Bon ok, ok tout ça pour en venir où ?... à la gestion automatique du delete des archivelogs quand ils sont appliqués… ok ben alors testons…

SQL-P>create table TOTO (col1 number, col2 varchar2(200)) tablespace USERS;
SQL-P>insert into TOTO (col1, col2 ) values (1,'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
SQL-P>BEGIN
   FOR z IN 2..20 LOOP
      INSERT INTO TOTO select z,col2 from toto;
   COMMIT;
   END LOOP;
   COMMIT;
END;
/

Si nous contrôlons la synchro de la standby nous voyons qu’il y a un problème, et dans l’alert.log il y a :

Tue Jul 16 21:39:42 2013
Errors in file /oracle/oraBase/diag/rdbms/troll2/TROLL/trace/TROLL_rfs_2743.trc:
ORA-19815: WARNING: db_recovery_file_dest_size of 104857600 bytes is 100.00% used, and has 0 remaining bytes available.
************************************************************************
You have following choices to free up space from recovery area:
1. Consider changing RMAN RETENTION POLICY. If you are using Data Guard,
   then consider changing RMAN ARCHIVELOG DELETION POLICY.
2. Back up files to tertiary device such as tape using RMAN
   BACKUP RECOVERY AREA command.
3. Add disk space and increase db_recovery_file_dest_size parameter to
   reflect the new space.
4. Delete unnecessary files using RMAN DELETE command. If an operating
   system command was used to delete files, then use RMAN CROSSCHECK and
   DELETE EXPIRED commands.
************************************************************************
Creating archive destination file : /oradata/FRA/TROLL/TROLL2/archivelog/2013_07_16/o1_mf_1_25_%u_.arc (102400 blocks)

Ah ouai, super, nous mettons la FRA et au lieu de nous simplifier la vie, c’est tout le contraire ça «nous plante ». La FRA est pleine, 100Mo d’atteint avec les archivelog et tout se gèle côté standby… c’est fait exprès, j’ai volontairement omis un détail… mais en premier réglons notre problème

Si on fait un switch de logfile sur la primaire nous voyons que l’archivelog n’est pas transféré sur la standby car la FRA de la standby est pleine alors vidons la. Deux solutions :

RMAN-S>delete archivelog until sequence 23;

 ou bien

SQL-S> alter system set DB_RECOVERY_FILE_DEST_SIZE=200m scope=both;

Mais pas de rm des archivelog à la main!!! Après avoir fait de la place ou augmenté la taille de la FRA à 200Mo, les archivelogs en attente se transfèrent sur la standby.

Pour activer la suppression automatique des archivelog appliqué, il faut sous RMAN activé la DELETION POLICY TO APPLIED. Cela signifie que quand il n’y a plus de place et seulement quand il n’y a plus de place dans la FRA, Oracle supprimera les archivelogs appliqués. Activons cela :

RMAN-S> CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY; --- sur standby mais aussi sur primaire si on veut

Retestons un remplissage :

SQL-P>delete  toto;
SQL-P>commit;
SQL-P>insert into TOTO (col1, col2 ) values (1,'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
BEGIN
   FOR z IN 2..20 LOOP
      INSERT INTO TOTO select z,col2 from toto;
   COMMIT;
   END LOOP;
   COMMIT;
END;
/

Et maintenant si on regarde ce qui s’est passé, en analysant par exemple l’alert.log de la standby :

Tue Jul 16 21:59:07 2013
RFS[7]: Selected log 11 for thread 1 sequence 32 dbid -1882216704 branch 820273293
Tue Jul 16 21:59:07 2013
Media Recovery Waiting for thread 1 sequence 32 (in transit)
Recovery of Online Redo Log: Thread 1 Group 11 Seq 32 Reading mem 0
  Mem# 0: /oradata/TROLL/sby_redo01.log
Tue Jul 16 21:59:07 2013
Deleted Oracle managed file /oradata/FRA/TROLL/TROLL2/archivelog/2013_07_16/o1_mf_1_24_8yc8cxlk_.arc
Archived Log entry 29 added for thread 1 sequence 31 ID 0x8fdd1df5 dest 1:

Oracle a supprimé l’archivelog o1_mf_1_24_8yc8cxlk_.arc, car appliqué et FRA pleine. Et voilà fini de se tracasser pour la gestion des archivelogs sur la standby. Pas belle la vie Cool

 

Le broker

Le broker c’est quoi? … c’est une surcouche fournit par Oracle qui permet de manager « plus facilement » une dataguard. Il suffit de le configurer (le plus dur) puis après l’administration de la dataguard devient très simple : une commande suffit à faire un switch, une commande suffit à connaître l’état de la dataguard, une commande et le failover est fait, et même il peut être mis en mode automatique et déclencher un failover tout seul s’il détecte qu’il y a un problème sur la primaire. Sans aller jusqu’au mode automatique, il est vrai que sur la 11g cela fonctionne, je trouve, assez bien.

(Ici les commandes s’appliquent sur une 11gR2, pour les versions précédentes, je n’ai jamais pratiqué le broker, donc à vous de voir)

J’ai pu le mettre en place sur des environnements de production à 3 nœuds et franchement une fois mis en place, c’est un régal de simplicité d’utilisation. Bon finit le bavardage, action !

 

Pour commencer, il faut rajouter des entrées statiques dans les listener.ora. Effectivement le broker a besoin de pouvoir arrêter et démarrer une base à distance donc si la base est arrêtée, le listener dynamique ne va pas connaitre le service de base de données appelée puisque celle-ci est éteinte.

Donc dans notre cas, sur le serveur sans ASM, oradbm1 dans le fichier $ORACLE_HOME/network/admin/listener.ora du compte oracle, il faut rajouter les lignes suivantes :

STB> vi $ORACLE_HOME/network/admin/listener.ora

SID_LIST_LISTENER =
(SID_LIST =
  (SID_DESC =
  (GLOBAL_DBNAME = TROLL2)
   (ORACLE_HOME = /oracle/11.2.0.3/database)
   (SID_NAME = TROLL)
  )
)

Un petit redémarrage ou relod du listener et passons au serveur suivant.

Sur le serveur avec ASM, idem mais cette fois, c'est dans le listener.ora du compte grid.

PRI> vi $ORACLE_HOME/network/admin/listener.ora

SID_LIST_LISTENER =
(SID_LIST =
  (SID_DESC =
  (GLOBAL_DBNAME = TROLL1)
   (ORACLE_HOME = /oracle/11.2.0.3/database)
   (SID_NAME = TROLL)
  )
)

Un petit arrêt redémarrage

PRI> srvctl stop listener
PRI> srvctl start listener

Ensuite il faut mettre dans les tnsname.ora des comptes oracle, les chemins vers TROLL1 et TROLL2, cela a déjà était fait précédemment dans le paragraphe «création de la dataguard », mais ici il est conseillé de fusionner les fichiers pour que chaque serveur connaissent TROLL1 et TROLL2 sur le réseau soit :

TROLL1 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = racdb1.localdomain)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = TROLL1)
    )
  )
TROLL2 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = oradbm1.localdomain)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = TROLL2)
    )
  )

Voilà les préparatifs sont finit, démarrons le broker. Pour cela sur chaque instance :

SQL-P>alter system set dg_broker_start=TRUE scope=both;

Et

SQL-S> alter system set dg_broker_start=TRUE scope=both;

Le broker vient de démarrer sur les 2 serveurs (process dmon) et il démarrera à chaque démarrage des bases. Il a démarré mais il n’est pas configuré, pour l’instant il ne fait rien. Pour information les logs du broker se trouve dans le background_dump_dest, et ce nomme drc<ORACLE_SID>.log, soit dans notre cas : drcTROLL.log dans le répertoire /oracle/oraBase/diag/rdbms/troll1/TROLL/trace.

 

Configurons ce broker. Pour cela, nous utilisons l’outil (en ligne de commande) : dgmgrl.

PRI> export ORACLE_SID=TROLL
PRI> dgmgrl
Connected.

DGMGRL> create configuration TROLL as primary database is TROLL1 connect identifier is TROLL1;
Configuration "troll" created with primary database "troll1"

DGMGRL> add database TROLL2 as connect identifier is TROLL2 maintained as physical;
Database "troll2" added

DGMGRL> enable configuration;
Enabled.

Et voilà c’est fini. Le broker est configuré. Facile. Voyons voir comment vérifier que la dataguard fonctionne bien et comment la datguard est configurée à travers le broker.

Une petite configuration à faire, à mon avis rapidement dans la foulé, mettre à jour la propriété StaticConnectIdentifier avec les alias que nous avons mis dans le tnsname.ora. Ce paramètre est à priori nouveau en 11.2, il sert au start et shut des instances.

dgmgrl-P> edit database troll1 set property StaticConnectIdentifier='TROLL1';
dgmgrl-P> edit database troll2 set property StaticConnectIdentifier='TROLL2';

Première commande à connaitre : « show configuration ». Comme toutes les commandes broker elle peut être exécutée indifféremment sur n’importe quel nœud.

DGMGRL> show configuration;

Configuration - troll

  Protection Mode: MaxPerformance
  Databases:
    troll1 - Primary database
    troll2 - Physical standby database

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

Le résultat de la commande ci-dessus, nous  informe que la dataguard est en MaxPerformance, que la primaire est TROLL1, et que tout va bien : SUCESS par rapport à la configuration, c'est-à-dire ici la dataguard est dans l’état attendue.

Si nous voulons en savoir un peu plus, nous pouvons faire :

DGMGRL> show database troll2;

Database - troll2

  Role:            PHYSICAL STANDBY
  Intended State:  APPLY-ON
  Transport Lag:   0 seconds
  Apply Lag:       0 seconds
  Real Time Query: ON

  Instance(s):
    TROLL

Database Status:
SUCCESS

La commande nous apprend que TROLL2 est un Standby, que le process d’apply (MRP) est actif, il applique les logs qui arrivent, pas de lag de transport et d’apply… le bonheur Cool

DGMGRL> show database troll1;

Database - troll1

  Role:            PRIMARY
  Intended State:  TRANSPORT-ON

  Instance(s):
    TROLL

Database Status:
SUCCESS

Ici nous apprenons TROLL1 est la primaire, et l’envoie des redolog/archivelog est actif.

Et si nous voulons tous les détails, il faut rajouter « verbose », ci-dessous un extrait du résultat de la commande

DGMGRL> show database verbose troll1

Database - troll1

  Role:            PRIMARY
  Intended State:  TRANSPORT-ON

  Instance(s):
    TROLL

  Properties:
    DGConnectIdentifier             = 'troll1'
    ObserverConnectIdentifier       = ''
    LogXptMode                      = 'ASYNC'
    DelayMins                       = '0'
    Binding                         = 'optional'
    MaxFailure                      = '0'
    MaxConnections                  = '1'
    ReopenSecs                      = '300'
    NetTimeout                      = '30'
    RedoCompression                 = 'DISABLE'
    LogShipping                     = 'ON'
[…]
    TopWaitEvents                   = '(monitor)'

Database Status:
SUCCESS

Le verbose permet de visualiser tout le paramétrage. Nous voyons entre autre que TROLL1 est en ASYNC pour le LogXptMode, alors que si nous faisons la même commande pour TROLL2 nous verrions SYNC. Cela explique que nous sommes en MaxPerformance (résutlat de show configuration).

Petit exemple de changement de configuration, passons de MaxPerforance à MaxAvailability:

DGMGRL> EDIT DATABASE troll1 SET property LogXptMode='SYNC';
edit configuration set protection mode as maxavailability;

DGMGRL> show configuration
Configuration - troll

  Protection Mode: MaxAvailability
  Databases:
    troll1 - Primary database
    troll2 - Physical standby database

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

Passons maintenant au plus intéressant, au clou du spectacle,Mesdames Messieur: le switchover en une seule commande composée de 3 mots :

STB> dgmgrl
DGMGRL> connect sys/oracle

DGMGRL> switchover to troll2
Performing switchover NOW, please wait...
New primary database "troll2" is opening...
Operation requires shutdown of instance "TROLL" on database "troll1"
Shutting down instance "TROLL"...
ORACLE instance shut down.
Operation requires startup of instance "TROLL" on database "troll1"
Starting instance "TROLL"...
ORACLE instance started.
Database mounted.
Database opened.
Switchover succeeded, new primary is "troll2"

Vérifions:

DGMGRL> show configuration
Configuration - troll

  Protection Mode: MaxAvailability
  Databases:
    troll2 - Primary database
    troll1 - Physical standby database

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

Comme vous pouvez le constater c’est simple, il n’y a pas de vérification à faire, à exécuter des commandes sur les deux instances, le broker fait tout pour vous et ne switchera pas si la synchro n’était pas correct.

Remarque : nous avons passé le mot de passe dans la commande connect (connect sys/oracle au lieu de connect /) sinon sans cela le switchover se fait mais il faut finir un redémarrage d’une instance à la main.

 

Et le failover ?

Pour le failover c’est pareil, une seul commande « failover to troll2 ». Mais ensuite la base anciennement primaire est perdue, il faut la reconstruire avec un nouveau backup. Rien de nouveau à ce niveau là… mais il existe une solution pour ne pas à avoir à recréer la base et en plus avec une seul commande à taper !!!!... grâce aux flashbacks

 

L'apport des flashback logs

Les flashbacks permettent de revenir sur la base dans un état antérieur sans à avoir à faire une restauration, ce serait plutôt un recover à l’envers. Ils ne sont donc en rien liés à la technologie dataguard. L’astuce de se servir des flashbacks après un failover, est de pouvoir revenir sur l’ancienne base primaire (que l’on avait perdu) au SCN juste d’avant le failover, puis de rejouer les archivelog/redolog qui ont été générés sur la nouvelle primaire juste après le failover. Cela va donc éviter de devoir recréer la base perdue. Sur une grosse volumétrie ce n’est pas négligeable.

Il n’y a pas besoin d’avoir le broker pour faire cela, mais le broker va simplifier les opérations. Les actions manuelles ne seront pas décrites ici (peut être dans un prochain article technique). Nous allons faire les feignants et le faire avec le broker Tongue Out

Commençons à mettre les flashbacks en place. Il faut fixer un temps de rétention en minutes et dire à la base qu’elle passe en flashback et aussi initialiser une FRA (Flash Recovery Area) mais cela a déjà été fait précédemment. Les flaskback vont s’écrire alors dans la FRA.

Donc sur les 2 bases :

SQL> alter system set db_flashback_retention_target=1440 scope=both;

Puis sur la base primaire:

SQL-S> alter database flashback on;

(Remarque : SQL-S car notre dataguard se trouve actuellement sur oradbm1)

Pour la base standby, il faut arrêter le process de recovery avant le "alter database". Comme quand on utilise le broker, il est conseillé de modifier le paramétrage avec dgmgrl, alors :

DGMGRL-P> connect /
DGMGRL-P>  EDIT DATABASE troll1 SET STATE="APPLY-OFF";
DGMGRL-P> sql "alter database flashback on";
DGMGRL-P>  EDIT DATABASE troll1 SET STATE="APPLY-ON";

Simulons une perte de la base primaire, euh …un kill du pmon et down de l’interface réseau…. Parfait ! la panique à bord… la prod ne répond plus, la prod ne répond plus… il faut que cela reparte de suite, on nous a vendu un DRS, faites le fonctionne!!!!!

Le failover est obligatoire... c'est l'hystérie ici, pas le temps d’analyser si c’est juste un câble réseau débranché par le femme de ménage.

DGMGRL-P> show configuration
Configuration - troll

  Protection Mode: MaxAvailability
  Databases:
    troll2 - Primary database
    troll1 - Physical standby database

Fast-Start Failover: DISABLED

Configuration Status:
ORA-12543: TNS:destination host unreachable
ORA-16625: cannot reach database "troll2"
DGM-17017: unable to determine configuration status

DGMGRL-P> failover to troll1
Performing failover NOW, please wait...
Failover succeeded, new primary is "troll1"

Voilà TROLL1 est devenu la primaire… la production repart… ouf.

Et grâce aux flashbacks et au broker, le DBA sait que la remise en place de TROLL2 en standby  ne va pas lui coûter beaucoup d’effort. Une commande va lui suffire : reinstate.

A partir du site de la base primaire (TROLL1 ici), se connecter sous dgmgrl.

DGMGRL-P> show configuration
Configuration - troll

  Protection Mode: MaxAvailability
  Databases:
    troll1 - Primary database
      Warning: ORA-16629: database reports a different protection level from the protection mode
    troll2 - Physical standby database (disabled)
      ORA-16661: the standby database needs to be reinstated

Fast-Start Failover: DISABLED

Configuration Status:
WARNING

DGMGRL-P> connect sys/oracle@troll2
DGMGRL-P > startup mount
DGMGRL-P > connect sys/oracle
DGMGRL-P >  reinstate database troll2;
Reinstating database "troll2", please wait...
Reinstatement of database "troll2" succeeded

Remarque : il faut se connecter avec compte et mot de passe, pas de "connect /"

Remarque 2 : reinstate doit être faite à partir du site de la base primaire.

Remarque 3 : pour simplifier les explications le mount a été fait sous dgmgrl du site primaire mais rien n’empêche de le faire sur l’autre site et sous sqlplus.

Une dernière petite vérif :

DGMGRL-P> show configuration
Configuration - troll

  Protection Mode: MaxAvailability
  Databases:
    troll1 - Primary database
    troll2 - Physical standby database

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

Le DBA n'a plus rien à faire... à part faire joujou avec les smileys CoolLaughingSmileTongue Out...Wink

 {jcomments on}