Après quelques temps d’inactivité, j’ai décidé de faire une série d’articles sur la technologie Oracle Dataguard 11G, afin de présenter les principales caractéristiques et la mise en place de ce mode de disponibilité.
Dans ces articles, nous verrons (dans l’ordre) :
Oracle Dataguard 11G Part #1 : Mise en place d’un Physical Dataguard
Oracle Dataguard 11G Part #2 : Comment changer le mode de protection de Dataguard ?
Oracle Dataguard 11G Part #3 : Gestion et supervision : Oracle Dataguard BROKER
Oracle Dataguard 11G Part #4 : Mise en place d’ACTIVE DATAGUARD
Oracle Dataguard 11G Part #5 : Mise en place d’un LOGICAL DATAGUARD
Oracle Dataguard 11G Part #6 : Restauration Rman d’une base Primaire : Les impacts
Bon, mais qu’est ce qu’un environnement DATAGUARD et à quoi cela peut il servir ?
Et bien c’est assez simple en fait. Un environnement Oracle DATAGUARD est un environnement pourvu d’une base de données dite principale (ou primary pour les intimes), et d’une base de secours sur un autre serveur (idéalement un autre datacenter / site) alimentée en temps rêel à partir des archivelogs de la base principale. Le mécanisme est entièrement automatique, y compris sa supervision.
Globalement, dans la plupart des cas de configuration, cette base de données de secours (standby pour les intimes) pourra être activée dès lors où la base de données principale ne sera plus opérationnelle, ou accessible. On nomme cela un PHYSICAL DATAGUARD. Cela permet d’avoir une continuité des opérations, qui seront redigirées vers le serveur et donc la base dite de secours / Standby.
Dans d’autres cas, plus rares de part mon expérience, cette base de données de secours pourra également être utilisée en parallèle de la base de données principale à des fins de tests, de récupération d’informations, de réglages ou autres. On nomme cela un LOGICAL DATAGUARD. Dans cette configuration, et à la différence de l’autre configuration PHYSICAL, cette base de secours est OPEN, alors que dans l’autre mode, elle serait uniquement MOUNTED en mode STANDBY (pour permettre l’application des archivelogs).
Vous l’avez compris, dans tous les cas, nous avons la notion d’archivelogs, lequels permettent d’alimenter la base de secours, qu’elle soit dans un mode PHYSICAL ou LOGICAL. Sans ce mode archivelog, il faut oublier tout mécanisme de disponibilité DATAGUARD, ou encore MANUAL Stanby
Pour la différence entre un environnement de secours DATAGUARD et MANUAL Standby, c’est simple également car d’un coté tout est géré par la mécanique dataguard Oracle (envoi d’archivelogs, application sur la base de secours, supervision via DGMGMRL) et de l’autre tout est à faire manuellement via pack de scripts OS / SQL.
Le petit plus de Dataguard, c’est du temps reel, alors qu’avec une configuration « Manual standby », cela sera lié à la planification qui sera mise en place pour l’envoie des archivelogs et leur application sur la base de secours.
D’un coté, une base de secours sera activée avec la dernière transaction datant d’avant panne / crash, de l’autre la base de secours sera activée avec une dernière transaction datant de la dernière application des archivelogs. Nous ne sommes donc pas, en mode Manual standby, en temps reel.
Evidemment, comme toute fonctionnalité « non défaut », Dataguard nécessite un licensing spécifique. Le fonctionnement DATAGUARD n’est disponible qu’en ENTERPRISE EDITION, et est une option supplémentaire payante.
Bon, passons maintenant à la partie technique. Je vais ici détailler la mise en place d’un PHYSICAL DATAGUARD
Le contexte technique, sur lequel je me base pour démarrer ce tuto, est le suivant :
- 2 serveurs (VM) Oracle Linux 6 installés et configurés (accès réseau et autres), disposant de 60Go d’espace chacun (à adapter en fonction du contexte d’étude)
- Moteurs oracle 11GR2 enterprise edition installés sur les deux serveurs
- Base de données « primaire » UP sur le premier serveur, en mode Archivelog, nommée ici « MICKPRIM »
- Listener Oracle UP sur les deux serveurs, en configuration statique :
Exemple pour le serveur « primaire » :
SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (ORACLE_HOME = /oracle/product/11.2.0.4) (SID_NAME = MICKPRIM) ) ) LISTENER = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = srvoraprim)(PORT = 1521)) ) ADR_BASE_LISTENER = /oracle
Exemple pour le serveur « secondaire / secours »
SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (ORACLE_HOME = /oracle/product/11.2.0.4) (SID_NAME = MICKSTBY) ) ) LISTENER = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = srvorastby)(PORT = 1521)) ) ADR_BASE_LISTENER = /oracle
Mais avant de démarrer d’emblée les actions, que représente un PHYSICAL DATAGUARD ?
Un Physical dataguard se base sur une base de données Standby (de secours) dont la structure est identique à la base de données Primary (principale).
Les archivelogs générées par la base primary seront directement appliquées sur la base standby.
Cette solution technique est couramment choisie. Elle permet notamment d’assurer une protection maximale en cas de crash de la base primaire.
Pour construire la base de secours « STANDBY », nous pourrons donc utiliser aisément notre ami RMAN, qui permet de réaliser (depuis la version 9i) un duplicate for standby, et plus particulièrement en 11G un duplicate for standby from active database.
Et oui, en 11g, grosse nouveauté (qui date un peu maintenant..) puisque nous pouvons construire une standby database à partir d’une base de données directement, au lieu d’utiliser un dernier backup rman (versions antérieures).
Je ne parlerais pas des versions 8i sur lesquelles j’ai eu à mettre en place un Physical dataguard dans une vie passée, c’était quelque peu moins efficace et rapide, et demandait pas mal de code et d’actions, mais le principe de fonctionnement et paramétrage reste globalement le même.
Mais avant la création de cette instance STANDBY, il faut préparer le terrain sur la base de données PRIMARY.
Première étape, très importante et obligatoire à toute configuration Standby, on s’assure que la base primary soit bien en force logging (ce qui sous entend de forcer la génération d’archivelog, même s’il y a des objets en Nologging)
SQL> select NAME,LOG_MODE,OPEN_MODE,DATABASE_ROLE,FORCE_LOGGING,DATAGUARD_BROKER,GUARD_STATUS,PROTECTION_MODE from v$database; NAME LOG_MODE OPEN_MODE DATABASE_ROLE FOR DATAGUAR GUARD_S PROTECTION_MODE --------- ------------ -------------------- ---------------- --- -------- ------- -------------------- MICKPRIM ARCHIVELOG READ WRITE PRIMARY NO DISABLED NONE MAXIMUM PERFORMANCE
=> Activation du Force Logging :
SQL> shutdown immediate ; Database closed. Database dismounted. ORACLE instance shut down. SQL> startup mount ; ORACLE instance started. Total System Global Area 1068937216 bytes Fixed Size 2260088 bytes Variable Size 671089544 bytes Database Buffers 390070272 bytes Redo Buffers 5517312 bytes Database mounted. SQL> alter database force logging ; Database altered. SQL> alter database open; Database altered. SQL> select NAME,LOG_MODE,OPEN_MODE,DATABASE_ROLE,FORCE_LOGGING,DATAGUARD_BROKER,GUARD_STATUS,PROTECTION_MODE from v$database; NAME LOG_MODE OPEN_MODE DATABASE_ROLE FOR DATAGUAR GUARD_S PROTECTION_MODE --------- ------------ -------------------- ---------------- --- -------- ------- -------------------- MICKPRIM ARCHIVELOG READ WRITE PRIMARY YES DISABLED NONE MAXIMUM PERFORMANCE SQL> select force_logging from v$database; FORCE_LOGGING --- YES
Ensuite, on vérifie que la base utilise bien un fichier de mot de passe et que le paramètre « REMOTE_LOGIN_PASSWORDFILE » soit bien à « EXCLUSIVE » :
SQL>show parameter remote_login_passwordfile NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ remote_login_passwordfile string EXCLUSIVE [oracle@srvoraprim dbs]$ ls -l orapw* -rw-r-----. 1 oracle dba 1536 Nov 7 10:46 orapwMICKPRIM
On vérifie le db_name et db_unique_name de notre base :
SQL> sho parameter _name NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_name string MICKPRIM db_unique_name string MICKPRIM
Dans mon cas, les 2 paramètres sont identiques. Sur la base Standby, le DB_NAME sera le même que la base primaire (ie MICKPRIM), mais la valeur de db_unique_name devra être différente (MICKSTBY).
De plus, la valeur de ce paramètre db_unique_name devra être indiquée dans la configuration dataguard « DG_CONFIG », pour les 2 bases. (cf plus bas où la configuration est indiquée).
On prépare maintenant les alias TNS qui seront utilisés aussi bien par RMAN (pour la mise en place de la database en Standby) que pour la fonctionnalité Dataguard.
Exemple :
MICKPRIM = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = srvoraprim)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = MICKPRIM)(UR=A) ) ) MICKSTBY = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = srvorastby)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = MICKSTBY)(UR=A) ) )
Bien sur, ce tnsnames devra être en place sur les 2 serveurs.
On vérifie ensuite que le TNSPING fonctionne bien entre les serveurs. Si cela ne passe pas, vérifier votre firewall et le service « iptables » (« service iptables status » à lancer en ROOT)
-> Sur le serveur dit primaire :
[oracle@srvoraprim ~]$ tnsping MICKSTBY TNS Ping Utility for Linux: Version 11.2.0.4.0 - Production on 07-NOV-2016 14:49:40 Copyright (c) 1997, 2013, Oracle. All rights reserved. Used parameter files: Used TNSNAMES adapter to resolve the alias Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = srvorastby)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = MICKSTBY)(UR=A))) OK (30 msec)
-> Sur le serveur secondaire
[oracle@srvorastby ~]$ tnsping MICKPRIM TNS Ping Utility for Linux: Version 11.2.0.4.0 - Production on 07-NOV-2016 14:49:52 Copyright (c) 1997, 2013, Oracle. All rights reserved. Used parameter files: Used TNSNAMES adapter to resolve the alias Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = srvoraprim)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = MICKPRIM)(UR=A))) OK (0 msec)
On passe maintenant à la configuration de Dataguard en lui même, sur l’instance Oracle PRIMAIRE.
Déjà, on sauvegarde le fichier de paramètre actuellement utilisé au cas où, puis on ajoute les paramètres liés à Dataguard qui sont :
LOG_ARCHIVE_CONFIG='DG_CONFIG=(MICKPRIM,MICKSTBY)' LOG_ARCHIVE_DEST_1='location=/oradata/MICKPRIM/arch valid_for=(all_logfiles,all_roles) db_unique_name=MICKPRIM' LOG_ARCHIVE_DEST_2='SERVICE=MICKSTBY NOAFFIRM ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=MICKSTBY' LOG_ARCHIVE_DEST_STATE_2=ENABLE LOG_ARCHIVE_MAX_PROCESSES=30 FAL_SERVER=MICKSTBY FAL_CLIENT=MICKPRIM STANDBY_FILE_MANAGEMENT=AUTO
Les 2 paramètres FAL_SERVER et FAL_CLIENT, configurés sur les 2 instances, serviront à réaliser des switchovers entre les bases (la base primaire devient standby, et vice versa).
Le paramètre STANDBY_FILE_MANAGEMENT quant à lui permet la gestion automatique des fichiers de base de données (datafiles). Autrement dit, si un datafile est crée / ajouté sur la base primaire, il sera automatiquement crée / ajouté sur l’instance standby.
Attention, ce paramètre ne peut être positionné en AUTO que lors d’une configuration DATAGUARD en tant que tel (donc enterprise edition + option..)
En ce qui concerne les 2 paramètres FAL_SERVER & FAL_CLIENT, iI n’est pas obligatoire de les indiquer pour le fonctionnement de dataguard, mais je le préconise cependant, le switchover pouvant s’avérer très utile en production.
Ce qui donne dans mon cas d’exmple:
*.audit_file_dest='/oracle/admin/MICKPRIM/adump' *.audit_trail='db' *.compatible='11.2.0.4.0' *.control_files='/oradata/MICKPRIM/control01.ctl','/oradata/MICKPRIM/control02.ctl' *.db_block_size=8192 *.db_domain='' *.db_name='MICKPRIM' *.diagnostic_dest='/oracle' *.dispatchers='(PROTOCOL=TCP) (SERVICE=MICKPRIMXDB)' *.LOG_ARCHIVE_CONFIG='DG_CONFIG=(MICKPRIM,MICKSTBY)' *.LOG_ARCHIVE_DEST_1='location=/oradata/MICKPRIM/arch valid_for=(all_logfiles,all_roles) db_unique_name=MICKPRIM' *.LOG_ARCHIVE_DEST_2='SERVICE=MICKSTBY NOAFFIRM ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=MICKSTBY' *.LOG_ARCHIVE_DEST_STATE_2=ENABLE *.LOG_ARCHIVE_MAX_PROCESSES=30 *.FAL_SERVER=MICKSTBY *.FAL_CLIENT=MICKPRIM *.STANDBY_FILE_MANAGEMENT=AUTO *.log_archive_format='%t_%s_%r.arc' *.memory_target=1073741824 *.open_cursors=300 *.processes=150 *.remote_login_passwordfile='EXCLUSIVE' *.undo_tablespace='UNDOTBS1'
Une fois cette partie de configuration terminée, nous allons passer à la mise en place de la base Standby nommée MICKSTBY, via RMAN.
Pour cela, copier tout d’abord le fichier de mot de passe « orapw » sur le serveur de secours.
[oracle@srvoraprim dbs]$ scp orapwMICKPRIM oracle@srvorastby:/oracle/product/11.2.0.4/dbs/orapwMICKSTBY orapwMICKSTBY 100% 1536 1.5KB/s 00:00
Se connecter sur le serveur de secours, et creer ensuite un fichier d’initialisation oracle init.ora pour la base standby, contenant uniquement le nom de la base :
[oracle@srvorastby dbs]$ echo "db_name=MICKSTBY" > $ORACLE_HOME/dbs/initMICKSTBY.ora
Par la suite, il est désormais possible de démarrer l’instance oracle avant la duplication RMAN.
=> Notez bien que je vais gérer via RMAN les modifications liées au SPFILE.
[oracle@srvorastby ~]$ rman Recovery Manager: Release 11.2.0.4.0 - Production on Mon Nov 7 14:52:47 2016 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. RMAN> connect target sys/oracle@MICKPRIM connected to target database: MICKPRIM (DBID=2500540110) RMAN> connect auxiliary sys/oracle@MICKSTBY connected to auxiliary database (not started) RMAN> startup clone nomount ; RMAN>run { allocate channel c1 device type disk; allocate auxiliary channel c2 device type disk; duplicate target database for standby from active database SPFILE set audit_file_dest='/oracle/admin/MICKSTBY/adump' set control_files='/oradata/MICKSTBY/control01.ctl' set fal_server='MICKPRIM' set fal_client='MICKSTBY' set standby_file_management='AUTO' set db_file_name_convert='/oradata/MICKPRIM','/oradata/MICKSTBY' set log_file_name_convert='/oradata/MICKPRIM','/oradata/MICKSTBY' set log_archive_dest_1='location=/oradata/MICKSTBY/arch valid_for=(all_logfiles,all_roles) db_unique_name=MICKSTBY' set log_archive_dest_2='service=MICKPRIM valid_for=(online_logfiles,primary_role) db_unique_name=MICKPRIM' set log_archive_dest_state_1='enable' set log_archive_dest_state_2='defer' set db_unique_name='MICKSTBY'; } using target database control file instead of recovery catalog allocated channel: c1 channel c1: SID=46 device type=DISK allocated channel: c2 channel c2: SID=171 device type=DISK Starting Duplicate Db at 08-NOV-16 contents of Memory Script: { backup as copy reuse targetfile '/oracle/product/11.2.0.4/dbs/orapwMICKPRIM' auxiliary format '/oracle/product/11.2.0.4/dbs/orapwMICKSTBY' targetfile '/oracle/product/11.2.0.4/dbs/spfileMICKPRIM.ora' auxiliary format '/oracle/product/11.2.0.4/dbs/spfileMICKSTBY.ora' ; sql clone "alter system set spfile= ''/oracle/product/11.2.0.4/dbs/spfileMICKSTBY.ora''"; } executing Memory Script Starting backup at 08-NOV-16 Finished backup at 08-NOV-16 sql statement: alter system set spfile= ''/oracle/product/11.2.0.4/dbs/spfileMICKSTBY.ora'' contents of Memory Script: { sql clone "alter system set audit_file_dest = ''/oracle/admin/MICKSTBY/adump'' comment= '''' scope=spfile"; sql clone "alter system set control_files = ''/oradata/MICKSTBY/control01.ctl'' comment= '''' scope=spfile"; sql clone "alter system set fal_server = ''MICKPRIM'' comment= '''' scope=spfile"; sql clone "alter system set fal_client = ''MICKSTBY'' comment= '''' scope=spfile"; sql clone "alter system set standby_file_management = ''AUTO'' comment= '''' scope=spfile"; sql clone "alter system set db_file_name_convert = ''/oradata/MICKPRIM'', ''/oradata/MICKSTBY'' comment= '''' scope=spfile"; sql clone "alter system set log_file_name_convert = ''/oradata/MICKPRIM'', ''/oradata/MICKSTBY'' comment= '''' scope=spfile"; sql clone "alter system set log_archive_dest_1 = ''location=/oradata/MICKSTBY/arch valid_for=(all_logfiles,all_roles) db_unique_name=MICKSTBY'' comment= '''' scope=spfile"; sql clone "alter system set log_archive_dest_2 = ''service=MICKPRIM valid_for=(online_logfiles,primary_role) db_unique_name=MICKPRIM'' comment= '''' scope=spfile"; sql clone "alter system set log_archive_dest_state_1 = ''enable'' comment= '''' scope=spfile"; sql clone "alter system set log_archive_dest_state_2 = ''defer'' comment= '''' scope=spfile"; sql clone "alter system set db_unique_name = ''MICKSTBY'' comment= '''' scope=spfile"; shutdown clone immediate; startup clone nomount; } executing Memory Script sql statement: alter system set audit_file_dest = ''/oracle/admin/MICKSTBY/adump'' comment= '''' scope=spfile sql statement: alter system set control_files = ''/oradata/MICKSTBY/control01.ctl'' comment= '''' scope=spfile sql statement: alter system set fal_server = ''MICKPRIM'' comment= '''' scope=spfile sql statement: alter system set fal_client = ''MICKSTBY'' comment= '''' scope=spfile sql statement: alter system set standby_file_management = ''AUTO'' comment= '''' scope=spfile sql statement: alter system set db_file_name_convert = ''/oradata/MICKPRIM'', ''/oradata/MICKSTBY'' comment= '''' scope=spfile sql statement: alter system set log_file_name_convert = ''/oradata/MICKPRIM'', ''/oradata/MICKSTBY'' comment= '''' scope=spfile sql statement: alter system set log_archive_dest_1 = ''location=/oradata/MICKSTBY/arch valid_for=(all_logfiles,all_roles) db_unique_name=MICKSTBY'' comment= '''' scope=spfile sql statement: alter system set log_archive_dest_2 = ''service=MICKPRIM valid_for=(online_logfiles,primary_role) db_unique_name=MICKPRIM'' comment= '''' scope=spfile sql statement: alter system set log_archive_dest_state_1 = ''enable'' comment= '''' scope=spfile sql statement: alter system set log_archive_dest_state_2 = ''defer'' comment= '''' scope=spfile sql statement: alter system set db_unique_name = ''MICKSTBY'' comment= '''' scope=spfile Oracle instance shut down connected to auxiliary database (not started) Oracle instance started Total System Global Area 1068937216 bytes Fixed Size 2260088 bytes Variable Size 671089544 bytes Database Buffers 390070272 bytes Redo Buffers 5517312 bytes allocated channel: c2 channel c2: SID=133 device type=DISK contents of Memory Script: { backup as copy current controlfile for standby auxiliary format '/oradata/MICKSTBY/control01.ctl'; } executing Memory Script Starting backup at 08-NOV-16 channel c1: starting datafile copy copying standby control file output file name=/oracle/product/11.2.0.4/dbs/snapcf_MICKPRIM.f tag=TAG20161108T172056 RECID=3 STAMP=927393657 channel c1: datafile copy complete, elapsed time: 00:00:03 Finished backup at 08-NOV-16 contents of Memory Script: { sql clone 'alter database mount standby database'; } executing Memory Script sql statement: alter database mount standby database contents of Memory Script: { set newname for tempfile 1 to "/oradata/MICKSTBY/temp01.dbf"; switch clone tempfile all; set newname for datafile 1 to "/oradata/MICKSTBY/system01.dbf"; set newname for datafile 2 to "/oradata/MICKSTBY/sysaux01.dbf"; set newname for datafile 3 to "/oradata/MICKSTBY/undotbs01.dbf"; set newname for datafile 4 to "/oradata/MICKSTBY/users01.dbf"; backup as copy reuse datafile 1 auxiliary format "/oradata/MICKSTBY/system01.dbf" datafile 2 auxiliary format "/oradata/MICKSTBY/sysaux01.dbf" datafile 3 auxiliary format "/oradata/MICKSTBY/undotbs01.dbf" datafile 4 auxiliary format "/oradata/MICKSTBY/users01.dbf" ; sql 'alter system archive log current'; } executing Memory Script executing command: SET NEWNAME renamed tempfile 1 to /oradata/MICKSTBY/temp01.dbf in control file executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME executing command: SET NEWNAME Starting backup at 08-NOV-16 channel c1: starting datafile copy input datafile file number=00001 name=/oradata/MICKPRIM/system01.dbf output file name=/oradata/MICKSTBY/system01.dbf tag=TAG20161108T172106 channel c1: datafile copy complete, elapsed time: 00:00:55 channel c1: starting datafile copy input datafile file number=00002 name=/oradata/MICKPRIM/sysaux01.dbf output file name=/oradata/MICKSTBY/sysaux01.dbf tag=TAG20161108T172106 channel c1: datafile copy complete, elapsed time: 00:00:35 channel c1: starting datafile copy input datafile file number=00003 name=/oradata/MICKPRIM/undotbs01.dbf output file name=/oradata/MICKSTBY/undotbs01.dbf tag=TAG20161108T172106 channel c1: datafile copy complete, elapsed time: 00:00:15 channel c1: starting datafile copy input datafile file number=00004 name=/oradata/MICKPRIM/users01.dbf output file name=/oradata/MICKSTBY/users01.dbf tag=TAG20161108T172106 channel c1: datafile copy complete, elapsed time: 00:00:01 Finished backup at 08-NOV-16 sql statement: alter system archive log current contents of Memory Script: { switch clone datafile all; } executing Memory Script datafile 1 switched to datafile copy input datafile copy RECID=3 STAMP=927393773 file name=/oradata/MICKSTBY/system01.dbf datafile 2 switched to datafile copy input datafile copy RECID=4 STAMP=927393773 file name=/oradata/MICKSTBY/sysaux01.dbf datafile 3 switched to datafile copy input datafile copy RECID=5 STAMP=927393773 file name=/oradata/MICKSTBY/undotbs01.dbf datafile 4 switched to datafile copy input datafile copy RECID=6 STAMP=927393773 file name=/oradata/MICKSTBY/users01.dbf Finished Duplicate Db at 08-NOV-16 released channel: c1 released channel: c2
Et voila, nous avons notre base de secours en mode STANDBY sur notre serveur. Vérifions donc la configuration de la base pour activer le mode DATAGUARD et de facto la synchronisation automatique via l’application des archivelogs.
Sur le serveur et base PRIMAIRE, on vérifie la base et on récupère le dernier numéro de séquence d’archivelog généré :
SQL> select status,instance_name,database_role from v$database,v$instance; STATUS INSTANCE_NAME DATABASE_ROLE ------------ ---------------- ---------------- OPEN MICKPRIM PRIMARY SQL> select max(sequence#) from v$archived_log; MAX(SEQUENCE#) -------------- 28
On fait la même vérification sur la standby :
SQL> select status,instance_name,database_role from v$database,v$instance; STATUS INSTANCE_NAME DATABASE_ROLE ------------ ---------------- ---------------- MOUNTED MICKSTBY PHYSICAL STANDBY SQL> select max(sequence#) from v$archived_log where applied='YES'; MAX(SEQUENCE#) -------------- 28
Nous avons donc les 2 bases au même niveau de séquence. Essayons voir si des archivelogs de la base primaire seraient automatiquement appliquées sur la base Standby :
Sur la base primary :
SQL> select status,instance_name,database_role from v$database,v$instance; STATUS INSTANCE_NAME DATABASE_ROLE ------------ ---------------- ---------------- OPEN MICKPRIM PRIMARY SQL> alter system switch logfile ; System altered. SQL> / System altered. SQL> / System altered. ... ... ... SQL> / System altered. SQL> select max(sequence#) from v$archived_log; MAX(SEQUENCE#) -------------- 36
On vérifie directement sur la base Standby, sans aucune autre action, en vérifiant tout d’abord si le transfert des archivelogs c’est bien fait entre les 2 machines :
[oracle@srvorastby arch]$ ls -ltr /oradata/MICKSTBY/arch total 112708 -rw-r-----. 1 oracle dba 169984 Nov 28 09:44 1_34_928484905.arc -rw-r-----. 1 oracle dba 22016 Nov 28 09:44 1_35_928484905.arc -rw-r-----. 1 oracle dba 28672 Nov 28 09:44 1_33_928484905.arc -rw-r-----. 1 oracle dba 6958592 Nov 28 09:44 1_29_928484905.arc -rw-r-----. 1 oracle dba 6540800 Nov 28 09:44 1_30_928484905.arc -rw-r-----. 1 oracle dba 19219968 Nov 28 09:44 1_32_928484905.arc -rw-r-----. 1 oracle dba 41263616 Nov 28 09:44 1_31_928484905.arc -rw-r-----. 1 oracle dba 19968 Nov 28 09:44 1_36_928484905.arc -rw-r-----. 1 oracle dba 52429312 Nov 28 09:48 1_37_928484905.arc
Nous avons bien nos archives, de la séquence 29 à 37, qui ont été transférées automatiquement. Vérifions maintenant l’application coté base :
[oracle@srvorastby arch]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on Tue Nov 8 17:45:14 2016 Copyright (c) 1982, 2013, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options SQL> select max(sequence#) from v$archived_log where applied='YES'; MAX(SEQUENCE#) -------------- 28
=> Les archivelogs n’ont pas été appliquées à la base standby, ce qui est normal puisque nous n’avons pas activé l’application automatique des archivelogs. Qu’à cela ne tienne, j’active la synchronisation automatique :
SQL> alter database recover managed standby database disconnect from session; Database altered. SQL> select process,status,sequence# from v$managed_standby; PROCESS STATUS SEQUENCE# --------- ------------ ---------- RFS IDLE 0 RFS IDLE 0 RFS IDLE 39 PROCESS STATUS SEQUENCE# --------- ------------ ---------- RFS IDLE 0 RFS IDLE 0 RFS IDLE 0 RFS IDLE 0 RFS IDLE 0 RFS IDLE 0 RFS IDLE 0 MRP0 APPLYING_LOG 30
Dans le contrôle ci dessus, que j’ai lancé directement après la commande de synchronisation, nous identifions deux processus importants pour le fonctionnement de Dataguard :
-> Le process RFS (remote file server) qui est en attente de la séquence 39 (Last séquence de la base primaire),
Dans sa définition la plus globale, le processus RFS récupère les informations des modifications qui ont eu lieu sur la base primaire (en interrogeant le processus LGWR), et les appliquent automatiquement en déclenchant le processus MRP dans les Standby redologs files.
-> Le process MRP (Managed Recovery Process) qui, quand à lui, est en charge de l’application des archivelogs reçues dans les STANDBY REDOLOGS FILES.
Qu’est ce dont ces standby redologs files ? Simple, ce sont des redologs similaires à des redologs normaux (Online Redo Log), sauf qu’ils sont utilisés uniquement pour enregistrer des données depuis une base distante.
Vérifions après quelques instant la base stanbdby, qui a du appliquer toutes les archivelogs reçues de la base PRIMARY :
SQL> select max(sequence#) from v$archived_log where applied='YES'; MAX(SEQUENCE#) -------------- 38 SQL> select process,status,sequence# from v$managed_standby; PROCESS STATUS SEQUENCE# --------- ------------ ---------- ARCH CONNECTED 0 ARCH CONNECTED 0 RFS IDLE 0 RFS IDLE 0 RFS IDLE 39 RFS IDLE 0 RFS IDLE 0 RFS IDLE 0 RFS IDLE 0 RFS IDLE 0 RFS IDLE 0 RFS IDLE 0 MRP0 WAIT_FOR_LOG 39 SQL> select DEST_NAME,RECOVERY_MODE,DATABASE_MODE,TYPE,STATUS,DESTINATION from v$archive_dest_status ; DEST_NAME RECOVERY_MODE DATABASE_MODE STATUS DESTINATION ------------------------- ----------------------------------- --------------- --------- ------------------------------ LOG_ARCHIVE_DEST_1 MANAGED MOUNTED-STANDBY VALID /oradata/MICKSTBY/arch LOG_ARCHIVE_DEST_2 IDLE UNKNOWN DEFERRED WITTPRDH
-> Les archivelogs ont bien été appliquées automatiquement et continueront à l’être, nous voyons bien que la base Standby est en « MANAGED » (ie : application des archives automatiquement gérée) !
Bon, nous avons bien toutes les archivelogs appliquées, et notre process MRP en waiting, preuve que la base STANDBY est en mode de d’application automatique des archivelogs dans les standby redologs files.
Et voilà, nous avons monté un mécanisme de Dataguard Physical, mis en place la synchronisation automatique, et vérifié que tout ce petit monde s’accorde correctement.
Mais qu’en est il si nous modifions le mode de protection de Dataguard ? Si nous passions en Maximum PROTECTION ou AVAILABILITY ?
Cela tombe bien, nous allons voir cela très prochainement dans le second article « Oracle Dataguard 11G Part #2 : Comment changer le mode de protection de Dataguard »
Enjoy !
Micka