How to Add a Single Instance Standby Database?
The example commands use the following configuration.
Oracle RDBMS software is installed into the ORACLE_HOME /u01/oracle/db19f on both servers.
The primary single instance database cdbfa runs on the server rkol7db1. This database uses Oracle Managed Files (OMF) for all database files. The database unique name is cdbfa_db1. The database domain is world.
SQL> show parameter db_name
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_name string cdbfa
SQL> show parameter db_unique_name
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_unique_name string cdbfa_db1
SQL> show parameter domain
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_domain string world
SQL> The standby database should run on the server rkol7db2 and use OMF as well. The database unique name will be cdbfa_db2.
Preparing the Primary Database
Set up Primary Database
You have to enable Archivelog mode on the primary database. To avoid possible issues during standby recovery you have to set Force Logging as well. It’s recommended to use Flashback Database especially on the standby database.
SQL> select log_mode, force_logging from v$database;
LOG_MODE FORCE_LOGGING
------------ ---------------------------------------
NOARCHIVELOG NO
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
NOCaution
Changing ARCHIVELOG mode requires restarting the database.
You can set these parameters using the following statements.
Restart the Database And Enable Archivelog
shutdown immediate
startup mount
alter database archivelog;
shutdown immediate
startupEnable Force Logging And Flashback Database
alter database force logging;
alter database flashback on;The current values on the primary database after the changes should be:
SQL> select log_mode, force_logging, flashback_on from v$database;
LOG_MODE FORCE_LOGGING FLASHBACK_ON
------------ --------------------------------------- ------------------
ARCHIVELOG YES YESParameter STANDBY_FILE_MANAGEMENT
In most cases you would like to manage all files operations on the standby database automatically:
alter system set standby_file_management=auto;
Create Standby Logfiles
You have to add standby logfiles to the primary database. Every thread should have one more standby logfile as online redo logfile.
select thread# thr, group# grp, bytes from v$log order by 1,2;
...
alter database add standby thread ... logfile ... size ...
...
select thread#, group#, bytes from v$standby_log order by 1, 2;So will will run on the primary database:
SQL> select thread# thr, group# grp, bytes from v$log order by 1,2;
THR GRP BYTES
---------- ---------- ----------
1 1 209715200
1 2 209715200
1 3 209715200
SQL> alter database add standby logfile size 209715200;
Database altered.
...
SQL> select thread#, group#, bytes from v$standby_log order by 1, 2;
THREAD# GROUP# BYTES
---------- ---------- ----------
0 4 209715200
0 5 209715200
0 6 209715200
0 7 209715200You can drop a standby logfile with one of the following statements:
alter database drop standby logfile member 'LogfilePath'alter database drop standby logfile group NN
Network files:
LISTENER.ORA
Usually on RAC you don’t have to add any entry. But this example is for the single instance database. If you don’t have working listener.ora and sqlnet.ora files, you can create them using the netca utility:
oracle@rkol7db1> cd $ORACLE_HOME/network/admin
oracle@rkol7db1> netca -silent -responsefile $ORACLE_HOME/assistants/netca/netca.rsp
Parsing command line arguments:
Parameter "silent" = true
Parameter "responsefile" = /u01/oracle/db19f/assistants/netca/netca.rsp
Done parsing command line arguments.
Oracle Net Services Configuration:
Profile configuration complete.
Oracle Net Listener Startup:
Running Listener Control:
/u01/oracle/db19f/bin/lsnrctl start LISTENER
Listener Control complete.
Listener started successfully.
Listener configuration complete.
Oracle Net Services configuration successful. The exit code is 0Now you should add the new entry using corresponing ORACLE_SID, ORACLE_HOME and the database GLOBAL_NAME values to the listener.ora file.
...
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME=cdbfa)
(ORACLE_HOME=/u01/oracle/db19f)
(GLOBAL_DBNAME=cdbfa_db1_DGMGRL.world)
)
)
...Use lsnrctl reload to load the new configuration to the listener.
You should use the listener.ora and sqlnet.ora on the primary database as a template to create corresponding files on the standby database.
This is a listener.ora file on the new standby database host rkol7db2:
# listener.ora Network Configuration File: /u01/oracle/db19f/network/admin/listener.ora
# Generated by Oracle configuration tools.
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rkol7db2)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME=cdbfa)
(ORACLE_HOME=/u01/oracle/db19f)
(GLOBAL_DBNAME=cdbfa_db2_DGMGRL.world)
)
)The differences to the primary database are:
- Hostname rkol7db2 instead of rkol7db1
- Global database name cdbfa_db2_DGMGRL.world instead of cdbfa_db1_DGMGRL.wolrd
You have to start or reload the listener on the standby database now.
TNSNAMES.ORA
We want to use RMAN to duplicate the primary database to the standby database. We will add the corresponding RMAN TNS aliases to the tnsnames.ora file.
cdbfa_db1_rman =
(DESCRIPTION =
(ADDRESS = (PROTOCOL=TCP)(HOST=rkol7db1)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SID = cdbfa)
)
)
cdbfa_db2_rman =
(DESCRIPTION =
(ADDRESS = (PROTOCOL=TCP)(HOST=rkol7db2)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SID = cdbfa)
)
)You should copy these TNS aliases to the standby database tnsnames.ora file.
INIT.ORA
Now you should create a PFILE from the primary database SPFILE. You can use this file as a template for the standby database PFILE.
oracle@rkol7db1> mkdir -p /home/oracle/tests/data_guard/primary
oracle@rkol7db1> cd /home/oracle/tests/data_guard/primary
oracle@rkol7db1> sqlplus / as sysdba
...
SQL> create pfile='/home/oracle/tests/data_guard/primary/init.ora.primary' from spfile;
File created.Clearing Logfiles In the Standby Database.
Before starting the recovery apply on the standby database we would like to clear the online and standby logfiles. This would re-create them in OMF configuration. We can generate the script for this taks on the primary database.
set echo on pagesi 1000 linesi 255 trimsp on
spool clear_logfiles.log
select distinct 'alter database clear logfile group ' || group# || ';' from v$logfile order by 1;
spool offCopy Files to Standby.
On the host rkol7db2:
oracle@rkol7db2> mkdir -p /home/oracle/tests/data_guard/standby
You should now copy the following files to the standby server rkol7db2 directory /home/oracle/tests/data_guard/standby from the current directory /home/oracle/tests/data_guard/primary on the primary server rkol7db1:
- init.ora.primary
- database password file from $ORACLE_HOME/dbs
- clear_logfiles.log file with online and standby redo logs.
oracle@rkol7db1> cd /home/oracle/tests/data_guard/primary
oracle@rkol7db1> scp init.ora.primary rkol7db2:/home/oracle/tests/data_guard/standby
init.ora.primary 100% 1253 1.5MB/s 00:00
oracle@rkol7db1> scp clear_logfiles.log rkol7db2:/home/oracle/tests/data_guard/standby
clear_logfiles.log 100% 543 652.1KB/s 00:00
oracle@rkol7db1> scp $ORACLE_HOME/dbs/orapwcdbfa rkol7db2:/home/oracle/tests/data_guard/standby
orapwcdbfa 100% 2048 3.0MB/s 00:00 For RAC/ASM you could use asmcmd cp command to copy the password file from ASM to the local file system.
Create Standby Database
Before doing the following steps, please check the environment variables ORACLE_HOME and ORACLE_BASE.
Prepare INIT.ORA
On the server rkol7db2:
cd /home/oracle/tests/data_guard/standby
cp init.ora.primary init.ora.standby
In the file init.ora.standby you should check and maybe modify at least the following parameters:
- audit_file_dest
- db_create_file_dest
- db_file_name_convert
- db_recovery_file_dest
- db_create_online_log_dest_xxx
- db_unique_name=cdbfa_db2
- log_file_name_convert
- cluster_interconnects
- Comment out control files (control_file).
We are going to use Oracle managed files (OMF) on the standby database as well. That’s why you usually don’t need to set the parameters db_file_name_convert and log_file_name_convert.
Please check, if you have to create the corresponding directories:
- audit_file_dest
- db_create_file_dest
- db_recovery_file_dest
These are the modified parameters in init.ora.standby for the new standby database cdbfa_db2:
*.audit_file_dest='/u01/oracle/admin/cdbfa_db2/adump'
...
#*.control_files='/u01/oracle/databases/db19/CDBFA_DB1/controlfile/o1_mf_mhv7b60r_.ctl','/u01/oracle/databases/fra/CDBFA_DB1/controlfile/o1_mf_mhv7b64j_.ctl'
...
*.db_create_file_dest='/u01/oracle/databases/db19'
...
*.db_recovery_file_dest='/u01/oracle/databases/fra'
...
*.db_unique_name='cdbfa_db2'In this case the folllowing directories must be created:
mkdir -p /u01/oracle/admin/cdbfa_db2/adump
mkdir -p /u01/oracle/databases/db19
mkdir -p /u01/oracle/databases/fraSingle Instance
You can start now the new instance in the NOMOUNT mode and create a new SPFILE using the init.ora.standby file.
oracle@rkol7db2> cp orapwcdbfa $ORACLE_HOME/dbs
oracle@rkol7db2> export ORACLE_SID=cdbfa
sracle@rkol7db2> sqlplus / as sysdba
...
SQL> startup nomount pfile='/home/oracle/tests/data_guard/standby/init.ora.standby'
...
SQL> create spfile from pfile='/home/oracle/tests/data_guard/standby/init.ora.standby';
File created.
SQL> shutdown abort
ORACLE instance shut down.
SQL> startup nomount
...RAC
- RAC: Create database configuration (srvctl + asmcmd).
- Start instance using the pfile and create the spfile.
- Create or copy the password file.
- Startup instance in nomount mode
Restore Primary Database To the Standby Database
Easy Connect Naming allows to run all commands without any new TNS aliases in the tnsnames.ora.
We will use RMAN feature “Restoring Data Files Over the Network” for the RMAN RESTORE.
Create standby control files with RMAN using service:
oracle@rkol7db2> cat restore_cf.rman
connect target /
restore standby controlfile from service 'rkol7db1/cdbfa_db1.world';
exit;
oracle@rkol7db2> rman @restore_cf.rman
...
RMAN> connect target *
2> restore standby controlfile from service 'rkol7db1/cdbfa_db1.world';
3> exit;
connected to target database: CDBFA (not mounted)
...
output file name=/u01/oracle/databases/db19/CDBFA_DB2/controlfile/o1_mf_n239lhjw_.ctl
output file name=/u01/oracle/databases/fra/CDBFA_DB2/controlfile/o1_mf_n239lhno_.ctl
Finished restore at 12-MAY-25
Recovery Manager complete.
oracle@rkol7db2> Now we have to mount the standby database:
sqlplus / as sysdba
alter database mount;
exitRestore database with RMAN using service:
oracle@rkol7db2> cat restore_db.rman
connect target /
run
{
allocate channel t1 device type disk;
allocate channel t2 device type disk;
restore database from service 'rkol7db1/cdbfa_db1.world'
section size 256m;
}
exit;
oracle@rkol7db2> rman @restore_db.rman
Recovery Manager: Release 19.0.0.0.0 - Production on Mon May 12 09:46:40 2025
Version 19.24.0.0.0
Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved.
RMAN> connect target *
2> run
3> {
4> allocate channel t1 device type disk;
5> allocate channel t2 device type disk;
6>
7> restore database from service 'rkol7db1/cdbfa_db1.world'
8> section size 256m;
9> }
10> exit;
connected to target database: CDBFA (DBID=898928678, not open)
using target database control file instead of recovery catalog
allocated channel: t1
channel t1: SID=12 device type=DISK
allocated channel: t2
channel t2: SID=258 device type=DISK
Starting restore at 12-MAY-25
Starting implicit crosscheck backup at 12-MAY-25
Finished implicit crosscheck backup at 12-MAY-25
Starting implicit crosscheck copy at 12-MAY-25
Finished implicit crosscheck copy at 12-MAY-25
searching for all files in the recovery area
cataloging files...
no files cataloged
channel t1: starting datafile backup set restore
channel t1: using network backup set from service rkol7db1/cdbfa_db1.world
channel t1: specifying datafile(s) to restore from backup set
channel t1: restoring datafile 00001 to /u01/oracle/databases/db19/CDBFA_DB2/datafile/o1_mf_system_n239v22y_.dbf
channel t1: restoring section 1 of 6
channel t2: starting datafile backup set restore
channel t2: using network backup set from service rkol7db1/cdbfa_db1.world
channel t2: specifying datafile(s) to restore from backup set
channel t2: restoring datafile 00003 to /u01/oracle/databases/db19/CDBFA_DB2/datafile/o1_mf_sysaux_n239v24y_.dbf
channel t2: restoring section 1 of 4
...
channel t1: restoring datafile 00008 to /u01/oracle/databases/db19/CDBFA_DB2/238481C02E841B13E0630107A8C01C2B/datafile/o1_mf_undotbs1_n239wxqf_.dbf
channel t1: restoring section 2 of 2
channel t1: restore complete, elapsed time: 00:00:01
channel t2: restore complete, elapsed time: 00:00:04
Finished restore at 12-MAY-25
released channel: t1
released channel: t2
Recovery Manager complete.The restore performance and network load depend on the number of allocated channels and the value of SECTION SIZE parameter.
Clear logfiles in the standby control file.
We have already prepared the file clear_logfiles.log with ALTER DATABASE commands for all online and standby redo logs. Using this file we can prepare and ran the script clear_logfiles.sql to clear the redo logs.
Caution
DO NOT RUN THIS SCRIPT ON THE PRIMARY DATABASE. MAKE SURE, YOU ARE CONNECTED TO THE NEW STANDBY DATABASE!!!
Original file from the primary database:
oracle@rkol7db2> cat clear_logfiles.log
SQL>
SQL> select distinct 'alter database clear logfile group ' || group# || ';' from v$logfile order by 1;
'ALTERDATABASECLEARLOGFILEGROUP'||GROUP#||';'
----------------------------------------------------------------------------
alter database clear logfile group 1;
alter database clear logfile group 2;
alter database clear logfile group 3;
alter database clear logfile group 4;
alter database clear logfile group 5;
alter database clear logfile group 6;
alter database clear logfile group 7;
7 rows selected.
SQL>
SQL> spool offexitNew created SQL file based on the clear_logfiles.log :
oracle@rkol7db2> cat clear_logfiles.sql
set echo on
alter database clear logfile group 1;
alter database clear logfile group 2;
alter database clear logfile group 3;
alter database clear logfile group 4;
alter database clear logfile group 5;
alter database clear logfile group 6;
alter database clear logfile group 7;Running this SQL file on the standby database:
oracle@rkol7db2> sqlplus / as sysdba
...
SQL> @clear_logfiles
SQL>
SQL> alter database clear logfile group 1;
Database altered.
...
SQL> alter database clear logfile group 7;
Database altered.
SQL> exitCreate New Data Guard Broker Configuration
Set init.ora Parameters
Set Data Guard database parameters on both primary and standby databases:
alter system set dg_broker_config_file1='/u01/oracle/db19f/dbs/cdbfa_dg.dat1';
alter system set dg_broker_config_file2='/u01/oracle/db19f/dbs/cdbfa_dg.dat2';
alter system set dg_broker_start=true;Set up Data Guard Broker On the Primary Database
dgmgrl / "create configuration cdbfa_dg as primary database is cdbfa_db1 connect identifier is 'rkol7db1:1521/cdbfa_db1.world'"
dgmgrl / "show configuration"
dgmgrl / "add database cdbfa_db2 as connect identifier is 'rkol7db2:1521/cdbfa_db2.world'"
dgmgrl / "show configuration"
dgmgrl / "enable configuration"
dgmgrl / "show configuration"Set Up Max. Availability Protection Mode
Run this commands in Data Guard Broker CLI:
edit database cdbfa_db1 set property LogXptMode=sync;
edit database cdbfa_db2 set property LogXptMode=sync;
edit configuration set protection mode as maxavailability;
show configuration;Run Switchover
Connect to the primary or standby database using listener. Don’t use dgmgrl /, because the database needs to re-connect after restarting the local database.
dgmgrl
connect sys/oracle@rkol7db1/cdbfa_db1.worldRun some checks before starting switchover:
validate static connect identifier for all
show configuration lag
show configurationRun switchover:
switchover to cdbfa_db2