1. Home
  2. Knowledge Base
  3. High Availability
  4. 11g Data Guard Cascading Standby Database

11g Data Guard Cascading Standby Database

This note describes the procedure used to setup and configure a Data Guard Cascaded Standby database environment.

The cascading standby database receives redo from the Primary database and then this redo is cascaded to one or more cascaded standby databases.

So the cascaded  standby database does not receive its redo directly from the Primary database and this type of data guard configuration offloads the overhead associated with performing redo transport from a primary database to a cascading standby database.

Quoting the official documentation:

“Primary database redo is written to the standby redo log as it is received at a cascading standby database. The redo is not immediately cascaded however. It is cascaded after the standby redo log file that it was written to has been archived locally. A cascaded destination will therefore always have a greater redo transport lag, with respect to the primary database, than the cascading standby database.”

We can use the cascaded standby database feature to say offload reporting from the primary database to the cascaded standby database (with or without Active Data Guard) or use the cascaded standby database along with the snapshot standby feature as a test environment in some cases where we need to test an urgent patch or fix and would like to do that using a database with real time production database and not some other test database.

This is the environment:

A) Primary Database (TESTDB1)
B) Physical Standby Database (TESTDB2)
C) Cascaded Standby Database (TESTDB3)

So this is how the redo log transport will happen:

TESTDB1 >>>> TESTDB2
TESTDB2 >>>> TESTDB3

The assumptions are:

• The Data Guard will be configured in Maximum Availability mode
• The backup location on the Primary server and Standby server is different
• The directory structure on the Standby server is not the same as the Primary server
• The Standby server will host both the Standby database as well as the Cascaded standby database
• The environment used in this example is Oracle database version 11.2.0.3 on OEL Linux 5.7
• The db_unique_name of the Primary database is testdb1 , the Standby database is testdb2 and the Cascaded Standby database is testdb3
• It is assumed that a recent RMAN backup of the Primary database and archivelogs is available on the Primary server. In this example it exists in the FRA.

Steps

Network Configuration

The tnsnames.ora file on both the Primary database server and Standby database serve have the entries :

TESTDB1 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = host1)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = testdb1)
)
)

TESTDB2 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = host2)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = testdb2)
)
)

TESTDB3 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = host2)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = testdb3)
)
)

The listener.ora on the Standby database server has a static entry for testdb2 and testdb3

SID_LIST_LISTENER=
(SID_LIST=
(SID_DESC=
(GLOBAL_DBNAME=testdb2)
(ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1)
(SID_NAME=testdb2)
)
(SID_DESC=
(GLOBAL_DBNAME=testdb3)
(ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1)
(SID_NAME=testdb3)
)

)

On Primary take a backup of the current control file which will be used by the Standby database

RMAN> backup current controlfile for standby;

…….
…….
channel ORA_DISK_1: finished piece 1 at 06-MAY-13
piece handle=/u01/app/oracle/fast_recovery_area/TESTDB1/backupset/2013_05_06/o1_mf_ncnnf_TAG20130506T165754_8rgo3n7o_.bkp tag=TAG20130506T165754 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01

………

Make a note of the backup piece name as we will be using this backup for the Standby database creation.

Take a backup of the database and archivelogs

RMAN> sql 'alter system switch logfile';

sql statement: alter system switch logfile

RMAN> backup database plus archivelog ;

Starting backup at 06-MAY-13
current log archived
using channel ORA_DISK_1
channel ORA_DISK_1: starting archived log backup set
channel ORA_DISK_1: specifying archived log(s) in backup set
input archived log thread=1 sequence=3 RECID=1 STAMP=814288291
input archived log thread=1 sequence=4 RECID=2 STAMP=814288349
input archived log thread=1 sequence=5 RECID=3 STAMP=814289179
input archived log thread=1 sequence=6 RECID=4 STAMP=814289262
input archived log thread=1 sequence=7 RECID=5 STAMP=814295555
input archived log thread=1 sequence=8 RECID=8 STAMP=814296764

……..

……….

input datafile file number=00002 name=/u01/app/oracle/oradata/testdb1/sysaux01.dbf
input datafile file number=00005 name=/u01/app/oracle/oradata/testdb1/example01.dbf
input datafile file number=00003 name=/u01/app/oracle/oradata/testdb1/undotbs01.dbf
input datafile file number=00004 name=/u01/app/oracle/oradata/testdb1/users01.dbf
channel ORA_DISK_1: starting piece 1 at 06-MAY-13
channel ORA_DISK_1: finished piece 1 at 06-MAY-13
piece handle=/u01/app/oracle/fast_recovery_area/TESTDB1/backupset/2013_05_06/o1_mf_nnndf_TAG20130506T170129_8rgobbk1_.bkp tag=TAG20130506T170129 comment=NONE
channel ORA_DISK_1: backup set complete, elapsed time: 00:01:05
Finished backup at 06-MAY-13

…..

Copy the most recent database backup, archivelog backup and controlfile backup to the staging location on the Standby server

cd /u01/app/oracle/fast_recovery_area/TESTDB1/backupset/2013_05_06

[oracle@pdemvrhl061 2013_05_06]$ ls -l
total 1898088
-rw-r----- 1 oracle dba 684387840 May 6 17:01 o1_mf_annnn_TAG20130506T170053_8rgo964x_.bkp
-rw-r----- 1 oracle dba 64000 May 6 17:02 o1_mf_annnn_TAG20130506T170235_8rgodcsg_.bkp
-rw-r----- 1 oracle dba 9994240 May 6 17:09 o1_mf_ncnnf_TAG20130506T170934_8rgoshw2_.bkp
-rw-r----- 1 oracle dba 1247256576 May 6 17:02 o1_mf_nnndf_TAG20130506T170129_8rgobbk1_.bkp

scp -rp * oracle@host2:/home/oracle/backup

Copy password file from $ORACLE_HOME/dbs on Primary to $ORACLE_HOME/dbs on Standby

scp -rp orapwtestdb1 oracle@host2:/u01/app/oracle/product/11.2.0/dbhome_1/dbs/orapwtestdb2

scp -rp orapwtestdb1 oracle@host2:/u01/app/oracle/product/11.2.0/dbhome_1/dbs/orapwtestdb3

Copy init.ora file from $ORACLE_HOME/dbs on Primary to $ORACLE_HOME/dbs on Standby

scp –rp inittestdb1.ora oracle@host2:/u01/app/oracle/product/11.2.0/dbhome_1/dbs/inittestdb2.ora

scp –rp inittestdb1.ora oracle@host2:/u01/app/oracle/product/11.2.0/dbhome_1/dbs/inittestdb3.ora

Make the required changes to the Standby database (testdb2) init.ora file

These are the changes we have made to the init.ora which we have copied from the Primary database (testdb1) – the remaining parameters like sga_target, db_name, diagnostic_dest etc will be the same regardless if the database is a Primary database or Physical standby database.

Review particularly the entries related to redo transport like the log_archive_dest_* entries

*.audit_file_dest='/u01/app/oracle/admin/testdb2/adump'
*.control_files='/u01/app/oracle/oradata/testdb2/control01.ctl','/u01/app/oracle/oradata/testdb2/control02.ctl'
*.db_file_name_convert='/u01/app/oracle/oradata/testdb1','/u01/app/oracle/oradata/testdb2'
*.db_unique_name='testdb2'
*.fal_client='testdb2'
*.fal_server='testdb1'
*.log_archive_config='DG_CONFIG=(testdb1,testdb2,testdb3)'
*.log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=testdb2'
*.log_archive_dest_2='SERVICE=testdb1 LGWR SYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=testdb1'
*.log_archive_dest_3='SERVICE=testdb3 VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE) DB_UNIQUE_NAME=testdb3'
*.log_file_name_convert='/u01/app/oracle/oradata/testdb1','/u01/app/oracle/oradata/testdb2'
*.service_names='testdb2'

Create the required directory structure on the Standby site

$ mkdir -p /u01/app/oracle/admin/testdb2/adump
$ mkdir -p /u01/app/oracle/admin/testdb3/adump
$ mkdir -p /u01/app/oracle/oradata/testdb1
$ mkdir -p /u01/app/oracle/oradata/testdb3
$ mkdir  -p /u01/app/oracle/fast_recovery_area

Add entries in /etc/oratab

 testdb2:/u01/app/oracle/product/11.2.0/dbhome_1:N
testdb3:/u01/app/oracle/product/11.2.0/dbhome_1:N

Start the Standby database instance in NOMOUNT state

SQL> startup nomount;
ORACLE instance started.

Total System Global Area  417546240 bytes
Fixed Size                  2228944 bytes
Variable Size             272633136 bytes
Database Buffers          134217728 bytes
Redo Buffers                8466432 bytes
SQL>

Restore the Standby Controlfile from the backup copied from Primary
 

RMAN> restore standby controlfile from '/home/oracle/backup/o1_mf_ncnnf_TAG20130506T170934_8rgoshw2_.bkp';

Starting restore at 06-MAY-13
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=133 device type=DISK

channel ORA_DISK_1: restoring control file
channel ORA_DISK_1: restore complete, elapsed time: 00:00:01
output file name=/u01/app/oracle/oradata/testdb2/control01.ctl
output file name=/u01/app/oracle/oradata/testdb2/control02.ctl
Finished restore at 06-MAY-13

Mount the standby database (note in 11g we can just ‘ALTER DATABASE MOUNT’ command)

RMAN> sql 'alter database mount standby database';

sql statement: alter database mount standby database
released channel: ORA_DISK_1

Now catalog all the backup pieces which we have copied from Primary

RMAN> catalog start with '/home/oracle/backup';

searching for all files that match the pattern /home/oracle/backup

List of Files Unknown to the Database
=====================================
File Name: /home/oracle/backup/o1_mf_annnn_TAG20130506T170235_8rgodcsg_.bkp
File Name: /home/oracle/backup/o1_mf_nnndf_TAG20130506T170129_8rgobbk1_.bkp
File Name: /home/oracle/backup/o1_mf_ncnnf_TAG20130506T170934_8rgoshw2_.bkp
File Name: /home/oracle/backup/o1_mf_annnn_TAG20130506T170053_8rgo964x_.bkp

Do you really want to catalog the above files (enter YES or NO)? y
cataloging files...
cataloging done

List of Cataloged Files
=======================
File Name: /home/oracle/backup/o1_mf_annnn_TAG20130506T170235_8rgodcsg_.bkp
File Name: /home/oracle/backup/o1_mf_nnndf_TAG20130506T170129_8rgobbk1_.bkp
File Name: /home/oracle/backup/o1_mf_ncnnf_TAG20130506T170934_8rgoshw2_.bkp
File Name: /home/oracle/backup/o1_mf_annnn_TAG20130506T170053_8rgo964x_.bkp

Restore the database –on the Standby database testdb2

Note the files are being restored in the new location:/u01/app/oracle/oradata/testdb2

RMAN> restore database;

Starting restore at 06-MAY-13
using channel ORA_DISK_1

channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00001 to /u01/app/oracle/oradata/testdb2/system01.dbf
channel ORA_DISK_1: restoring datafile 00002 to /u01/app/oracle/oradata/testdb2/sysaux01.dbf
channel ORA_DISK_1: restoring datafile 00003 to /u01/app/oracle/oradata/testdb2/undotbs01.dbf
channel ORA_DISK_1: restoring datafile 00004 to /u01/app/oracle/oradata/testdb2/users01.dbf
channel ORA_DISK_1: restoring datafile 00005 to /u01/app/oracle/oradata/testdb2/example01.dbf
channel ORA_DISK_1: reading from backup piece /home/oracle/backup/o1_mf_nnndf_TAG20130506T170129_8rgobbk1_.bkp
channel ORA_DISK_1: piece handle=/home/oracle/backup/o1_mf_nnndf_TAG20130506T170129_8rgobbk1_.bkp tag=TAG20130506T170129
channel ORA_DISK_1: restored backup piece 1
channel ORA_DISK_1: restore complete, elapsed time: 00:00:46
Finished restore at 06-MAY-13

Note the last archived log sequence # which has been backed up

RMAN> list backup of archivelog all;

List of Backup Sets
===================

BS Key  Size       Device Type Elapsed Time Completion Time
------- ---------- ----------- ------------ ---------------
……
………

  List of Archived Logs in backup set 23
  Thrd Seq     Low SCN    Low Time  Next SCN   Next Time
  ---- ------- ---------- --------- ---------- ---------
  1    60      1602201    06-MAY-13 1604763    06-MAY-13
  1    61      1604763    06-MAY-13 1604769    06-MAY-13
  1    62      1604769    06-MAY-13 1629416    06-MAY-13
  1    63      1629416    06-MAY-13 1674083    07-MAY-13
  1    64      1674083    07-MAY-13 1694517    07-MAY-13
  1    65      1694517    07-MAY-13 1694574    07-MAY-13
  1    66      1694574    07-MAY-13 1694766    07-MAY-13

Recover the database – the SET UNTIL SEQUENCE will be the last archive log sequence backup available plus 1

RMAN> run
2> { set until sequence 67;
3> recover database;
4> }

executing command: SET until clause

Starting recover at 07-MAY-13
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=13 device type=DISK

starting media recovery

channel ORA_DISK_1: starting archived log restore to default destination
channel ORA_DISK_1: restoring archived log
archived log thread=1 sequence=64
channel ORA_DISK_1: restoring archived log
archived log thread=1 sequence=65
channel ORA_DISK_1: restoring archived log
archived log thread=1 sequence=66
channel ORA_DISK_1: reading from backup piece /home/oracle/backup/o1_mf_annnn_TAG20130507T141625_8rk00td3_.bkp
channel ORA_DISK_1: piece handle=/home/oracle/backup/o1_mf_annnn_TAG20130507T141625_8rk00td3_.bkp tag=TAG20130507T141625
channel ORA_DISK_1: restored backup piece 1
channel ORA_DISK_1: restore complete, elapsed time: 00:00:01
archived log file name=/u01/app/oracle/fast_recovery_area/TESTDB2/archivelog/2013_05_07/o1_mf_1_64_8rk04zb6_.arc thread=1 sequence=64
channel default: deleting archived log(s)
archived log file name=/u01/app/oracle/fast_recovery_area/TESTDB2/archivelog/2013_05_07/o1_mf_1_64_8rk04zb6_.arc RECID=8 STAMP=814803519
archived log file name=/u01/app/oracle/fast_recovery_area/TESTDB2/archivelog/2013_05_07/o1_mf_1_65_8rk04zbz_.arc thread=1 sequence=65
channel default: deleting archived log(s)
archived log file name=/u01/app/oracle/fast_recovery_area/TESTDB2/archivelog/2013_05_07/o1_mf_1_65_8rk04zbz_.arc RECID=7 STAMP=814803519
archived log file name=/u01/app/oracle/fast_recovery_area/TESTDB2/archivelog/2013_05_07/o1_mf_1_66_8rk04zbp_.arc thread=1 sequence=66
channel default: deleting archived log(s)
archived log file name=/u01/app/oracle/fast_recovery_area/TESTDB2/archivelog/2013_05_07/o1_mf_1_66_8rk04zbp_.arc RECID=6 STAMP=814803519
media recovery complete, elapsed time: 00:00:01
Finished recover at 07-MAY-13

Now we need to perform the same steps for the Cascaded Standby database testdb3

We make the following changes in the init.ora file which we have copied from the Primary database:

 *.audit_file_dest=’/u01/app/oracle/admin/testdb3/adump’
*.control_files=’/u01/app/oracle/oradata/testdb3/control01.ctl’,’/u01/app/oracle/oradata/testdb3/control02.ctl’
*.db_file_name_convert=’/u01/app/oracle/oradata/testdb1′,’/u01/app/oracle/oradata/testdb3′
*.log_file_name_convert=’/u01/app/oracle/oradata/testdb1′,’/u01/app/oracle/oradata/testdb3′
*.db_unique_name=’testdb3′
*.fal_client=’testdb3′
*.fal_server=’testdb2′
*.log_archive_dest_1=’LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=testdb3′
*.service_names=’testdb3′
*.LOG_ARCHIVE_CONFIG=’DG_CONFIG=(testdb1,testdb2,testdb3)’

  •  Set the enevironment for the database testdb3
  • Startup NOMOUNT the database
  • Restore the backup of the controlfile taken from the Primary database
  • Mount the database
  • Restore the database
  • Recover the database until the same archived log sequence number we used for the earlier standby database testdb2.

Add the Standby Redo Log Files

Create the Standby redo log files on all the three databases. Note that we use the same size as the redo log files and create one additional group in case of the standby redo log files as compared to the online redo log files.

For example:

 

SQL> alter database add standby logfile '/u01/app/oracle/oradata/testdb1/standby_redo01.log' size 50m;

Database altered.

SQL> alter database add standby logfile '/u01/app/oracle/oradata/testdb1/standby_redo02.log' size 50m;

Database altered.

SQL> alter database add standby logfile '/u01/app/oracle/oradata/testdb1/standby_redo03.log' size 50m;

Database altered.

SQL> alter database add standby logfile '/u01/app/oracle/oradata/testdb1/standby_redo04.log' size 50m;

Database altered.

Open both the Standby Database as well as the Cascaded standby database and put them in managed recovery mode

SQL> alter database open;

Database altered.

SQL> recover managed standby database using current logfile disconnect;
Media recovery complete.

 

Configure redo transport for the Primary Database

We add the following entries in the init.ora of the Parimary database

 *.fal_client=’testdb1′
*.fal_server=’testdb2′
*.log_archive_dest_1=’LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=testdb1′
*.log_archive_dest_2=’SERVICE=testdb2 LGWR SYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=testdb2′
*.log_archive_dest_3=’SERVICE=testdb3  VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE) DB_UNIQUE_NAME=testdb3′;
*.log_archive_dest_state_3=’DEFER’
*.standby_file_management=’AUTO’

Note that we have set parameter log_archive_dest_state_3 to DEFER because in normal operation, the Primary database testdb2 will only ship redo logs to the standby database testdb2 and NOT the cascaded standby database testdb3.

When the current Primary database testdb1 assumes the role of a standby database at some time in the future when a switchover happens, then only we need to enable the log shipping from testdb1 to testdb3.

Change the protection mode to MAXIMUM AVAILABILITY

 

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.

Total System Global Area  839282688 bytes
Fixed Size                  2233000 bytes
Variable Size             494931288 bytes
Database Buffers          335544320 bytes
Redo Buffers                6574080 bytes
Database mounted.

SQL> alter database set standby database to maximize availability;

Database altered.

SQL> alter database open;

Database altered.

SQL> select  PROTECTION_MODE,PROTECTION_LEVEL from v$database;

PROTECTION_MODE      PROTECTION_LEVEL
-------------------- --------------------
MAXIMUM AVAILABILITY MAXIMUM AVAILABILITY

Lets Test!

Primary Database TESTDB1
 

SQL> update customers
  2  set cust_first_name=’Smith’
  3   where rownum=1;

1 row updated.

SQL> commit;

Commit complete.

 

Standby Database/Cascading Standby TESTDB2
 

SQL> select cust_first_name from customers where rownum=1;

CUST_FIRST_NAME
——————–
Smith

 

Cascaded Standby Database TESTDB3

At this stage the cascaded standby database is lagging behind the Primary as well as the cascading Standby database because the changes from the TESTDB2 will only be cascaded to TESTDB3 when a log switch is triggered when the archive redo log file fills up

SQL> select cust_first_name from customers where rownum=1;

CUST_FIRST_NAME
--------------------
Sachin

Primary Database TESTDB1

SQL> conn / as sysdba
Connected.

SQL> alter system switch logfile;

System altered.

Cascaded Standby Database TESTDB3

SQL> select cust_first_name from customers where rownum=1;

CUST_FIRST_NAME
--------------------
Smith
Updated on June 2, 2021

Was this article helpful?

Related Articles

Comments

  1. Nice post, thanks for sharing. You mentioned to add one additional standby log group compared to online log group. I always used same no.of groups for standby and online logs. Is there any reason or benefit of creating one extra standby group ? any oracle document to refer.

    Thanks
    Rao

  2. Hi Sudhakar,

    Have a look at this note on Metalink – Usage, Benefits and Limitations of Standby Redo Logs (SRL) [ID 219344.1].

    Taken from the note:

    “If you consider using Standby Redo Logs, you must make certain that they are
    the same size as the Online Redo Logs. If you have different sizes of Online
    Redo Logs, you have to create corresponding Standby Redo Logs. The RFS process
    won’t attach Standby Redo Logs if they are different from the Online Redo Log.
    It is recommended to have at least one more of Standby Redo Log Group as you
    have of Online Redo Log Groups per Thread and Size..

Leave a Comment