Mir Sayeed Hassan – Oracle Blog

Oracle DBA – Tips & Techniques | Learn with real-time examples

  • Translate

  • It’s Me






  • My Certificates

  • Links

    My Acclaim Certification : Credly Profile
    My Oracle ACE Pro Profile

  • Achievements

    Awarded Top 100 Oracle Blogs from Worldwide - #RANK 39
  • VISITORS COUNT

  • Verified International Academic Qualification from World Education Service (WES)

    Verified International Academic Qualification from World Education Service (WES)

  • Jobs

How to Configure the Data Guard with Cascading Standby Database on Oracle 19C DB

Posted by Mir Sayeed Hassan on February 16th, 2025

How to Configure the Data Guard with Cascading Standby Database on Oracle 19C DB

Brief about this concept

– I would like to configure the data guard with the cascading standby database on Oracle Database 19C.
– To perform this we should have configure 1 Primary database, 2 Standby database

Flow should be like this

PRIMARY > STANDBY 1 > STANDBY 2

Our Environments

ROLE        LOCATION     IP                HOSTNAME       CDB NAME   PDB NAME   DB UNIQUE NAME   DB VERSION                OS

PRIMARY     Bangalore    192.168.***.165   PRI-TESTDB     PRITESTD   TESTDB1    PRITESTDB         19.3.0.0.0      Oracle Linux Server 7.8
STANDBY 1   Chennai      192.168.***.166   TESTDB-STD1    PRITESTD   TESTDB1    TESTDBSTD1        19.3.0.0.0      Oracle Linux Server 7.8
STANDBY 2   Mumbai       192.168.***.167   TESTDB-STD2    PRITESTD   TESTDB1    TESTDBSTD2        19.3.0.0.0      Oracle Linux Server 7.8

Login to the all the server and add the hostname

First turn off firewall on all the 3 server

Primary DB

[root@PRI-TESTDB ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.***.165    PRI-TESTDB
192.168.***.166    TESTDB-STD1
192.168.***.167    TESTDB-STD2

Standby DB 1

[root@TESTDB-STD1 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.***.165    PRI-TESTDB
192.168.***.166    TESTDB-STD1
192.168.***.167    TESTDB-STD2

Standby DB 3

[root@localhost ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.***.165    PRI-TESTDB
192.168.***.166    TESTDB-STD1
192.168.***.167    TESTDB-STD2

Configuration on Primary DB Server

Install SOFTWARE + CDB + PDB.

SQL> select name, version, status from v$instance, v$database;

NAME         VERSION       STATUS
----------------------------------
PRITESTD    19.0.0.0.0      OPEN

Enable the database in archivelog mode.

SQL > shu immediate;
SQL > startup mount;
SQL > alter database archivelog;
SQL> alter system set log_archive_dest_1='LOCATION=/u01/app/oracle/fast_recovery_area';
System altered.
SQL> show parameter log_archive_dest_1

NAME                   TYPE                       VALUE
------------------------------------------------------------------------------
log_archive_dest_1    string     LOCATION=/u01/app/oracle/fast_recovery_area
SQL > alter database open;

Create a default location for storing datafile.

SQL> alter system set db_create_online_log_dest_1='/u01/app/oracle/oradata/';
System altered.

Create the require logfile

SQL> alter database add logfile group 4 size 100m;
Database altered.
SQL> alter database add logfile group 5 size 100m;
Database altered.
SQL> select * from V$log;

GROUP# THREAD#  SEQUENCE#        BYTES   BLOCKSIZE  MEMBERS  ARC STATUS  FIRST_CHANGE#   FIRST_TIM    NEXT_CHANGE#    NEXT_TIME      CON_ID
--------------------------------------------------------------------------------------------------------------------------------------------
1       1        56 104857600    512       1         YES       ACTIVE     2533483        15-DEC-24      2533504       15-DEC-24        0
2       1        58 104857600    512       1         YES       ACTIVE     2533507        15-DEC-24      2533510       15-DEC-24        0
3       1        57 104857600    512       1         YES       ACTIVE     2533504        15-DEC-24      2533507       15-DEC-24        0
4       1        59 104857600    512       1         YES       ACTIVE     2533510        15-DEC-24      2533513       15-DEC-24        0
5       1        60 104857600    512       1         NO        CURRENT    2533513        15-DEC-24      1.8447E+19                     0

Add Standby logfile

SQL> alter database add standby logfile group 11 size 100m;
Database altered.
SQL> alter database add standby logfile group 12 size 100m;
Database altered.
SQL> alter database add standby logfile group 13 size 100m;
Database altered.
SQL> alter database add standby logfile group 14 size 100m;
Database altered.
SQL> alter database add standby logfile group 15 size 100m;
Database altered.
SQL> alter database add standby logfile group 16 size 100m;
Database altered.

Verify

SQL> SELECT GROUP#,THREAD#,SEQUENCE#,ARCHIVED,STATUS FROM V$STANDBY_LOG;

GROUP# THREAD# SEQUENCE#    ARC    STATUS
---------- ---------- ---------- --- ----------
11     0         0          YES     UNASSIGNED
12     0         0          YES     UNASSIGNED
13     0         0          YES     UNASSIGNED
14     0         0          YES     UNASSIGNED
15     0         0          YES     UNASSIGNED
16     0         0          YES     UNASSIGNED

Add the Database entries into the tnsnames.ora file on PRIMARY DATABASE, STANDBY DATABASE 1 & STANDBY DATABASE 2

[oracle@PRITESTDB ~]$ vi $ORACLE_HOME/network/admin/tnsnames.ora

PRITESTDB =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = PRI-TESTDB)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = PRITESTDB)
)
)
TESTDBSTD1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = TESTDB-STD1)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = TESTDBSTD1)
)
)
TESTDBSTD2 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = TESTDB-STD2)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = TESTDBSTD2)
)
)

Transfer the ORAPASSWD File from Primary to both Standby database server 1 & 2

From Primary DB Server to Standby Server

[oracle@PRI-TESTDB ~]$ cd $ORACLE_HOME/dbs
[oracle@PRI-TESTDB dbs]$ scp orapwPRITESTDB oracle@192.168.***.166:/u01/app/oracle/product/19C/dbhome_1/dbs/orapwTESTDBSTD1
[oracle@PRI-TESTDB ~]$ cd $ORACLE_HOME/dbs
[oracle@PRI-TESTDB dbs]$ scp orapwPRITESTDB oracle@192.168.***.166:/u01/app/oracle/product/19C/dbhome_1/dbs/orapwTESTDBSTD2

Configure the require parameter in Primary db for data guard syncronization.

SQL> show parameter db_unique_name

NAME             TYPE        VALUE
-------------------------------------
db_unique_name   string    PRITESTDB
SQL> ALTER SYSTEM SET log_archive_config='dg_config=(PRITESTDB,TESTDBSTD1,TESTDBSTD2)' SCOPE=SPFILE;
System altered.
SQL> ALTER SYSTEM SET log_archive_dest_1='LOCATION=C:\Archive valid_for=(all_logfiles,all_roles) db_unique_name=PRITESTDB' SCOPE=SPFILE;
System altered.
SQL> ALTER SYSTEM SET log_archive_dest_2='service=TESTDBSTD1 async valid_for=(online_logfiles,primary_role) db_unique_name=TESTDBSTD1' SCOPE=SPFILE;
System altered.
SQL> ALTER SYSTEM SET log_archive_dest_3='service=TESTDBSTD2 async valid_for=(standby_logfiles,standby_role) db_unique_name=TESTDBSTD2' SCOPE=SPFILE;
System altered.
SQL> ALTER SYSTEM SET log_archive_dest_state_3='DEFER' SCOPE=SPFILE;
System altered.
SQL> ALTER SYSTEM SET fal_server='TESTDBSTD1' SCOPE=SPFILE;
System altered.
SQL> ALTER SYSTEM SET fal_client='PRITESTDB' SCOPE=SPFILE;
System altered.
SQL> ALTER SYSTEM SET standby_file_management='AUTO' SCOPE=SPFILE;
System altered.
SQL> ALTER SYSTEM SET db_file_name_convert='/u01/app/oracle/oradata/PRITESTDB/','/u01/app/oracle/oradata/TESTDBSTD1/' SCOPE=SPFILE;
System altered.
SQL> ALTER SYSTEM SET log_file_name_convert='/u01/app/oracle/oradata/PRITESTDB/','/u01/app/oracle/oradata/TESTDBSTD1/' SCOPE=SPFILE;
System altered.

Create a pfile from spfile before change for backup purpose.

SQL> create pfile='/tmp/pfile_new_15feb25.ora' from spfile;
File created.
SQL> shu immediate;
SQL> startup;

Configure the STANDBY DATABASE 1: TESTDBSTD1

Create a pfile:

vi initTESTDBSTD1.ora

TESTDBSTD1.__data_transfer_cache_size=0
TESTDBSTD1.__db_cache_size=587202560
TESTDBSTD1.__inmemory_ext_roarea=0
TESTDBSTD1.__inmemory_ext_rwarea=0
TESTDBSTD1.__java_pool_size=0
TESTDBSTD1.__large_pool_size=16777216
TESTDBSTD1.__oracle_base='/u01/app/oracle'#ORACLE_BASE set from environment
TESTDBSTD1.__pga_aggregate_target=536870912
TESTDBSTD1.__sga_target=1577058304
TESTDBSTD1.__shared_io_pool_size=0
TESTDBSTD1.__shared_pool_size=956301312
TESTDBSTD1.__streams_pool_size=0
TESTDBSTD1.__unified_pga_pool_size=0
*.audit_file_dest='/u01/app/oracle/admin/TESTDBSTD1/adump'
*.audit_trail='db'
*.compatible='19.0.0'
*.control_files='/u01/app/oracle/oradata/TESTDBSTD1/control01.ctl','/u01/app/oracle/oradata/TESTDBSTD1/control02.ctl'
*.db_block_size=8192
*.db_create_online_log_dest_1='/u01/app/oracle/oradata/'
*.db_file_name_convert='/u01/app/oracle/oradata/PRITESTDB/','/u01/app/oracle/oradata/TESTDBSTD1/'
*.db_name='PRITESTD'
*.db_recovery_file_dest_size=10737418240
*.db_recovery_file_dest='/u01/app/oracle/fast_recovery_area/'
*.db_unique_name='TESTDBSTD1'
*.diagnostic_dest='/u01/app/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=PRITESTDBXDB)'
*.enable_pluggable_database=true
*.fal_client='TESTDBSTD1'
*.fal_server='PRITESTDB'
*.local_listener='(ADDRESS=(PROTOCOL=TCP)(HOST=TESTDB-STD1)(PORT=1521))'
*.log_archive_config='dg_config=(PRITESTDB,TESTDBSTD1,TESTDBSTD2)'
*.log_archive_dest_1='LOCATION=/u01/app/oracle/fast_recovery_area/TESTDBSTD1/archivelog/ valid_for=(all_logfiles,all_roles) db_unique_name=TESTDBSTD1'
*.log_archive_dest_2='service=PRITESTDB async valid_for=(online_logfiles,primary_role) db_unique_name=PRITESTDB'
*.log_archive_dest_3='service=TESTDBSTD2 async valid_for=(standby_logfiles,standby_role) db_unique_name=TESTDBSTD2'
*.log_archive_dest_state_3='ENABLE'
*.log_file_name_convert='/u01/app/oracle/oradata/PRITESTDB/','/u01/app/oracle/oradata/TESTDBSTD1/'
*.nls_language='AMERICAN'
*.nls_territory='AMERICA'
*.open_cursors=300
*.pga_aggregate_target=500m
*.processes=5000
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=1500m
*.standby_file_management='AUTO'
*.undo_tablespace='UNDOTBS1'

Create the below directory on STANDBY DB 1

[oracle@TESTDBSTD1 dbs]$ mkdir -p /u01/app/oracle/admin/TESTDBSTD1/adump
[oracle@TESTDBSTD1 dbs]$ mkdir -p /u01/app/oracle/oradata/TESTDBSTD1/
[oracle@TESTDBSTD1 dbs]$ mkdir -p /u01/app/oracle/oradata/
[oracle@TESTDBSTD1 dbs]$ mkdir -p /u01/app/oracle/oradata/PRITESTDB/
[oracle@TESTDBSTD1 dbs]$ mkdir -p /u01/app/oracle/fast_recovery_area/
[oracle@TESTDBSTD1 dbs]$ mkdir -p /u01/app/oracle/fast_recovery_area/TESTDBSTD1/archivelog/

Backup the Primary database and transfer backup file into the Startup database server 1 & restore on it.

[oracle@TESTDBSTD1 ~]$ ls
arch_PRITESTD_20250215_7.bck controlstby.ctl df_PRITESTD_20250215_5.bck df_PRITESTD_20250215_6.bck

Restore on Standby DB 1

On Standby database TESTDBSTD1

Startup database in nomount mode.

SQL> startup nomount;
ORACLE instance started.

Total System Global Area 1577056568 bytes
Fixed Size 9144632 bytes
Variable Size 956301312 bytes
Database Buffers 603979776 bytes
Redo Buffers 7630848 bytes
[oracle@TESTDB-STD1 fulldb_bkp]$ rman target /

Recovery Manager: Release 19.0.0.0.0 - Production on Sat Feb 15 16:21:42 2025
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved.
connected to target database: PRITESTD (DBID=2511388085, not open)

RMAN> restore controlfile from '/u01/app/oracle/backup/rman/fulldb_bkp/controlstby.ctl'
RMAN> alter database mount;
RMAN> catalog start with '/u01/app/oracle/backup/rman/fulldb_bkp/';

RMAN> run {
2> set newname for database to '/u01/app/oracle/oradata/TESTDBSTD1/%b';
3> restore database;
4> switch datafile all;
5> }

Start recovery process of database

SQL> alter database recover managed standby database using current logfile disconnect from session;
Database altered.

Check the archivelog applied process.

SQL> select process, status, thread#, sequence#, block#, blocks from v$managed_standby ;
SQL> select thread#, max(sequence#) FROM v$archived_log where applied='YES' group by thread#;

Check the process of applied archive log and sync of database.

SQL> @stbytest.sql;

PROCESS   STATUS     THREAD#    SEQUENCE#   BLOCK#       BLOCKS
--------- ------------ ---------- ------------------------------
ARCH    CLOSING         1          327         1           1
DGRD    ALLOCATED       0          0           0           0
DGRD    ALLOCATED       0          0           0           0
ARCH    CLOSING         1          327         1           1
ARCH    CLOSING         1          326         1           7
ARCH    CLOSING         1          314         1           1
RFS     IDLE            1          0           0           0
LNS     WRITING         1          328         157         1
RFS     IDLE            1          0           0           0
RFS     IDLE            0          0           0           0
RFS     IDLE            0          0           0           0
RFS     IDLE            0          0           0           0
MRP0    APPLYING_LOG    1          328         157         204800
DGRD    ALLOCATED       0          0           0           0
RFS     IDLE            1          328         1           1

15 rows selected.

THREAD# MAX(SEQUENCE#)
---------- --------------
1 327

Configure the STANDBY DATABASE 2: TESTDBSTD2

Create a pfile

vi initTESTDBSTD2.ora

TESTDBSTD2.__data_transfer_cache_size=0
TESTDBSTD2.__db_cache_size=1090519040
TESTDBSTD2.__inmemory_ext_roarea=0
TESTDBSTD2.__inmemory_ext_rwarea=0
TESTDBSTD2.__java_pool_size=0
TESTDBSTD2.__large_pool_size=16777216
TESTDBSTD2.__oracle_base='/u01/app/oracle'#ORACLE_BASE set from environment
TESTDBSTD2.__pga_aggregate_target=536870912
TESTDBSTD2.__sga_target=1577058304
TESTDBSTD2.__shared_io_pool_size=83886080
TESTDBSTD2.__shared_pool_size=369098752
TESTDBSTD2.__streams_pool_size=0
TESTDBSTD2.__unified_pga_pool_size=0
*.audit_file_dest='/u01/app/oracle/admin/TESTDBSTD2/adump'
*.audit_trail='db'
*.compatible='19.0.0'
*.control_files='/u01/app/oracle/oradata/TESTDBSTD2/control01.ctl','/u01/app/oracle/oradata/TESTDBSTD2/control02.ctl'
*.db_block_size=8192
*.db_create_online_log_dest_1='/u01/app/oracle/oradata/'
*.db_file_name_convert='/u01/app/oracle/oradata/TESTDBSTD1/','/u01/app/oracle/oradata/TESTDBSTD2/'
*.db_name='PRITESTD'
*.db_recovery_file_dest_size=10737418240
*.db_recovery_file_dest='/u01/app/oracle/fast_recovery_area/'
*.db_unique_name='TESTDBSTD2'
*.diagnostic_dest='/u01/app/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=PRITESTDBXDB)'
*.enable_pluggable_database=true
*.fal_client='TESTDBSTD2'
*.fal_server='TESTDBSTD1'
*.log_archive_config='dg_config=(PRITESTDB,TESTDBSTD1,TESTDBSTD2)'
*.log_archive_dest_1='LOCATION=/u01/app/oracle/fast_recovery_area/TESTDBSTD2/archivelog/ valid_for=(all_logfiles,all_roles) db_unique_name=TESTDBSTD2'
*.log_archive_dest_3='service=TESTDBSTD1 async valid_for=(standby_logfiles,standby_role) db_unique_name=TESTDBSTD1'
*.log_archive_dest_state_3='ENABLE'
*.log_file_name_convert='/u01/app/oracle/oradata/TESTDBSTD1/','/u01/app/oracle/oradata/TESTDBSTD2/'
*.nls_language='AMERICAN'
*.nls_territory='AMERICA'
*.open_cursors=300
*.pga_aggregate_target=500m
*.processes=5000
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=1500m
*.standby_file_management='AUTO'
*.undo_tablespace='UNDOTBS1'

Create the below directory on STANDBY DB 2

[oracle@TESTDB-STD2 ~]$ mkdir -p /u01/app/oracle/admin/TESTDBSTD2/adump
[oracle@TESTDB-STD2 ~]$ mkdir -p /u01/app/oracle/oradata/TESTDBSTD2/
[oracle@TESTDB-STD2 ~]$ mkdir -p /u01/app/oracle/fast_recovery_area/
[oracle@TESTDB-STD2 ~]$ mkdir -p /u01/app/oracle/fast_recovery_area/TESTDBSTD2/archivelog/
[oracle@TESTDB-STD2 ~]$ mkdir -p /u01/app/oracle/oradata/TESTDBSTD2/

Backup the Primary database and transfer into the Startup database server 1 & restore on it.

[oracle@TESTDB-STD2 ~]$ ls
arch_PRITESTD_20250215_7.bck controlstby.ctl df_PRITESTD_20250215_5.bck df_PRITESTD_20250215_6.bck

Restore on Standby DB Server 1

On Standby database TESTDBSTD1

Startup database in nomount mode:

SQL> startup nomount;
ORACLE instance started.

Total System Global Area 1577056568 bytes
Fixed Size 9144632 bytes
Variable Size 956301312 bytes
Database Buffers 603979776 bytes
Redo Buffers 7630848 bytes
[oracle@TESTDB-STD2 ~]$ rman target /

Recovery Manager: Release 19.0.0.0.0 - Production on Sun Feb 16 10:26:53 2025
Version 19.3.0.0.0
Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved.
connected to target database: PRITESTD (not mounted)

RMAN> restore controlfile from '/u01/app/oracle/backup/rman/fulldb_bkp/controlstby.ctl'
RMAN> alter database mount;
RMAN> crosscheck backup;
RMAN> delete noprompt expired backup;
RMAN> crosscheck archivelog all;
RMAN> delete noprompt expired archivelog all;
RMAN> catalog start with '/u01/app/oracle/backup/rman/fulldb_bkp/';
RMAN> run {
2> set newname for database to '/u01/app/oracle/oradata/TESTDBSTD2/%b';
3> restore database;
4> switch datafile all;
5> }

Start recovery process of database

SQL> alter database recover managed standby database using current logfile disconnect from session;
Database altered.

Check the archivelog applied process.

SQL> select process, status, thread#, sequence#, block#, blocks from v$managed_standby ;
SQL> select thread#, max(sequence#) FROM v$archived_log where applied='YES' group by thread#;

Check the process of applied archive log and sync of database.

SQL> @/home/oracle/scripts/stbytest.sql;

PROCESS    STATUS         THREAD#     SEQUENCE#      BLOCK#    BLOCKS
--------- ------------------------------------------------------------
ARCH       CLOSING          1            325            1         1
DGRD       ALLOCATED        0            0              0         0
DGRD       ALLOCATED        0            0              0         0
ARCH       CLOSING          1            327            1         1
ARCH       CLOSING          1            326            1         7
ARCH       CLOSING          1            324            1         1
MRP0       APPLYING_LOG     1            328            157       204800
RFS        IDLE             1            0              0         0
RFS        IDLE             1            328            157       1
RFS        IDLE             0            0              0         0
RFS        IDLE             0            0              0         0
RFS        IDLE             0            0              0         0
LNS        CONNECTED        0            0              0         0
LNS        WRITING          1            328            1         1

14 rows selected.

THREAD# MAX(SEQUENCE#)
———- ————–
1 327

Therefore, I have configured the cascading standby database.

====Hence tested and verified in our test env=====

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>