Why Data Guard Is Still the Baseline in 2026
Every Oracle environment that cares about its data has Data Guard in the picture — or should. Whether you’re running on-premises Exadata, Oracle Cloud Infrastructure, or a hybrid setup, Data Guard is the most battle-tested data protection mechanism Oracle has. It predates most of the cloud-native alternatives and remains the right choice when you need:
- Zero or near-zero RPO on your primary database
- Automatic or manual failover without data loss
- A synchronized standby you can open read-only for reporting or backups
- Protection modes that match your business requirements (Maximum Performance vs. Maximum Availability vs. Maximum Protection)
We’ve configured Data Guard on systems ranging from 500GB single-instance to 40TB RAC clusters. The sequence is the same every time. This guide walks through it exactly as we do it in production.
Prerequisites: What You Need Before You Start
Before touching anything, confirm these are in place on both the primary and standby hosts:
- Oracle software installed and running the same release/patch level on both servers
- Oracle Net listener configured on both hosts —
lsnrctl statusreturns the expected service name - Password file exists on the primary (
orapw<ORACLE_SID>) — you’ll copy this to the standby - Oracle Managed Files (OMF) enabled or you’re prepared to specify full filenames on all file creation commands
- Flashback Database enabled on the primary — this makes DG Broker switchovers dramatically cleaner and is required for some configurations
- Archive log mode enabled —
SELECT log_mode FROM v\$database;must returnARCHIVELOG - Standby redo logs sized to match your primary online redo logs — if you don’t have them, add them before enabling Data Guard
- Firewall ports open between primary and standby on TCP 1521 (or your custom listener port)
- Tnsnames.ora entries exist on both hosts for the primary and standby aliases
Step 1: Configure the Primary Database for Redo Transport
Start on the primary. Set the Data Guard configuration parameters via ALTER SYSTEM. These are persistent and survive restarts.
-- Force log shipping (mandatory)
ALTER SYSTEM SET log_archive_dest_1=‘LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=PRIMARY’;
-- Destination for redo received by standby
ALTER SYSTEM SET log_archive_dest_2=‘SERVICE=STANDBYASYNC VALIDFOR=(ONLINE_LOGFILE,PRIMARY_ROLE) DB_UNIQUE_NAME=STANDBY’;
-- Set the DB unique name (required for DG Broker)
ALTER SYSTEM SET db_unique_name=‘PRIMARY’ SCOPE=BOTH;
-- Specify which roles can use each destination
ALTER SYSTEM SET log_archive_dest_state_1=‘ENABLE’;
ALTER SYSTEM SET log_archive_dest_state_2=‘ENABLE’;
The STANDBYASYNC in log_archive_dest_2 means asynchronous redo transport — the primary doesn’t wait for the standby to acknowledge. This is the right setting for Maximum Performance mode (the default). For Maximum Availability, you’d use STANDBYSYNC and add AFFIRM.
Step 2: Create the Standby Database
There are two ways to create the standby: RMAN duplicate from active database, or restore from a backup. The RMAN duplicate method is faster and is what we use in most scenarios.
Option A: RMAN Duplicate (Preferred)
On the standby host, create the necessary directories and set up a minimal init.ora for the standby. Then connect RMAN to both the primary (as target) and the standby (as auxiliary):
rman target sys/password@PRIMARY auxiliary sys/password@STANDBY
DUPLICATE TARGET DATABASE
FOR STANDBY
FROM ACTIVE DATABASE
DORECOVER
SPFILE
SET db_unique_name=‘STANDBY’
SET log_archive_dest_1=‘LOCATION=USE_DB_RECOVERY_FILE_DEST VALIDFOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=STANDBY’
SET log_archive_dest_2=‘SERVICE=PRIMARYASYNC VALIDFOR=(ONLINE_LOGFILE,STANDBY_ROLE) DB_UNIQUE_NAME=PRIMARY’
SET fal_server=‘PRIMARY’
SET fal_client=‘STANDBY’
SET standby_file_management=‘AUTO’
NOFILENAMECHECK;
The DORECOVER clause tells RMAN to continue applying archived logs until the standby is in sync with the primary. This can take a while on large databases — budget 30–90 minutes depending on size and network speed.
Option B: Restore from Backup (When Duplicate Won’t Work)
If the standby can’t reach the primary over the network (rare but happens in strict network segmentation scenarios), take a backup on primary and ship it to standby:
-- On primary: full backup plus control file for standby
RMAN> BACKUP FORMAT ‘/backup/%U’ DATABASE PLUS ARCHIVELOG;
RMAN> BACKUP CURRENT CONTROLFILE FOR STANDBY FORMAT ‘/backup/standby_control.ctl’;
Copy everything to the standby, restore the control file, then restore and recover the database. This method works in air-gapped or strict-LAN-only topologies.
Step 3: Create Standby Redo Logs on Both Sites
Standby redo logs (SRLs) are the receiving mechanism for redo data on the standby. Without them, the standby can only recover — it can’t apply in real-time. For any production Data Guard configuration, you want real-time apply.
-- On primary: one SRL per thread, matching the size of your online redo logs
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 (‘/u01/oradata/PRIMARY/srl01.log’) SIZE 256M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 (‘/u01/oradata/PRIMARY/srl02.log’) SIZE 256M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 (‘/u01/oradata/PRIMARY/srl03.log’) SIZE 256M;
-- On standby: same configuration
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 (‘/u01/oradata/STANDBY/srl01.log’) SIZE 256M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 (‘/u01/oradata/STANDBY/srl02.log’) SIZE 256M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 (‘/u01/oradata/STANDBY/srl03.log’) SIZE 256M;
-- If running RAC, add SRLs for each thread on each instance
Verify your SRL count: SELECT GROUP#, THREAD#, BYTES FROM v\$standby_log ORDER BY THREAD#, GROUP#;
Step 4: Start the Standby’s Apply Process
On the standby, put the database in mount mode and start Redo Apply:
-- Ensure standby is in mount state
SHUTDOWN IMMEDIATE;
STARTUP NOMOUNT;
ALTER DATABASE MOUNT STANDBY DATABASE;
-- Real-time apply (recommended for production)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
-- Or deferred apply (for maintenance windows):
-- ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
The USING CURRENT LOGFILE clause enables real-time apply — redo is applied as it arrives, not just during recovery intervals. DISCONNECT FROM SESSION runs the apply in the background.
Monitor apply progress:
SELECT SEQUENCE#, APPLIED, ARCHIVE_TIME, COMPLETION_TIME
FROM V\$ARCHIVED_LOG
WHERE APPLIED=‘YES’
ORDER BY SEQUENCE# DESC
FETCH FIRST 10 ROWS ONLY;
Step 5: Configure the Data Guard Broker (DGB)
The DG Broker is Oracle’s management interface for Data Guard. Without it, you’re managing configuration via static init.ora parameters. With it, you get a centralized CLI, automatic failover, and Far Sync support. Always use the broker in production.
Enable the Broker on Both Sites
-- On primary
ALTER SYSTEM SET dg_broker_start=TRUE SCOPE=BOTH;
-- On standby
ALTER SYSTEM SET dg_broker_start=TRUE SCOPE=BOTH;
Create the Broker Configuration
dgmgrl sys/password@PRIMARY
CREATE CONFIGURATION ‘PROD_DG’ AS PRIMARY DATABASE IS ‘PRIMARY’
CONNECT IDENTIFIER IS ‘PRIMARY’;
ADD DATABASE ‘STANDBY’ AS CONNECT IDENTIFIER IS ‘STANDBY’
MAINTAINED AS PHYSICAL;
ENABLE CONFIGURATION;
Validate everything is healthy:
DGMGRL> SHOW CONFIGURATION
Configuration - PROD_DG
Protection Mode: MaxPerformance
Databases:
PRIMARY - Primary database
STANDBY - Physical standby database
Fast-Start Failover: Disabled
Configuration Status:
SUCCESS
Set the Protection Mode
By default, DG Broker creates configurations in Maximum Performance mode. If you need Maximum Availability:
DGMGRL> EDIT DATABASE ‘PRIMARY’ SET PROPERTY LogXptMode=Sync;
DGMGRL> EDIT DATABASE ‘STANDBY’ SET PROPERTY LogXptMode=Sync;
DGMGRL> EDIT CONFIGURATION SET PROTECTION MODE AS MAXAVAILABILITY;
Step 6: Test the Configuration End-to-End
Before calling this done, test three things:
1. Verify Redo Shipping
-- On primary: force a log switch
ALTER SYSTEM SWITCH LOGFILE;
-- On standby: verify the sequence arrived
SELECT SEQUENCE#, APPLIED, ARCHIVE_TIME
FROM V\$ARCHIVED_LOG
ORDER BY SEQUENCE# DESC
FETCH FIRST 5 ROWS ONLY;
2. Verify the Standby Is Receiving and Applying
-- On standby: check managed recovery is running
SELECT PROCESS, STATUS, SEQUENCE# FROM V\$MANAGED_STANDBY;
-- Should show MRP0 with APPLYING_LOG, RFS with RECEIVE, LNS with SENDING
3. Check the Data Guard Status View
-- On primary
SELECT MESSAGE, TIMESTAMP FROM v\$dataguard_status
WHERE TIMESTAMP > SYSDATE-1
ORDER BY TIMESTAMP DESC;
Step 7: Run Your First Switchover (Do This Before You Need It)
A switchover is a planned role reversal — primary becomes standby, standby becomes primary. It’s the safe way to test your configuration. Do it in a maintenance window. It’s reversible if something goes wrong.
dgmgrl sys/password@PRIMARY
-- Validate both databases are ready
VALIDATE DATABASE ‘STANDBY’;
-- Initiate switchover (primary becomes standby)
SWITCHOVER TO ‘STANDBY’;
The command verifies the standby is ready, converts the primary to a standby, then converts the standby to a primary. Total time for a well-configured system: 60–90 seconds.
Common Issues We See in Practice
Standby Falls Behind — Sequence Gap
If the standby is more than 10 sequences behind, check: (1) is the archive log destination full on the standby? (2) is network throughput adequate? (3) is the standby in read-only mode with apply running?
-- On standby: stop apply, ship missing logs, restart
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
-- SCP missing logs to /u01/archive/
ALTER DATABASE REGISTER LOGFILE ‘/u01/archive/arc_SEQ_123_ABC.log’;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
ORA-16009: Remote Archive Log Destination Is Invalid
This usually means the db_unique_name on one side doesn’t match the other. Check v\$archive_dest on both sides — DB_UNIQUE_NAME is case-sensitive on some platforms.
DG Broker Won’t Connect
Verify the GLOBAL_DBNAME in the listener.ora on the remote side includes the _DGMGRL suffix:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME=STANDBY_DGMGRL) -- required for DG Broker
(ORACLE_HOME=/u01/oracle/19c)
(SID_NAME=STANDBY)
)
)
What’s Next After Setup
Now that Data Guard is running, a few things we put in place immediately after configuration:
- Far Sync Instance: If you need Maximum Protection mode without geographically limiting your primary, add a Far Sync instance. It receives redo synchronously from the primary and forwards it asynchronously to standbys — zero data loss protection without the latency constraint.
- Fast-Start Failover (FSFO): Enable it for automatic failover within a defined timeout. Combined with an Oracle Observer on a third host, FSFO gives you RTO under 30 seconds.
- Monitoring: Add
V\$DATAGUARD_STATSto your monitoring. We’re happy to audit your Data Guard setup as part of a Database Health Assessment.
Data Guard configuration done right is a one-time investment that pays dividends every day your primary is healthy. When something does go wrong, the difference between a tested configuration and an untested one is measured in hours of downtime.
- → SQL Server Always On AGs vs. Oracle Data Guard: Which Should You Trust With Your Data?
- → Oracle AWR Reports Explained: Performance Tuning Without Guessing
- → Database Backup Strategies: RPO, RTO, and What Actually Matters
- → Free assessment: Get your Data Guard configuration reviewed by a senior Oracle DBA