Oracle Data Guard 19c Deployment Series from Zero to Fast Failover part 6 standby broker

So Far

Up to this point, we have completed the following steps:

In this part, we implement Data Guard along with Data Guard Broker.
Fast-Start Failover and Observer will be explained in the next article.


Topology and Environment Information

As you have seen in the previous five parts, our environment has been set up as follows, and the Data Guard configuration will be based on this topology:

Primary Database : vahiddb
Primary Host     : dc1          (192.168.56.21)
Standby Database : vahiddbdc2
Standby Host     : dc2          (192.168.56.22)
DB_NAME          : vahiddb
ORACLE_HOME      : /u01/app/oracle/product/19c/dbhome

  • On dc1, the database vahiddb has already been created using DBCA

  • On dc2, no database exists yet, and we will create the Standby database


Primary-Side Prerequisites (dc1)

As the oracle user, add the following parameters to the file:

/home/oracle/.bash_profile

export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=/u01/app/oracle/product/19c/dbhome
export LD_LIBRARY_PATH=/u01/app/oracle/product/19c/dbhome/lib
export ORACLE_SID=vahiddb
export PATH=$PATH:$ORACLE_HOME/bin

After saving the file, apply the changes using the following command, or alternatively open a new session:

source ~/.bash_profile

Then connect to the database:

sqlplus / as sysdba

2.1 Enabling ARCHIVELOG and FORCE LOGGING

SQL> SELECT log_mode FROM v$database;

If the result is NOARCHIVELOG:

SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;

Strongly recommended:

ALTER DATABASE FORCE LOGGING;
3. Configuring Data Guard Parameters on the Primary
ALTER SYSTEM SET standby_file_management='AUTO' SCOPE=BOTH;

Important note:
The unique name of the Primary database remains vahiddb.


4. Creating Standby Redo Logs

The number of Standby Redo Log groups must be one more than the number of Online Redo Log groups, and their size must be the same.

First, run the following query to check the current redo log configuration:

SELECT * FROM v$log;

Based on the output below, since we have 3 online redo log groups, we create 4 standby redo log groups:

ALTER DATABASE ADD STANDBY LOGFILE GROUP 10 SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 11 SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 12 SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 13 SIZE 200M;

5. Enabling Flashback Database (Required for REINSTATE)

This step is mandatory before any failover operation.
Enable Flashback only if you plan to reinstate the old standby database after failover.

In previous steps, db_recovery_file_dest and db_recovery_file_dest_size were already configured.
If they are not

SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE FLASHBACK ON;
ALTER DATABASE OPEN;

Verify Flashback status:

SELECT flashback_on FROM v$database;

Expected output:

YES

How Much Space Is Required for Flashback?

Based on practical experience:

  • Flashback size should be 2× to 3× daily redo generation

  • Production environments typically require 30 GB to 200 GB, depending on workload

  • For lab and test environments, 50 GB is usually sufficient

If Flashback is not enabled, the REINSTATE DATABASE command cannot be used, and the Standby must be rebuilt from scratch.


6. Preparing the Standby Server (dc2)

6.1 Creating a PFILE from the Primary SPFILE (on dc1)

sqlplus / as sysdba
SQL> CREATE pfile='/home/oracle/pfile_for_standby.ora' FROM spfile;

This file contains all Primary database parameters and will be modified for the Standby.


6.2 Transferring the PFILE to the Standby Server

On dc1:

scp /home/oracle/pfile_for_standby.ora oracle@dc2:/home/oracle/

6.3 Transferring the Primary Password File

  1. First, check whether a password file is registered:

srvctl config database -db vahiddb

Look for the Password file entry.

  • If it exists, transfer it

  • In this case, no password file is registered

So we locate it manually:

ls $ORACLE_HOME/dbs/orapw*

If it does not exist, create it:

orapwd file=$ORACLE_HOME/dbs/orapwvahiddb password=MyPass123 entries=10

Transfer it to the Standby server:

scp $ORACLE_HOME/dbs/orapwvahiddb oracle@dc2:$ORACLE_HOME/dbs/orapwvahiddbdc2

6.4 Configuring the Standby Environment

Edit the oracle user’s .bash_profile on dc2:

export ORACLE_SID=vahiddbdc2
export ORACLE_HOME=/u01/app/oracle/product/19c/dbhome
export PATH=$ORACLE_HOME/bin:$PATH
export LD_LIBRARY_PATH=$ORACLE_HOME/lib

Apply the changes:

source ~/.bash_profile

6.5 Editing the PFILE for Standby-Specific Parameters

Open /home/oracle/pfile_for_standby.ora and modify the parameters as described.

(Parameters marked --remove must be deleted; others must be adjusted for the Standby.)

[Original parameters omitted here for brevity — retain exactly as shown in the Persian text]

Key changes include:

1) db_unique_name

*.db_unique_name='vahiddbdc2'

Primary remains vahiddb.

Add the same service name as the Primary:

*.service_names='vahiddb'

2) ASM File Destinations

*.db_create_file_dest='+DATA'
*.db_recovery_file_dest='+DATA'
*.db_recovery_file_dest_size=20G

3) File Name Conversion

*.log_file_name_convert='+DATA/VAHIDDB/','+DATA/VAHIDDBDC2/'
*.db_file_name_convert='+DATA/VAHIDDB/','+DATA/VAHIDDBDC2/'

Adjust paths if your ASM disk group names differ.

after completing editing it looks like this:

*.audit_file_dest='/u01/app/oracle/admin/vahiddbdc2/adump'
*.audit_trail='db'
*.compatible='19.0.0'
*.control_files='+DATA/VAHIDDBDC2/CONTROLFILE/current.278.1217810713','+DATA/VAHIDDBDC2/CONTROLFILE/current.289.1217810713'
*.db_block_size=8192
*.db_create_file_dest='+DATA'
*.db_name='vahiddb'
*.db_recovery_file_dest='+DATA'
*.db_recovery_file_dest_size=15g
*.diagnostic_dest='/u01/app/oracle'
*.enable_pluggable_database=true
*.log_archive_format='%t_%s_%r.dbf'
*.nls_language='AMERICAN'
*.nls_territory='AMERICA'
*.open_cursors=300
*.pga_aggregate_target=1554m
*.processes=320
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=4662m
*.standby_file_management='AUTO'
*.undo_tablespace='UNDOTBS1'
*.db_unique_name='vahiddbdc2'
*.service_names='vahiddb'
*.log_file_name_convert='+DATA/VAHIDDB/','+DATA/VAHIDDBDC2/'
*.db_file_name_convert='+DATA/VAHIDDB/','+DATA/VAHIDDBDC2/'

4) Standby File Management

*.standby_file_management='AUTO'

6.6 Creating the SPFILE on the Standby

Start the database in NOMOUNT mode using the PFILE:

sqlplus / as sysdba
SQL> STARTUP NOMOUNT pfile='/home/oracle/pfile_for_standby.ora';

Create the SPFILE:

SQL> CREATE spfile='+DATA/VAHIDDBDC2/PARAMETERFILE/spfile.ora'
     FROM pfile='/home/oracle/pfile_for_standby.ora';

Shut down the database:

SQL> SHUTDOWN IMMEDIATE;

6.8 Registering the Standby Database with Clusterware

On dc2:

srvctl add database -db vahiddbdc2 \
 -oraclehome $ORACLE_HOME \
 -spfile +DATA/VAHIDDBDC2/PARAMETERFILE/spfile.ora \
 -pwfile /u01/app/oracle/product/19c/dbhome/dbs/orapwvahiddbdc2 \
 -role PHYSICAL_STANDBY \
 -dbname vahiddb

Parameter Explanation

  • -db vahiddbdc2 → Database name in Clusterware

  • -dbname vahiddb → Actual database name

  • -role PHYSICAL_STANDBY → Database role

  • -spfile, -pwfile → ASM locations

Verify:

srvctl config database -db vahiddbdc2

7. Static Listener Registration (Both Servers)

Edit listener.ora under Grid Infrastructure ORACLE_HOME (set ORACLE_SID=+ASM).

listener cannot dynamically register a database that is not yet open or is in a transitional state (MOUNT, NOMOUNT, role transition).

Since the listener is managed under Grid Infrastructure, all changes must be made in the Grid listener environment.


Step 1: Switch to ASM Environment

On each server, first switch the environment to ASM using oraenv:

[oracle@dc1 ~]$ . oraenv
ORACLE_SID = [vahiddb] ? +ASM
The Oracle base remains unchanged with value /u01/app/oracle

This ensures that you are editing the Grid Infrastructure listener, not the database listener.


Step 2: Edit listener.ora

Edit the listener configuration file located under the Grid Infrastructure ORACLE_HOME:

vi $ORACLE_HOME/network/admin/listener.ora

Static Registration on Primary Server (dc1)

Add the following entry to listener.ora on dc1:

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = vahiddb)
      (ORACLE_HOME = /u01/app/oracle/product/19c/dbhome)
      (SID_NAME = vahiddb)
    )
  )

Explanation:

  • GLOBAL_DBNAME
    The service name used by Data Guard Broker and clients.

  • ORACLE_HOME
    Database Oracle Home (not Grid Home).

  • SID_NAME
    Instance SID of the Primary database.


Static Registration on Standby Server (dc2)

Add the following entry to listener.ora on dc2:

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = vahiddbdc2)
      (ORACLE_HOME = /u01/app/oracle/product/19c/dbhome)
      (SID_NAME = vahiddbdc2)
    )
  )

Restart the listener:

lsnrctl reload

Why Static Registration Is Required

  • During startup, failover, switchover, and broker operations, the database may be in MOUNT or NOMOUNT state.

  • In these states, dynamic registration does not occur.

  • Data Guard Broker relies on static listener entries to connect reliably.

  • Without static registration, Broker may fail with:

    • ORA-12514: TNS:listener does not currently know of service requested

    • Inconsistent Broker status during role transitions.

For this reason, static listener registration is strongly recommended for all Data Guard configurations that use Broker.

TNS Configuration (Both Servers)

Edit or create:

$ORACLE_HOME/network/admin/tnsnames.ora

Correct example:

vahiddb =
 (DESCRIPTION =
  (ADDRESS = (PROTOCOL = TCP)(HOST = dc1.vahiddb.com)(PORT = 1521))
  (CONNECT_DATA =
    (SERVER = DEDICATED)
    (SERVICE_NAME = vahiddb)
  )
 )

vahiddbdc2 =
 (DESCRIPTION =
  (ADDRESS = (PROTOCOL = TCP)(HOST = dc2.vahiddb.com)(PORT = 1521))
  (CONNECT_DATA =
    (SERVER = DEDICATED)
    (SERVICE_NAME = vahiddbdc2)
    (UR=A)
  )
 )

 

 

UR=A means:
Use Remote Listener for asynchronous connect-time load balancing


9. Creating the Standby Using RMAN Active Duplicate

On dc2:

srvctl start database -d vahiddbdc2 -o nomount

On dc1:

rman target sys@vahiddb auxiliary sys@vahiddbdc2

Run in RMAN:

run {
 allocate auxiliary channel ac1 device type disk;
 allocate auxiliary channel ac2 device type disk;
 allocate channel c1 device type disk;
 allocate channel c2 device type disk;
 allocate channel c3 device type disk;
 allocate channel c4 device type disk;
 DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE
   DORECOVER NOFILENAMECHECK;
}

 

10. Enabling Data Guard Broker

On both servers:

ALTER SYSTEM SET dg_broker_start=TRUE SCOPE=BOTH;

10.1 Creating the Broker Configuration

dgmgrl
CONNECT sys@vahiddb

CREATE CONFIGURATION dg_vahiddb
 AS PRIMARY DATABASE IS vahiddb
 CONNECT IDENTIFIER IS vahiddb;

ADD DATABASE vahiddbdc2
 AS CONNECT IDENTIFIER IS vahiddbdc2
 MAINTAINED AS PHYSICAL;

ENABLE CONFIGURATION;

11. Important Broker Settings (Without FSFO)

11.1 Enable Apply

EDIT DATABASE vahiddbdc2 SET STATE='APPLY-ON';
ENABLE CONFIGURATION;

11.2 File Management

EDIT DATABASE vahiddbdc2 SET PROPERTY StandbyFileManagement='AUTO';

12. Switchover

VALIDATE DATABASE vahiddb;
VALIDATE DATABASE vahiddbdc2;
SWITCHOVER TO vahiddbdc2;

13. Manual Failover

Ensure Flashback is enabled on both databases:

SELECT flashback_on FROM v$database;

If not enabled, enable it as described earlier.

FAILOVER TO vahiddbdc2;

14. Reinstating the Former Primary

After dc1 comes back online connect to dc2 and dgmgrl

SHOW DATABASE vahiddb;

ORA-16661: the standby database needs to be reinstated

Run:

REINSTATE DATABASE vahiddb;

Video Link

YouTube link for this part in persian


Next Part

Automatic Fast-Start Failover