Introduction

Ce billet, assez conséquent, détaille la mise en place d'un environnement Dataguard Oracle 12c en utilisant deux clusters RAC à deux noeuds sur des sites distants. La version de l'OS est CentOS 7.4. La version de Oracle est la 12.1.0.2 avec application du PSU de avril 2018.

Il est supposé une bonne connaissance du RAC et du Dataguard en général.

Au moment de la configuration seule la base YODASA est en place.

  • DB_NAME : YODA
  • DB_UNIQUE_NAME : YODASA ( primaire )
  • DB_UNIQUE_NAME : YODASB ( standby )

Les fichiers de la base sont sur des diskgroups ASM :

  • DG_YODA
  • FRA_YODA

La gestion OMF est en place.

La Fast Recovery Area est configurée sur le diskgroup FRA_YODA.

Le schéma ci-dessous présente succinctement la configuration.

cluster test dataguard.jpg

Il n'est pas détaillé ici l'installation des binaires Oracle ( Grid et RDBMS ) ainsi que la création de la base primaire YODASA.

Les variables d'environnement Oracle sont :

  • ORACLE_BASE=/ora01/app/oracle
  • ORACLE_HOME=/ora01/app/oracle/product/12.1.0.2/DB ( RDBMS, user oracle )
  • ORACLE_HOME=/ora01/app/oragrid/product/12.1.0.2/GI ( GRID, user oragrid )

La couche Oracle*Net

Les serveurs sont tous gérés par un DNS sur une zone fictive nommée formation.maison. La configuration DNS n'est pas détaillée ici.

Un soin particulier doit être de mise pour cette configuration. Le dataguard utilise massivement le réseau. Les lignes suivantes doivent être présentes sur tous les noeuds de la configuration dans le fichier tnsnames.ora.

YODASA =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = rac01-scan.formation.maison)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = YODASA)
    )
  )

YODASB =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = rac02-scan.formation.maison)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = UMUTST1VE)
    )
  )

# Seulement pour RMAN duplicate ... from active database
YODASA_DUP =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = ora01sa.formation.maison)(PORT = 1521))
     )
    (CONNECT_DATA =
      (SERVICE_NAME = YODASA)
    )
  )

YODASB_DUP =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST =ora01sb.formation.maison )(PORT = 1521))
       )
    (CONNECT_DATA =
      (SERVICE_NAME = YODASB)
    )
  )

Pour les entrées type *_DUP il faut utiliser l'adresse VIP et un seul des noeuds. Via la commande tnsping, vérifier sur chaque noeud la réponse correcte de la configuration TNS. La boucle shell suivante exécute cette vérification.

for i in YODASA YODASB YODASA_DUP YODASB_DUP; do echo -n $i;  echo -n " --> "; tnsping $i | grep OK; done
YODASA --> OK (10 msec)
YODASB --> OK (20 msec)
YODASA_DUP --> OK (0 msec)
YODASB_DUP --> OK (20 msec)

Sur les noeuds du SITEB soit ora01sb et ora02sb ajouter les lignes suivantes dans le fichier listener.ora. Attention selon le noeud les lignes sont différentes. Sur le serveur ora01sb

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = YODASB)
      (ORACLE_HOME = /ora01/app/oracle/product/12.1.0.2/DB)
      (SID_NAME = YODASB1)
    )
  )

Sur le serveur ora02sb

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = YODASB)
      (ORACLE_HOME = /ora01/app/oracle/product/12.1.0.2/DB)
      (SID_NAME = YODASB2)
    )
  )

Entre les deux noeuds le nom de l'instance est différent. Il faut recharger la configuration listener sur chaque noeuds de SITEB par la commande ''lsnrctl reload"".

Préparation base primaire

Certaines actions sont nécessaires avant de lancer la création de la standby. La base primaire doit être en archivelog.

YODASA1.SYS > select log_mode from v$database;

LOG_MODE
------------
ARCHIVELOG

YODASA1.SYS > archive log list;
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence     34
Next log sequence to archive   36
Current log sequence           36
YODASA1.SYS >

Il est de plus nécessaire d'activer le mode force logging.

alter database force logging;

La requête suivante permet de vérifier certains points. Pour cette procédure le mode flashback n'est pas actif.

YODASA1.SYS > select name,db_unique_name,database_role,log_mode,force_logging,flashback_on from v$database;

NAME      DB_UNIQUE_NAME                 DATABASE_ROLE    LOG_MODE     FORCE_LOGGING                           FLASHBACK_ON
---------       ------------------------------ ---------------- ------------ --------------------------------------- ------------------
YODA      YODASA                      PRIMARY          ARCHIVELOG   YES                                     NO

YODASA1.SYS >

Configuration du transport et l'apply

Plusieurs paramètre sont nécessaires pour le transport et l'application des ordres SQL.

alter system set log_archive_config='DG_CONFIG=(YODASA,YODASB)' scope=both sid='*';
alter system set log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=YODASA' scope=both sid='*';
alter system set log_archive_dest_2='SERVICE=YODASB VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=YODASB' scope=both sid='*';
alter system set log_archive_max_processes=8 scope=both sid='*';
alter system set fal_client='YODASA' scope=both sid='*';
alter system set fal_server='YODASB' scope=both sid='*';
alter system set standby_file_management=AUTO scope=both sid='*';

Standby redolog

Les standby redolog sont utilisés par la base standby, toutefois une base peut être primaire ou standby donc il est de bonne pratique de crééer de suite les standby redolog. Il faut 1 standby redolog de plus par thread et ils doivent avoir la même dimension que les online redolog.

YODASA1.SYS > select * from v$log;

    GROUP#    THREAD#  SEQUENCE#      BYTES  BLOCKSIZE    MEMBERS ARC STATUS           FIRST_CHANGE# FIRST_TIM NEXT_CHANGE# NEXT_TIME     CON_ID
---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------- ------------ --------- ----------
         1          1         34   52428800        512          2 YES INACTIVE                377639 06-JUN-18       420081 06-JUN-18          0
         2          1         35   52428800        512          2 YES INACTIVE                420081 06-JUN-18       463619 07-JUN-18          0
         3          1         36   52428800        512          2 NO  CURRENT                 463619 07-JUN-18   2.8147E+14                    0
         4          2          7   52428800        512          2 YES INACTIVE                427685 06-JUN-18       437418 06-JUN-18          0
         5          2          8   52428800        512          2 YES INACTIVE                437418 06-JUN-18       462576 07-JUN-18          0
         6          2          9   52428800        512          2 NO  CURRENT                 462576 07-JUN-18   2.8147E+14                    0

6 rows selected.

YODASA1.SYS >

La base primaire comporte 3 groupes de online redolog par thread ( taille des membres : 50Mo ), il faut donc 4 standby redolog par thread. Oracle recommande de ne pas multiplexer les standby redolog.

YODASA1.SYS > alter database add standby logfile thread 1 ('+DG_YODA') size 50M;

Database altered.

YODASA1.SYS > /

Database altered.

YODASA1.SYS > /

Database altered.

YODASA1.SYS > /

Database altered.

YODASA1.SYS > alter database add standby logfile thread 2 ('+DG_YODA') size 50M;

Database altered.

YODASA1.SYS > /

Database altered.

YODASA1.SYS > /

Database altered.

YODASA1.SYS > /

Database altered.
YODASA1.SYS > select group#,thread#,sequence#,bytes,status from v$standby_log;

    GROUP#    THREAD#  SEQUENCE#      BYTES STATUS
---------- ---------- ---------- ---------- ----------
         7          1          0   52428800 UNASSIGNED
         8          1          0   52428800 UNASSIGNED
         9          1          0   52428800 UNASSIGNED
        10          1          0   52428800 UNASSIGNED
        11          2          0   52428800 UNASSIGNED
        12          2          0   52428800 UNASSIGNED
        13          2          0   52428800 UNASSIGNED
        14          2          0   52428800 UNASSIGNED

8 rows selected.

YODASA1.SYS >

Fichier de paramètres

Pour la génération de la standby partir du pfile de la primaire et y apporter certaines modifications.

create pfile='/home/oracle/initYODASB1.ora' from spfile;

Editier ce fichier, retirer toutes les lignes contenant "__" ainsi que les lignes cluster_database et control_files.

Dans un dataguard le paramètre DB_NAME doit être identique sur les deux sites soit ici YODA. C'est le paramètre DB_UNIQUE_NAME qui fait la différence.

Modifier les occurences YODASA et YODASB ( YODASA devient YODASB et réciproquement ) voir exemple suivant :

*.db_block_size=8192
*.db_create_file_dest='+DG_YODA'
*.db_name='YODA'
*.db_recovery_file_dest='FRA_YODA'
*.db_recovery_file_dest_size=20G
*.db_unique_name='YODASB'
*.fal_client='YODASB'
*.fal_server='YODASA'
YODASB1.instance_number=1
YODASB2.instance_number=2
*.log_archive_config='DG_CONFIG=(YODASA,YODASB)'
*.log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=YODASB'
*.log_archive_dest_2='SERVICE=YODASA VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=YODASA'
*.log_archive_format='YODA_%t_%s_%r.arch'
*.log_archive_max_processes=8
*.open_cursors=300
*.pga_aggregate_target=360M
*.processes=300
*.remote_login_passwordfile='exclusive'
*.sga_target=1280M
*.standby_file_management='AUTO'
YODASB1.thread=1
YODASB2.thread=2
YODASB1.undo_tablespace='UNDOTBS1'
YODASB2.undo_tablespace='UNDOTBS2'

Ce fichier est à copier sous le nom initYODASB1.ora sur le serveur ora01sb dans le répertoire $ORACLE_HOME/dbs. Le principe est dans un premier temps de créer la standby sans gestion de cluster et de l'activer par la suite.

Fichier de mot de passe

Toujours sur le serveur ora01sb et dans $ORACLE_HOME/dbs crééer un fichier de mot de passe temporaire. Celui-ci sera recopié par RMAN lors du duplicate depuis la base primaire.

orapwd file=orapwYODASB1
Enter password for SYS:

Création de la standby

La création utilisera RMAN via la commande duplicate from active database. Ici la création est lancée depuis le serveur ora01sb

rman target sys@YODASA_DUP auxiliary sys@YODASB_DUP

Recovery Manager: Release 12.1.0.2.0 - Production on Thu Jun 7 07:52:05 2018

Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.

target database Password:
connected to target database: YODASA1 (DBID=2193309380)
auxiliary database Password:
connected to auxiliary database (not started)

RMAN> startup clone nomount;

Oracle instance started

Total System Global Area    1342177280 bytes

Fixed Size                     2924160 bytes
Variable Size                402653568 bytes
Database Buffers             922746880 bytes
Redo Buffers                  13852672 bytes

RMAN> duplicate target database for standby from active database;

Starting Duplicate Db at 07/06/2018 09:00:33
using target database control file instead of recovery catalog
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=2 device type=DISK
...
...
Finished Duplicate Db at 07/06/2018 09:02:22

RMAN>

A ce stade la standby est en place il reste à l'intégrer au cluster. Editer le fichier $ORACLE_HOME/dbs/initYODASB1.ora et ajouter les deux lignes suivantes :

*.cluster_database=true
*.control_files='+DG_YODA/YODASB/CONTROLFILE/current.281.978166873','+FRA_YODA/YODASB/CONTROLFILE/current.499.978166875'

Le noms des fichiers de contrôle générés est disponible dans la trace du duplicate RMAN.

Supprimer le spfile généré

rm $ORACLE_HOME/dbs/spfileYODASB1.ora

Stopper la base standby et la redémarrer en mode mount.

export ORACLE_SID=YODASB1
sqlplus / as sysdba

shutdown immediate;
startup mount

Créer le spfile sur le diskgroup ASM

create spfile='+DG_YODA/YODASB/spfileYODASB.ora' from pfile;
shutdown immediate;

Sur chaque noeud du cluster standby créer sous $ORACLE_HOME/dbs un fichier initYODASB1.ora ( ora01sb ) et initYODASB2.ora ( ora02sb ) avec la ligne suivante :

SPFILE='+DG_YODA/YODASB/spfileYODASB.ora'

Intégration au cluster

Les commandes suivantes intègre la base standby au cluster

srvctl add database -db YODASB -oraclehome $ORACLE_HOME -dbtype RAC -role PHYSICAL_STANDBY -startoption MOUNT -dbname YODA -diskgroup "DG_YODA,FRA_YODA"
srvctl add instance -db YODASB -instance YODASB1 -node ora02sa
srvctl add instance -db YODASB -instance YODASB2 -node ora02sb
srvctl modify database -db YODASB -spfile '+DG_YODA/YODASB/spfileYODASB.ora'
srvctl config database -db YODASB
Database unique name: YODASB
Database name: YODA
Oracle home: /ora01/app/oracle/product/12.1.0.2/DB
Oracle user: oracle
Spfile: +DG_YODA/YODASB/spfileYODASB.ora
Password file:
Domain:
Start options: mount
Stop options: immediate
Database role: PHYSICAL_STANDBY
Management policy: AUTOMATIC
Server pools:
Disk Groups: DG_YODA,FRA_YODA
Mount point paths:
Services:
Type: RAC
Start concurrency:
Stop concurrency:
OSDBA group: g_db_sysdba
OSOPER group: g_db_sysoper
Database instances: YODASB1,YODASB2
Configured nodes: ora01sb,ora02sb
Database is administrator managed

Activation dataguard

Démarrer la base standby

srvctl start database -db YODASB
srvctl status database -db YODASB
Instance YODASB1 is running on node ora01sb
Instance YODASB2 is running on node ora02sb

Se connecter à la standby et activer le recouvrement

alter database recover managed standby database using current logfile disconnect from session;

Les commandes suivantes permettent de voir le fonctionnement correct du dataguard.

Sur la base primaire YODASA

select thread#,max(sequence#) from v$archived_log group by thread#;

   THREAD# MAX(SEQUENCE#)
         1             41
         2             14

Sur la base standby YODASB

select thread#,max(sequence#) from v$archived_log where applied='YES' group by thread#;

   THREAD# MAX(SEQUENCE#)
         1             41
         2             14

La consultation de la vue V$DATAGUARD_STATUS est aussi intéressante.

Fichier de mot de passe

Il faut transférer le fichier de mot de passe sur le diskgroup ASM. Sur le serveur ora01sb se connecter oragrid et charger l'environnement asm.

asmcmd -p
ASMCMD [+] > pwcopy --dbuniquename YODASB '/ora01/app/oracle/product/12.1.0.2/DB/dbs/orapwYODASB1' '+DG_YODA/YODASB/orapwYODASB'
copying /ora01/app/oracle/product/12.1.0.2/DB/dbs/orapwUMUTST1VE1 -> +DG_UMU/UMUTST1VE/orapwUMUTST1VE
ASMCMD-9453: failed to register password file as a CRS resource
ASMCMD [+] > exit

Le message ASMCMD-9453 est normal car l'enregistrement doit être fait par le user oracle. Se reconnecter oracle et modifier la configuration cluster

srvctl modify database -db YODASB -pwfile '+DG_YODA/YODASB/orapwYODASB'

Supprimer le fichier de mot de passe local.

rm /ora01/app/oracle/product/12.1.0.2/DB/dbs/orapwYODASB1

Configuration broker

La broker permet de simplifier les commandes d'administration du dataguard. Depuis la version 12c il n'est plus nécessaire de configurer les services _DGMGRL dans le listener.

Positionner les fichiers de configuration du broker sur l'ASM et démarrer le broker

Sur base primaire : YODASA

alter system set log_archive_dest_2='' scope=both sid='*';
alter system set dg_broker_config_file1='+DG_YODA/YODASA/dr1YODASA.dat' scope=both sid='*';
alter system set dg_broker_config_file2='+FRA_YODA/YODASA/dr2YODASA.dat' scope=both sid='*';
alter system set dg_broker_start=TRUE scope=both sid='*';

Sur la base standby : YODASB

alter system set log_archive_dest_2='' scope=both sid='*';
alter system set dg_broker_config_file1='+DG_YODA/YODASB/dr1YODASB.dat' scope=both sid='*';
alter system set dg_broker_config_file2='+FRA_YODA/YODASB/dr2YODASB.dat' scope=both sid='*';
alter system set dg_broker_start=TRUE scope=both sid='*';

Depuis le serveur ora01sa ( base primaire ) se connecter au broker

dgmgrl /
DGMGRL> create configuration DG_YODA as primary database is YODASA connect identifier is "YODASA";
Configuration "dg_yoda" created with primary database "yodasa"
DGMGRL> add database YODASB as connect identifier is "YODASB" maintained as physical;
Database "yodasb" added
DGMGRL> enable configuration;
Enabled.
DGMGRL> show configuration verbose;

Configuration - dg_yoda

  Protection Mode: MaxPerformance
  Members:
  yodasa - Primary database
    yodasb - Physical standby database

  Properties:
    FastStartFailoverThreshold      = '30'
    OperationTimeout                = '30'
    TraceLevel                      = 'USER'
    FastStartFailoverLagLimit       = '30'
    CommunicationTimeout            = '180'
    ObserverReconnect               = '0'
    FastStartFailoverAutoReinstate  = 'TRUE'
    FastStartFailoverPmyShutdown    = 'TRUE'
    BystandersFollowRoleChange      = 'ALL'
    ObserverOverride                = 'FALSE'
    ExternalDestination1            = ''
    ExternalDestination2            = ''
    PrimaryLostWriteAction          = 'CONTINUE'

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

DGMGRL>

Les commandes show/validate database verbose YODASA et show/validate database verbose YODASB donnent un grand nombre d'informations.

Switchover par broker

Lancer le broker et se connecter à la future primaire.

dgmgrl
DGMGRL for Linux: Version 12.1.0.2.0 - 64bit Production

Copyright (c) 2000, 2013, Oracle. All rights reserved.

Welcome to DGMGRL, type "help" for information.
DGMGRL> connect sys@YODASB
Password:
Connected as SYSDBA.
DGMGRL> switchover to YODASB;
Performing switchover NOW, please wait...
New primary database "yodasb" is opening...
Oracle Clusterware is restarting database "yodasa" ...
Switchover succeeded, new primary is "yodasb"
DGMGRL> show configuration verbose;
Configuration - dg_yoda

  Protection Mode: MaxPerformance
  Members:
  yodasb - Primary database
    yodasa - Physical standby database

  Properties:
    FastStartFailoverThreshold      = '30'
    OperationTimeout                = '30'
    TraceLevel                      = 'USER'
    FastStartFailoverLagLimit       = '30'
    CommunicationTimeout            = '180'
    ObserverReconnect               = '0'
    FastStartFailoverAutoReinstate  = 'TRUE'
    FastStartFailoverPmyShutdown    = 'TRUE'
    BystandersFollowRoleChange      = 'ALL'
    ObserverOverride                = 'FALSE'
    ExternalDestination1            = ''
    ExternalDestination2            = ''
    PrimaryLostWriteAction          = 'CONTINUE'

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

DGMGRL>

Modifier paramètres via le broker

Certains paramètres de la base peuvent être modifiés via le broker. Ici par exemple configuration de archive_lag_target à 900 secondes.

DGMGRL> edit database YODASB set property ArchiveLagTarget=900;
DGMGRL> edit database YODASA set property ArchiveLagTarget=900;
DGMGRL> show database verbose YODASB;
Database - yodasb

  Role:               PRIMARY
  Intended State:     TRANSPORT-ON
  Instance(s):
    YODASB1
    YODASB2

  Properties:
    DGConnectIdentifier             = 'YODASB'
    ObserverConnectIdentifier       = ''
    LogXptMode                      = 'ASYNC'
    RedoRoutes                      = ''
    DelayMins                       = '0'
    Binding                         = 'optional'
    MaxFailure                      = '0'
    MaxConnections                  = '1'
    ReopenSecs                      = '300'
    NetTimeout                      = '30'
    RedoCompression                 = 'DISABLE'
    LogShipping                     = 'ON'
    PreferredApplyInstance          = ''
    ApplyInstanceTimeout            = '0'
    ApplyLagThreshold               = '0'
    TransportLagThreshold           = '0'
    TransportDisconnectedThreshold  = '30'
    ApplyParallel                   = 'AUTO'
    StandbyFileManagement           = 'AUTO'
    ArchiveLagTarget                = '900'
    LogArchiveMaxProcesses          = '8'
    LogArchiveMinSucceedDest        = '1'
    DbFileNameConvert               = ''
    LogFileNameConvert              = ''
    FastStartFailoverTarget         = ''
    InconsistentProperties          = '(monitor)'
    InconsistentLogXptProps         = '(monitor)'
    SendQEntries                    = '(monitor)'
    LogXptStatus                    = '(monitor)'
    RecvQEntries                    = '(monitor)'
    StaticConnectIdentifier(*)
    StandbyArchiveLocation(*)
    AlternateLocation(*)
    LogArchiveTrace(*)
    LogArchiveFormat(*)
    TopWaitEvents(*)
    (*) - Please check specific instance for the property value

Database Status:
SUCCESS

Le fichier alert.log de la base montre cette modification

...
2018-06-07 11:05:54.328000 +02:00
ALTER SYSTEM SET archive_lag_target=900 SCOPE=BOTH SID='*';
...

Configuration de services

Le principe général est de démarrer les services uniquement quand la base est primaire. Sur chaque envrionnement il faut donc créer les services en indiquant la clause -role PRIMARY. Ici on met en place 3services

  • YODA_APS : Load Balancing
  • YODA_BAS1 : sur noeud 1 et failover sur noeud 2
  • YODA_BAS2 : sur noeud 2 et failover sur noeud 1

Sur base primaire YODASB

srvctl add service -db YODASB -service YODA_APS -preferred YODASB1,YODASB2 -role PRIMARY
srvctl add service -db YODASB -service YODA_BAS1 -preferred YODASB1 -available YODASB2 -role PRIMARY
srvctl add service -db YODASB -service YODA_BAS2 -preferred YODASB2 -available YODASB1 -role PRIMARY

Sur base standby YODASA

srvctl add service -db YODASA -service YODA_APS -preferred YODASA1,YODASA2 -role PRIMARY
srvctl add service -db YODASA -service YODA_BAS1 -preferred YODASA1 -available YODASA2 -role PRIMARY
srvctl add service -db YODASA -service YODA_BAS2 -preferred YODASA2 -available YODASA1 -role PRIMARY