Oracle 19c: Roll Forward a Data Guard Physical Standby (Service-Based Recovery Method)
Assumptions
This instruction assumes:
- Oracle Linux 7.x or 8.x (x86_64) is installed on both primary and standby hosts
- Oracle Database 19c (19.3 or later, any Release Update) is installed on both hosts
- A physical standby database already exists and was previously synchronized with the primary
- The standby has fallen behind with an archive log gap that normal redo transport (FAL_SERVER, log shipping) cannot resolve -- symptoms include:
- Managed Recovery Process (MRP) has stopped or is reporting gap errors in the alert log (e.g.,
FAL[client]: Failed to request gap sequence) V$ARCHIVE_GAPon the standby shows missing archive log sequencesV$DATAGUARD_STATSshows a large transport lag or apply lag- Alert log on the standby contains messages such as
Media Recovery Waiting for thread X sequence Y
- Managed Recovery Process (MRP) has stopped or is reporting gap errors in the alert log (e.g.,
- The primary database is running and accessible (single-instance or RAC)
- The standby database is a single-instance configuration -- if the standby is RAC, only one instance should be running during this procedure
- Oracle Net connectivity exists from the standby host to the primary database (a
tnsnames.oraentry resolves to the primary) -- this was configured when the standby was created - Password files are identical on primary and standby -- if a password change occurred on the primary since the standby fell behind, resync before proceeding
- The COMPATIBLE initialization parameter is set to 12.0 or higher on both databases (required for FROM SERVICE functionality)
- The reader has SYSDBA or SYSBACKUP privilege on both primary and standby databases
- The reader is familiar with RMAN and SQL*Plus
- The Data Guard configuration is managed by Data Guard Broker (DGMGRL)
Prerequisites
Automatic setup
No automatic setup package exists for this task. The recovery is a manual DBA procedure using RMAN.
Manual setup
All commands run as the oracle user on the standby host unless noted otherwise. Set environment variables before proceeding.
- Set environment variables for the standby database
export ORACLE_HOME={ORACLE_HOME}
export ORACLE_SID={STANDBY_SID}
export PATH=$ORACLE_HOME/bin:$PATH
{ORACLE_HOME} -- the Oracle home directory (e.g., /u01/app/oracle/product/19.0.0/dbhome_1).
{STANDBY_SID} -- the SID of the standby database instance (e.g., STBY).
{PRIMARY_SERVICE} -- the Oracle Net service name of the primary database as defined in tnsnames.ora on the standby host (e.g., ORCL_PRIMARY).
{PRIMARY_SID} -- the SID of the primary database instance (e.g., ORCL).
{PRIMARY_HOST} -- the hostname or IP of the primary server.
{STANDBY_DB} -- the DB_UNIQUE_NAME of the standby database (e.g., ORCL_STBY).
- Verify the archive gap exists
Confirm the gap before proceeding. This validates that the procedure is needed.
dgmgrl / as sysdba
DGMGRL> SHOW DATABASE {STANDBY_DB};
Check for Transport Lag and Apply Lag values showing a non-zero gap. The broker status will likely show WARNING or ERROR due to the gap.
For details on the exact missing sequences:
DGMGRL> SHOW DATABASE {STANDBY_DB} 'InconsistentProperties';
Exit DGMGRL and confirm with V$ARCHIVE_GAP:
DGMGRL> EXIT;
sqlplus / as sysdba
SELECT * FROM V$ARCHIVE_GAP;
Expected output:
THREAD# LOW_SEQUENCE# HIGH_SEQUENCE#
------- ------------- --------------
1 145 278
One or more rows confirm missing archive log sequences. If no rows are returned, the standby has no gap and this procedure is not needed.
- Verify Data Guard Broker configuration
dgmgrl / as sysdba
DGMGRL> SHOW CONFIGURATION;
Expected output:
Configuration - {CONFIG_NAME}
Protection Mode: MaxPerformance
Members:
{PRIMARY_DB} - Primary database
{STANDBY_DB} - Physical standby database
Warning: ORA-16809: multiple warnings detected for the member
Fast-Start Failover: Disabled
Configuration Status:
WARNING (status updated XX seconds ago)
{CONFIG_NAME} -- the Data Guard Broker configuration name. {PRIMARY_DB} -- the DB_UNIQUE_NAME of the primary database.
The configuration may show WARNING due to the archive gap. This is expected. Verify the broker recognizes both databases. If the broker is not running or the configuration does not exist, this procedure requires a broker-managed environment.
Also verify Oracle Net connectivity to the primary (the RECOVER command connects over the network):
DGMGRL> SHOW DATABASE {STANDBY_DB};
Confirm the standby database entry exists and the DGConnectIdentifier is reachable. Exit DGMGRL:
DGMGRL> EXIT;
- Ensure the standby database is in MOUNT state
sqlplus / as sysdba
SELECT STATUS FROM V$INSTANCE;
Expected output:
STATUS
------
MOUNTED
If the standby is down, start it in MOUNT mode:
STARTUP MOUNT;
- Stop the Managed Recovery Process (MRP) on the standby
MRP must be stopped before running the recovery command. If MRP is active, the command fails with ORA-01153: an incompatible media recovery is active. (Source: Oracle Data Guard Concepts and Administration, 19c)
dgmgrl / as sysdba
DGMGRL> EDIT DATABASE {STANDBY_DB} SET STATE='APPLY-OFF';
Expected output:
Succeeded.
Verify MRP has stopped:
DGMGRL> SHOW DATABASE {STANDBY_DB};
Confirm Intended State shows APPLY-OFF. Exit DGMGRL:
DGMGRL> EXIT;
Additional setup
No additional setup is required. The RECOVER STANDBY DATABASE FROM SERVICE command handles control file restoration, datafile discovery, and recovery automatically.
Recovery
Warning: This command replaces the standby control file with a copy from the primary. Any RMAN catalog metadata referencing the old standby control file will need re-registration after this procedure. The standby database is unavailable for read-only queries (Active Data Guard) during the entire recovery process.
Step 1: Connect RMAN to the standby database as TARGET
RMAN must connect to the standby database as TARGET. Do not connect to the primary as TARGET.
rman target /
Expected output:
Recovery Manager: Release 19.0.0.0.0 - Production on ...
Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved.
connected to target database: {STANDBY_DB} (DBID=XXXXXXXXXX, not open)
Verify that the connected database shows the standby DB_UNIQUE_NAME and shows not open.
Step 2: Execute the RECOVER STANDBY DATABASE FROM SERVICE command
Warning: This command replaces the standby control file and all datafiles over the network. It is irreversible once started. Ensure you are connected to the standby, not the primary. For multi-terabyte databases, this transfers the entire database and may take hours — plan accordingly.
RECOVER STANDBY DATABASE FROM SERVICE {PRIMARY_SERVICE};
This single command automates the following internal operations:
- Disables flashback database (if enabled)
- Restores the standby control file from the primary (
RESTORE STANDBY CONTROLFILE FROM SERVICE) - Mounts the standby database (
ALTER DATABASE MOUNT STANDBY DATABASE) - Sets new names for datafiles using
DB_FILE_NAME_CONVERT - Restores any new datafiles added to the primary since the standby fell behind (
RESTORE FROM SERVICE datafile) - Catalogs the restored datafile copies and switches to them (
CATALOG DATAFILECOPY,SWITCH DATAFILE ALL) - Recovers the standby database to the primary's current SCN (
RECOVER DATABASE FROM SERVICE) - Restarts the standby instance
Expected output (abbreviated):
Starting recover at ...
using target database control file instead of recovery catalog
...
executing command: ALTER DATABASE FLASHBACK OFF
...
contents of Memory Script:
{
restore standby controlfile from service '{PRIMARY_SERVICE}';
alter database mount standby database;
}
...
Finished restore at ...
...
contents of Memory Script:
{
set newname for datafile 1 to ...
...
restore from service '{PRIMARY_SERVICE}' datafile 1, 2, 3, ...;
catalog datafilecopy ...
switch datafile all;
}
...
contents of Memory Script:
{
recover database from service '{PRIMARY_SERVICE}';
}
...
media recovery complete, elapsed time: 00:05:23
Finished recover at ...
The elapsed time depends on the database size and network throughput between the primary and standby hosts. For large databases over constrained networks, this may take hours. Monitor progress in the RMAN session output or the standby alert log.
Step 3: Verify the recovery completed successfully
After the RMAN command completes, exit RMAN and verify the standby is mounted:
RMAN> EXIT;
sqlplus / as sysdba
SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;
Expected output:
DATABASE_ROLE OPEN_MODE
---------------- --------------------
PHYSICAL STANDBY MOUNTED
Post-recovery
Step 1: Clear standby redo logs (if needed)
After the control file replacement, standby redo logs may show errors when MRP attempts to restart. Check the alert log for messages about standby redo log groups. If errors appear, clear all standby redo log groups.
Query existing standby redo log groups:
SELECT GROUP#, BYTES/1024/1024 AS SIZE_MB, STATUS FROM V$STANDBY_LOG;
Expected output:
GROUP# SIZE_MB STATUS
---------- ------- ----------
4 200 UNASSIGNED
5 200 UNASSIGNED
6 200 UNASSIGNED
7 200 UNASSIGNED
Clear each standby redo log group:
ALTER DATABASE CLEAR LOGFILE GROUP {GROUP_NUMBER};
{GROUP_NUMBER} -- repeat for each standby redo log group number returned by the query above (e.g., 4, 5, 6, 7).
Step 2: Re-enable flashback database (if previously enabled)
The recovery command disables flashback database on the standby. If flashback was enabled before the recovery, re-enable it:
ALTER DATABASE FLASHBACK ON;
Expected output:
Database altered.
If flashback was not previously enabled, skip this step.
Step 3: Restart Managed Recovery Process (MRP)
dgmgrl / as sysdba
DGMGRL> EDIT DATABASE {STANDBY_DB} SET STATE='APPLY-ON';
Expected output:
Succeeded.
The broker restarts MRP and manages redo apply automatically. If the standby was previously open for Active Data Guard (read-only queries), the broker will handle opening the database and starting real-time apply.
Verify the standby state:
DGMGRL> SHOW DATABASE {STANDBY_DB};
Confirm Intended State shows APPLY-ON and Database Status is updating. Exit DGMGRL:
DGMGRL> EXIT;
Validation
Quick check
After MRP has been running for a few minutes, verify the broker shows no warnings:
dgmgrl / as sysdba
DGMGRL> SHOW CONFIGURATION;
Expected output:
Configuration - {CONFIG_NAME}
Protection Mode: MaxPerformance
Members:
{PRIMARY_DB} - Primary database
{STANDBY_DB} - Physical standby database
Fast-Start Failover: Disabled
Configuration Status:
SUCCESS (status updated XX seconds ago)
SUCCESS with no warnings confirms the standby is synchronized and healthy.
Full validation
- Verify standby database status and apply lag
DGMGRL> SHOW DATABASE {STANDBY_DB};
Confirm Database Status shows SUCCESS, Intended State shows APPLY-ON, and Apply Lag shows 0 seconds (or near zero).
- Verify no archive gap exists
sqlplus / as sysdba
SELECT * FROM V$ARCHIVE_GAP;
Expected output:
no rows selected
No rows confirms all archive log sequences are present.
- Verify redo transport is active
DGMGRL> SHOW DATABASE {STANDBY_DB} 'LogXptStatus';
Confirm Log Transport Status shows no errors.
Exit DGMGRL:
DGMGRL> EXIT;
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
ORA-01153: an incompatible media recovery is active |
MRP was not stopped before running the RECOVER command | Stop MRP via the broker: DGMGRL> EDIT DATABASE {STANDBY_DB} SET STATE='APPLY-OFF';. Then re-run the RECOVER command. |
RMAN-05146: must be connected to standby database to issue RECOVER STANDBY DATABASE |
RMAN is connected to the primary database as TARGET instead of the standby | Exit RMAN and reconnect to the standby: rman target / (with ORACLE_SID set to the standby SID). |
ORA-01031: insufficient privileges during RECOVER |
Password file mismatch between primary and standby, or the connecting user lacks SYSDBA/SYSBACKUP | Copy the primary password file to the standby: scp {PRIMARY_HOST}:$ORACLE_HOME/dbs/orapw{PRIMARY_SID} $ORACLE_HOME/dbs/orapw{STANDBY_SID}. Verify with sqlplus sys@{PRIMARY_SERVICE} as sysdba. |
ORA-12154: TNS:could not resolve the connect identifier or network timeout during RECOVER |
The {PRIMARY_SERVICE} in the RECOVER command does not match a valid tnsnames.ora entry, or the primary is unreachable |
Verify connectivity: tnsping {PRIMARY_SERVICE}. Check tnsnames.ora on the standby host. Verify the primary listener is running: lsnrctl status on the primary host. |
| Recovery takes excessively long or appears hung | Large database size combined with limited network bandwidth between primary and standby | Monitor progress in the standby alert log (tail -f $ORACLE_BASE/diag/rdbms/{STANDBY_DB}/{STANDBY_SID}/trace/alert_{STANDBY_SID}.log). The recovery transfers the entire database over the network. For multi-terabyte databases, schedule during a maintenance window with adequate bandwidth. |
ORA-19573: cannot obtain %s enqueue for datafile %s |
A datafile enqueue conflict -- the standby is not properly in MOUNT state, another RMAN session holds a lock, or MRP is still active | Verify the standby is mounted (not open): SELECT OPEN_MODE FROM V$DATABASE;. Ensure MRP is stopped and no other RMAN sessions are connected to the standby. |
Standby redo log errors after MRP restart (e.g., ORA-00313, ORA-00312) |
The control file replacement invalidated standby redo log references | Clear all standby redo log groups: ALTER DATABASE CLEAR LOGFILE GROUP {GROUP_NUMBER}; for each group shown in V$STANDBY_LOG. |
| Flashback database disabled after recovery | The RECOVER command automatically disables flashback as part of its internal operations | Re-enable flashback: ALTER DATABASE FLASHBACK ON;. |
| Archive gap reappears immediately after recovery and MRP restart | Redo transport from the primary to the standby is not active -- LOG_ARCHIVE_DEST_n or FAL_SERVER is misconfigured |
On the primary, verify the standby destination (commonly DEST_ID 2 — check V$ARCHIVE_DEST to find it): SELECT DEST_ID, STATUS, ERROR FROM V$ARCHIVE_DEST WHERE STATUS <> 'INACTIVE';. Re-enable if needed: ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2=ENABLE;. On the standby, verify FAL_SERVER points to the primary: SHOW PARAMETER fal_server;. |
| Mid-recovery failure (network drop, RMAN crash) | Network interruption or process failure during the RECOVER operation | The command can be re-run from the beginning. RMAN will restart the entire sequence (control file restore, datafile restore, recovery). There is no resume capability -- the command restarts the full process. Ensure network stability before retrying. |
Broker shows WARNING after recovery |
The broker has not yet re-evaluated the configuration after the control file replacement and MRP restart | Wait 2-3 minutes for the broker to update. Run SHOW CONFIGURATION; again. If warnings persist, check the specific database: SHOW DATABASE {STANDBY_DB}; for detailed status. |