Far Sync is an Oracle Data Guard feature that lets you achieve zero data loss (SYNC transport) to a remote standby database without paying the latency penalty on primary transactions. A Far Sync instance sits in a third location between the primary and the standby, receives redo synchronously from the primary (low-latency hop), and then ships it asynchronously to the standby (long-distance hop).

Oracle Data Guard Far Sync Architecture — Frankfurt to Amsterdam with SYNC and ASYNC redo transport paths

1. Reference Architecture

1.1 Environment Overview

Role Hostname DB Unique Name Location OS
Primary DB (RAC, 2 nodes) prim01.fra.example.com, prim02.fra.example.com ORCL_FRA Frankfurt DC (AZ-1) OL 8.9
Far Sync Instance farsync01.fra.example.com ORCL_FS Frankfurt DC (AZ-2) OL 8.9
Physical Standby (RAC, 2 nodes) stby01.ams.example.com, stby02.ams.example.com ORCL_AMS Amsterdam DC OL 8.9
DGMGRL / Observer host observer01.fra.example.com Frankfurt DC (AZ-3) OL 8.9
  • Oracle version: 19c (19.23 RU)
  • Primary ↔ Far Sync network: Dedicated 10 GbE VLAN, round-trip latency ≈ 0.4 ms
  • Far Sync ↔ Standby network: WAN link, round-trip latency ≈ 8 ms
  • DB_NAME: ORCL (same for all members); DB_UNIQUE_NAME differs per member

2. Live Redo Information Flow

The diagram above shows the full geographical redo flow. Below is the step-by-step explanation of how zero data loss is achieved:

Why this design achieves zero data loss

  1. The primary commits only after the Far Sync instance confirms the redo has been written to its standby redo log (SYNC transport, AFFIRM).
  2. Because Far Sync is physically close (sub-millisecond), the commit latency impact is negligible.
  3. Far Sync ships the redo to the standby asynchronously (ASYNC, NOAFFIRM), so the long-haul WAN latency does not block primary commits.
  4. If the Far Sync instance itself fails, the primary automatically re-evaluates transport and can temporarily fall back to direct ASYNC to the standby — controlled by MAX_FAILURE and REOPEN settings.

3. Prerequisites

3.1 OS / Network

# On ALL hosts — ensure Oracle user, groups, and limits are consistent
id oracle
# uid=54321(oracle) gid=54321(oinstall)

# Verify sub-millisecond RTT primary <-> Far Sync
ping -c 10 farsync01.fra.example.com

# Open required ports (both directions)
firewall-cmd --permanent --add-port=1521/tcp   # Oracle listener
firewall-cmd --permanent --add-port=6200/tcp   # Grid IPC (RAC)
firewall-cmd --reload

3.2 Oracle Software on the Far Sync Host

Far Sync requires only an Oracle Database home — no Grid Infrastructure, no actual database datafiles.

# On farsync01 — install 19c RDBMS home only (same patch level as primary)
export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1
$ORACLE_HOME/runInstaller -silent -responseFile /tmp/db_install.rsp \
  ORACLE_HOME=$ORACLE_HOME \
  ORACLE_BASE=/u01/app/oracle \
  oracle.install.option=INSTALL_DB_SWONLY \
  DECLINE_SECURITY_UPDATES=true

4. Primary Database Configuration

4.1 init.ora / SPfile Parameters

-- Connect to primary as SYSDBA
sqlplus / as sysdba

ALTER SYSTEM SET DB_NAME='ORCL'                        SCOPE=SPFILE SID='*';
ALTER SYSTEM SET DB_UNIQUE_NAME='ORCL_FRA'             SCOPE=SPFILE SID='*';

-- Enable Data Guard
ALTER SYSTEM SET LOG_ARCHIVE_CONFIG=
  'DG_CONFIG=(ORCL_FRA,ORCL_FS,ORCL_AMS)'             SCOPE=BOTH SID='*';

-- Standby redo logs (SRLs) — required on primary for role transitions
-- Size must match online redo log size; add (threads × max_log_members) + 1
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1
  GROUP 11 ('/u01/oradata/ORCL/srl01a.log',
             '/u02/oradata/ORCL/srl01b.log') SIZE 512M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1
  GROUP 12 ('/u01/oradata/ORCL/srl02a.log',
             '/u02/oradata/ORCL/srl02b.log') SIZE 512M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1
  GROUP 13 ('/u01/oradata/ORCL/srl03a.log',
             '/u02/oradata/ORCL/srl03b.log') SIZE 512M;
-- Repeat for THREAD 2 (second RAC node), groups 21-23

-- Archive log destinations
-- DEST_1: local archiving (mandatory)
ALTER SYSTEM SET LOG_ARCHIVE_DEST_1=
  'LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES)
   DB_UNIQUE_NAME=ORCL_FRA'                            SCOPE=BOTH SID='*';

-- DEST_2: SYNC to Far Sync (the key setting)
ALTER SYSTEM SET LOG_ARCHIVE_DEST_2=
  'SERVICE=ORCL_FS SYNC AFFIRM
   VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)
   DB_UNIQUE_NAME=ORCL_FS
   MAX_FAILURE=1 REOPEN=300
   COMPRESSION=ENABLE'                                 SCOPE=BOTH SID='*';

ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2=ENABLE       SCOPE=BOTH SID='*';

-- DEST_3: ASYNC to standby (used only when FS is down)
ALTER SYSTEM SET LOG_ARCHIVE_DEST_3=
  'SERVICE=ORCL_AMS ASYNC NOAFFIRM
   VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)
   DB_UNIQUE_NAME=ORCL_AMS
   DEPENDENCY=LOG_ARCHIVE_DEST_2'                      SCOPE=BOTH SID='*';

ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_3=ENABLE       SCOPE=BOTH SID='*';

-- Data protection
ALTER SYSTEM SET LOG_ARCHIVE_MIN_SUCCEED_DEST=1        SCOPE=BOTH SID='*';

-- Force logging (mandatory for Data Guard)
ALTER DATABASE FORCE LOGGING;

-- Remote archive
ALTER SYSTEM SET REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE   SCOPE=SPFILE SID='*';
ALTER SYSTEM SET FAL_SERVER='ORCL_FS','ORCL_AMS'       SCOPE=BOTH SID='*';
ALTER SYSTEM SET FAL_CLIENT='ORCL_FRA'                 SCOPE=BOTH SID='*';

-- Standby file management
ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO          SCOPE=BOTH SID='*';

4.2 tnsnames.ora on the Primary

# /u01/app/oracle/product/19.0.0/dbhome_1/network/admin/tnsnames.ora

ORCL_FRA =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = prim01-vip.fra.example.com)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = prim02-vip.fra.example.com)(PORT = 1521))
    (CONNECT_DATA = (SERVICE_NAME = ORCL_FRA)))

ORCL_FS =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = farsync01.fra.example.com)(PORT = 1521))
    (CONNECT_DATA = (SERVICE_NAME = ORCL_FS)))

ORCL_AMS =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = stby01-vip.ams.example.com)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = stby02-vip.ams.example.com)(PORT = 1521))
    (CONNECT_DATA = (SERVICE_NAME = ORCL_AMS)))

5. Far Sync Instance Creation

A Far Sync instance has no datafiles — only a control file, standby redo logs, and a password file. It is created via CREATE FAR SYNC INSTANCE (19c+) or by duplicating with RMAN.

5.1 Password File (copy from primary)

# On prim01 — copy the password file to the Far Sync host
scp $ORACLE_HOME/dbs/orapwORCL [email protected]:$ORACLE_HOME/dbs/orapwORCL_FS

5.2 Parameter File for the Far Sync Instance

# On farsync01 — create a minimal pfile
cat > $ORACLE_HOME/dbs/initORCL_FS.ora << 'EOF'
DB_NAME=ORCL
DB_UNIQUE_NAME=ORCL_FS
ENABLE_PLUGGABLE_DATABASE=TRUE    # match primary CDB setting

LOG_ARCHIVE_CONFIG='DG_CONFIG=(ORCL_FRA,ORCL_FS,ORCL_AMS)'

# Far Sync receives from primary (VALID_FOR=STANDBY_LOGFILES)
LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST
  VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=ORCL_FS'

# Far Sync forwards to standby ASYNC
LOG_ARCHIVE_DEST_2='SERVICE=ORCL_AMS ASYNC NOAFFIRM
  VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE)
  DB_UNIQUE_NAME=ORCL_AMS'
LOG_ARCHIVE_DEST_STATE_2=ENABLE

FAL_SERVER=ORCL_FRA
FAL_CLIENT=ORCL_FS
STANDBY_FILE_MANAGEMENT=AUTO

DB_RECOVERY_FILE_DEST=/u01/fra/ORCL_FS
DB_RECOVERY_FILE_DEST_SIZE=100G

REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE
EOF

5.3 Start the Far Sync Instance and Create the Control File

-- On farsync01 as SYSDBA
export ORACLE_SID=ORCL_FS
sqlplus / as sysdba

STARTUP NOMOUNT PFILE='$ORACLE_HOME/dbs/initORCL_FS.ora';

-- Create the Far Sync control file (run on farsync01, referencing primary)
-- This is a STANDBY control file; no datafiles needed
CREATE FAR SYNC INSTANCE CONTROLFILE AS
  '/u01/fra/ORCL_FS/ORCL_FS_control01.ctl';

-- Mount it
ALTER DATABASE MOUNT;

-- Add Standby Redo Logs on the Far Sync instance
-- Match the primary's online redo log size and count
ALTER DATABASE ADD STANDBY LOGFILE GROUP 11
  '/u01/fra/ORCL_FS/srl11.log' SIZE 512M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 12
  '/u01/fra/ORCL_FS/srl12.log' SIZE 512M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 13
  '/u01/fra/ORCL_FS/srl13.log' SIZE 512M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 14
  '/u01/fra/ORCL_FS/srl14.log' SIZE 512M;
-- Far Sync is single-instance so THREAD 1 only

-- Convert the listener to register the Far Sync service
-- /etc/oratab entry: ORCL_FS:/u01/app/oracle/product/19.0.0/dbhome_1:N

5.4 Listener on farsync01

# listener.ora on farsync01
LISTENER_FS =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = farsync01.fra.example.com)(PORT = 1521))))

SID_LIST_LISTENER_FS =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = ORCL_FS)
      (ORACLE_HOME = /u01/app/oracle/product/19.0.0/dbhome_1)
      (SID_NAME = ORCL_FS)))
lsnrctl start LISTENER_FS
lsnrctl status LISTENER_FS

6. Physical Standby Database

6.1 Duplicate from Primary Using RMAN Active Duplication

# Run from the standby host (stby01) as oracle user
rman target sys/SYS_PASSWORD@ORCL_FRA auxiliary sys/SYS_PASSWORD@ORCL_AMS

DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE
  SPFILE
    SET DB_UNIQUE_NAME='ORCL_AMS'
    SET LOG_ARCHIVE_CONFIG='DG_CONFIG=(ORCL_FRA,ORCL_FS,ORCL_AMS)'
    SET LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST
      VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=ORCL_AMS'
    SET LOG_ARCHIVE_DEST_2='SERVICE=ORCL_FRA ASYNC NOAFFIRM
      VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=ORCL_FRA'
    SET FAL_SERVER='ORCL_FS','ORCL_FRA'
    SET FAL_CLIENT='ORCL_AMS'
    SET STANDBY_FILE_MANAGEMENT='AUTO'
    SET DB_RECOVERY_FILE_DEST='/u01/fra/ORCL_AMS'
    SET DB_RECOVERY_FILE_DEST_SIZE='500G'
  NOFILENAMECHECK;

6.2 Start Managed Recovery on the Standby

-- On stby01 as SYSDBA
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;

-- Verify apply is running
SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK#
FROM   V$MANAGED_STANDBY
ORDER  BY PROCESS;

7. DGMGRL Configuration

7.1 Create the Broker Configuration

# On observer01 (or any host with tnsnames configured)
dgmgrl sys/SYS_PASSWORD@ORCL_FRA

DGMGRL> CREATE CONFIGURATION 'DG_ORCL'
          AS PRIMARY DATABASE IS 'ORCL_FRA'
          CONNECT IDENTIFIER IS ORCL_FRA;

DGMGRL> ADD FAR_SYNC 'ORCL_FS'
          AS CONNECT IDENTIFIER IS ORCL_FS;

DGMGRL> ADD DATABASE 'ORCL_AMS'
          AS CONNECT IDENTIFIER IS ORCL_AMS
          MAINTAINED AS PHYSICAL;

DGMGRL> ENABLE CONFIGURATION;

7.2 Configure Redo Routes

The Broker “redo route” tells it the intended transport path. The Far Sync instance is the relay.

DGMGRL> EDIT DATABASE 'ORCL_FRA' SET PROPERTY
          RedoRoutes = '(LOCAL : ORCL_FS SYNC AFFIRM)';

DGMGRL> EDIT FAR_SYNC 'ORCL_FS' SET PROPERTY
          RedoRoutes = '(ORCL_FRA : ORCL_AMS ASYNC NOAFFIRM)';

-- Protection mode: MAXIMUM AVAILABILITY (zero data loss via Far Sync)
DGMGRL> EDIT CONFIGURATION SET PROTECTION MODE AS MAXAVAILABILITY;

DGMGRL> SHOW CONFIGURATION;

Expected output:

Configuration - DG_ORCL

  Protection Mode: MaxAvailability
  Members:
  ORCL_FRA - Primary database
    ORCL_FS  - Far sync instance
      ORCL_AMS - Physical standby database

Fast-Start Failover:  Disabled
Configuration Status:
SUCCESS   (status updated 8 seconds ago)

7.3 Enable Fast-Start Failover (FSFO)

-- Set target and thresholds
DGMGRL> EDIT CONFIGURATION SET PROPERTY
          FastStartFailoverThreshold = 30;     -- seconds

DGMGRL> EDIT CONFIGURATION SET PROPERTY
          FastStartFailoverTarget = 'ORCL_AMS';

DGMGRL> ENABLE FAST_START FAILOVER;

-- Start the observer (keep running — use nohup or a dedicated service)
DGMGRL> START OBSERVER FILE='/u01/fsfo/observer_DG_ORCL.dat'
          LOGFILE='/u01/fsfo/observer_DG_ORCL.log';

8. Verification

8.1 Redo Transport Lag and Apply Lag

-- On the primary
SELECT DEST_ID, DEST_NAME, STATUS, TARGET, ARCHIVER,
       SCHEDULE, DESTINATION, APPLIED_SCN,
       TRANSMIT_MODE, NET_TIMEOUT, MAX_FAILURE, REOPEN_SECS
FROM   V$ARCHIVE_DEST
WHERE  TARGET = 'STANDBY'
ORDER  BY DEST_ID;

-- Lag check via Data Guard V$ views (on primary)
SELECT NAME, VALUE, UNIT, TIME_COMPUTED
FROM   V$DATAGUARD_STATS
WHERE  NAME IN ('transport lag','apply lag','apply finish time');

8.2 Far Sync Health

-- On the Far Sync instance
SELECT PROCESS, STATUS, THREAD#, SEQUENCE#
FROM   V$MANAGED_STANDBY;

-- Confirm it is in FAR SYNC role
SELECT DB_UNIQUE_NAME, DATABASE_ROLE, OPEN_MODE
FROM   V$DATABASE;
-- Expected: FAR SYNC | MOUNTED

8.3 DGMGRL Status

DGMGRL> SHOW CONFIGURATION VERBOSE;
DGMGRL> SHOW DATABASE VERBOSE 'ORCL_FRA';
DGMGRL> SHOW DATABASE VERBOSE 'ORCL_AMS';
DGMGRL> SHOW FAR_SYNC VERBOSE 'ORCL_FS';
DGMGRL> VALIDATE FAR_SYNC 'ORCL_FS';

8.4 Switchover Test

DGMGRL> VALIDATE DATABASE 'ORCL_AMS';
DGMGRL> SWITCHOVER TO 'ORCL_AMS';

-- After switchover:
DGMGRL> SHOW CONFIGURATION;
-- ORCL_AMS is now primary; ORCL_FRA is physical standby
-- Switchover back:
DGMGRL> SWITCHOVER TO 'ORCL_FRA';

9. Far Sync Failure Handling

When the Far Sync instance fails, the primary automatically re-evaluates LOG_ARCHIVE_DEST_2. Because MAX_FAILURE=1 and DEPENDENCY is set on DEST_3, the primary switches to direct ASYNC transport to the standby (DEST_3), temporarily trading zero-data-loss for availability. This transition is seamless and logged in the alert log.

-- Check current effective transport mode during FS outage
SELECT DEST_ID, STATUS, TARGET, TRANSMIT_MODE, ERROR
FROM   V$ARCHIVE_DEST
WHERE  TARGET = 'STANDBY';

-- Monitor recovery from alert log
ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2 = ENABLE;  -- re-enables after FS comes back

When the Far Sync instance recovers, it catches up from the primary’s archived logs (FAL fetch), and the primary’s REOPEN=300 timer ensures it will re-try DEST_2 within 5 minutes.


10. Tips and Best Practices

  • Same patch level everywhere. Far Sync, primary, and standby must run identical Oracle version and RU. Patch Far Sync in rolling fashion like any other member.
  • Standby Redo Log sizing. Add at least (max_online_log_groups + 1) SRLs per thread on every member, sized to match the online redo logs exactly.
  • Far Sync is CPU-light. It only processes redo headers and forwards log files — a VM with 2 vCPU / 8 GB RAM is sufficient for most workloads.
  • Place the observer in a third fault domain. The observer on observer01.fra.example.com (AZ-3) must not share fate with the primary or Far Sync; otherwise FSFO cannot reliably distinguish a primary failure from a network partition.
  • Encryption in transit. Enable Oracle Net encryption (sqlnet.ora / SQLNET.ENCRYPTION_SERVER=REQUIRED) on all members to protect redo in flight over the WAN.
  • Monitor with Enterprise Manager or DGMGRL health checks scheduled via a cron job: dgmgrl -silent sys/... @/dba/scripts/dg_healthcheck.dgmgrl.