Far Sync (Oracle 12c New Feature)

Cyrille Modiano
Latest posts by Cyrille Modiano (see all)


Oracle Far Sync is an Oracle 12c new feature for Oracle Data Guard. This feature is meant to resolve the performance problems induced by network latency when you maintain a standby database geographically distant of the primary database. In this type of situation you sometimes have to make a compromise between performance and data loss. The Far Sync feature offer you both.

How does Far Sync works ?

The principe is fairly simple, the Far Sync instance receive data synchronously from the primary database and then forward it asynchronously to up de 29 remote destinations.

Data Guard Far Sync

The far sync database is not a standard database, it only contains a specific controlfile, a spfile and standby redologs. This database must be placed near the primary database to guarantee an optimal network latency during synchronous replication. But be careful, don’t place this database on the same geographical place than the primary, because if your primary database experiences a geographical disaster, your Far Sync will be impacted too, and some data could be lost.

In case of an outage on the primary database, the standard failover procedure applies and the far sync instance guarantee that no data is lost during the failover.

Configuration for the test

HOSTS : 3 Virtual Machines with 2 GB of Memory
OS : Oracle Linux 6.4
ORACLE VERSION : Oracle 12.1.0.1 Enterprise Edition

SERVER NAME ROLE
SVR-ORA-03 PRIMARY SERVER
SVR-ORA-04 FAR SYNC SERVER
SVR-ORA-05 STANDBY SERVER

Standby database creation

I created a standby database using following script on host SVR-ORA-05

rman target sys/******@DB12CE_PRIMARY auxiliary sys/*******@DB12CE_STANDBY
run 
{
    DUPLICATE TARGET DATABASE
    FOR STANDBY
    FROM ACTIVE DATABASE
    DORECOVER
    NOFILENAMECHECK;
}

and added the standby redologs as follow

ALTER DATABASE ADD STANDBY LOGFILE GROUP 4 (
    '/u01/app/oracle/oradata/DB12CE/onlinelog/stdbyrdo41.log',
    '/u01/app/oracle/fast_recovery_area/DB12CE/onlinelog/stdbyrdo42.log'
  ) SIZE 50M BLOCKSIZE 512;

ALTER DATABASE ADD STANDBY LOGFILE GROUP 5 (
    '/u01/app/oracle/oradata/DB12CE/onlinelog/stdbyrdo51.log',
    '/u01/app/oracle/fast_recovery_area/DB12CE/onlinelog/stdbyrdo52.log'
  ) SIZE 50M BLOCKSIZE 512;

ALTER DATABASE ADD STANDBY LOGFILE GROUP 6 (
    '/u01/app/oracle/oradata/DB12CE/onlinelog/stdbyrdo61.log',
    '/u01/app/oracle/fast_recovery_area/DB12CE/onlinelog/stdbyrdo62.log'
  ) SIZE 50M BLOCKSIZE 512;

My standby is ready, Next we will create the Far Sync Instance.

Far Sync instance creation

We need to create a specific controlfile and a pfile from our primary database.

First, create the controlfile for the Far Sync instance using the following command

SQL> ALTER DATABASE CREATE FAR SYNC INSTANCE CONTROLFILE AS '/u01/app/oracle/control01.ctl';

Database altered.

then create a pfile from the primary spfile that we will use for the Far Sync instance.

SQL> create pfile='/u01/app/oracle/initDB12CE.ora' from spfile;

File created.

After that, we need to copy those files to the Far Sync server.

[oracle@svr-ora-03 oracle]$ scp control01.ctl initDB12CE.ora svr-ora-04:/u01/app/oracle
oracle@svr-ora-04's password:
control01.ctl                                                             100% 9840KB   9.6MB/s   00:00
initDB12CE.ora                                                            100% 1078     1.1KB/s   00:00

I edit the parameter file on the Far Sync server to change the control_files parameter

*.control_files='/u01/app/oracle/oradata/DB12CE/controlfile/control01.ctl'

Then I create the needed directories, copy the controlfile to the right place and the parameter file to the oracle home:

[oracle@svr-ora-04 oracle]$ mkdir -p /u01/app/oracle/oradata/DB12CE/controlfile/
[oracle@svr-ora-04 oracle]$ mkdir -p /u01/app/oracle/oradata/DB12CE/onlinelog/
[oracle@svr-ora-04 oracle]$ mv control01.ctl /u01/app/oracle/oradata/DB12CE/controlfile/
[oracle@svr-ora-04 oracle]$ mv initDB12CE.ora $ORACLE_HOME/dbs

Now, I need to create a spfile from my pfile, mount the database and create my standby redologs :

SQL> create spfile from pfile;

File created.

SQL> startup mount
ORACLE instance started.

Total System Global Area  521936896 bytes
Fixed Size                  2290264 bytes
Variable Size             264244648 bytes
Database Buffers          251658240 bytes
Redo Buffers                3743744 bytes
Database mounted.

SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 4 (
    '/u01/app/oracle/oradata/DB12CE/onlinelog/stdbyrdo41.log',
    '/u01/app/oracle/fast_recovery_area/DB12CE/onlinelog/stdbyrdo42.log'
  ) SIZE 50M BLOCKSIZE 512;

Database altered

SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 5 (
    '/u01/app/oracle/oradata/DB12CE/onlinelog/stdbyrdo51.log',
    '/u01/app/oracle/fast_recovery_area/DB12CE/onlinelog/stdbyrdo52.log'
  ) SIZE 50M BLOCKSIZE 512;

Database altered

SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 6 (
    '/u01/app/oracle/oradata/DB12CE/onlinelog/stdbyrdo61.log',
    '/u01/app/oracle/fast_recovery_area/DB12CE/onlinelog/stdbyrdo62.log'
  ) SIZE 50M BLOCKSIZE 512;

Database altered

SQL> select GROUP#,MEMBER,TYPE from v$logfile;

   GROUP# MEMBER                                                                           TYPE
---------- -------------------------------------------------------------------------------- -------
         3 /u01/app/oracle/oradata/DB12CE/onlinelog/o1_mf_3_9jsrb6dz_.log                   ONLINE
         3 /u01/app/oracle/fast_recovery_area/DB12CE/onlinelog/o1_mf_3_9jsrb6n4_.log        ONLINE
         2 /u01/app/oracle/oradata/DB12CE/onlinelog/o1_mf_2_9jsrb4qo_.log                   ONLINE
         2 /u01/app/oracle/fast_recovery_area/DB12CE/onlinelog/o1_mf_2_9jsrb4vc_.log        ONLINE
         1 /u01/app/oracle/oradata/DB12CE/onlinelog/o1_mf_1_9jsrb34c_.log                   ONLINE
         1 /u01/app/oracle/fast_recovery_area/DB12CE/onlinelog/o1_mf_1_9jsrb3br_.log        ONLINE
         4 /u01/app/oracle/oradata/DB12CE_FS/onlinelog/stdbyrdo41.log                       STANDBY
         4 /u01/app/oracle/fast_recovery_area/DB12CE_FS/onlinelog/stdbyrdo42.log            STANDBY
         5 /u01/app/oracle/oradata/DB12CE_FS/onlinelog/stdbyrdo51.log                       STANDBY
         5 /u01/app/oracle/fast_recovery_area/DB12CE_FS/onlinelog/stdbyrdo52.log            STANDBY
         6 /u01/app/oracle/oradata/DB12CE_FS/onlinelog/stdbyrdo61.log                       STANDBY
         6 /u01/app/oracle/fast_recovery_area/DB12CE_FS/onlinelog/stdbyrdo62.log            STANDBY

SQL>

Our Far Sync instance is now ready for the configuration through Data Guard Broker.

Data Guard configuration

First be sure every database is configured with a listener and tnsnames on each server and has a reference for each other databases, here is my tnsnames.ora for all three servers:

DB12CE_PRIMARY =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = svr-ora-03)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SID = DB12CE)
    )
  )

DB12CE_FS =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = svr-ora-04)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SID = DB12CE)
    )
  )

DB12CE_STANDBY =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = svr-ora-05)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SID = DB12CE)
    )
  )

I changed the db_unique_name of all my three databases.

PRIMARY:

SQL> alter system set db_unique_name='DB12C_PRIM' scope=spfile;

System altered.

FARSYNC:

SQL> alter system set db_unique_name='DB12C_FS' scope=spfile;

System altered.

STANDBY:

SQL> alter system set db_unique_name='DB12C_STBY' scope=spfile;

System altered.

and restarted the databases.

I have to enable the dg_broker on all databases using the following command:

SQL>  alter system set dg_broker_start=true;

System altered.

Once done I connect to dgmgrl on the primary server and create the configuration

DGMGRL> connect target /
Password:
Connected as SYSDG.

DGMGRL> CREATE CONFIGURATION dgb_db12c AS PRIMARY DATABASE IS DB12C_PRIM CONNECT IDENTIFIER IS DB12CE_PRIMARY;

Configuration "dgb_db12c" created with primary database "db12c_prim"

DGMGRL> ADD DATABASE DB12C_STBY AS CONNECT IDENTIFIER IS DB12CE_STANDBY MAINTAINED AS PHYSICAL;

Database "db12c_stby" added

DGMGRL> ADD FAR_SYNC DB12C_FS AS CONNECT IDENTIFIER IS DB12CE_FS;
far sync instance "db12c_fs" added

DGMGRL>

Now we will enable the configuration

DGMGRL> enable configuration
Enabled.

DGMGRL> show configuration verbose

Configuration - dgb_db12c

  Protection Mode: MaxPerformance
  Databases:
  db12c_prim - Primary database
    db12c_stby - Physical standby database
    db12c_fs   - Far Sync (inactive)

  Properties:
    FastStartFailoverThreshold      = '30'
    OperationTimeout                = '30'
    TraceLevel                      = 'USER'
    FastStartFailoverLagLimit       = '30'
    CommunicationTimeout            = '180'
    ObserverReconnect               = '0'
    FastStartFailoverAutoReinstate  = 'TRUE'
    FastStartFailoverPmyShutdown    = 'TRUE'
    BystandersFollowRoleChange      = 'ALL'
    ObserverOverride                = 'FALSE'

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

The configuration is enabled but far sync is not active, we need to configure redo and activate Far Sync

DGMGRL> edit database db12c_prim set property redoroutes='(local:db12c_fs sync)';
Property "redoroutes" updated
DGMGRL> edit far_sync db12c_fs set property redoroutes='(db12c_prim:db12c_stby)';
Property "redoroutes" updated
DGMGRL> enable far_sync db12c_fs;
Enabled.
DGMGRL> show configuration verbose

Configuration - dgb_db12c

  Protection Mode: MaxPerformance
  Databases:
  db12c_prim - Primary database
    db12c_fs   - Far Sync
      db12c_stby - Physical standby database

  Properties:
    FastStartFailoverThreshold      = '30'
    OperationTimeout                = '30'
    TraceLevel                      = 'USER'
    FastStartFailoverLagLimit       = '30'
    CommunicationTimeout            = '180'
    ObserverReconnect               = '0'
    FastStartFailoverAutoReinstate  = 'TRUE'
    FastStartFailoverPmyShutdown    = 'TRUE'
    BystandersFollowRoleChange      = 'ALL'
    ObserverOverride                = 'FALSE'

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

DGMGRL>

Now far sync is enabled, we changed the redo configuration to indicate to the primary database that redo should be forwarded to the Far Sync instance using synch mode.
We edited the Far Sync configuration to indicate that redo will be received from the primary database and then forwarded to the standby database.

Now we can change the protection mode from MaxPerformance to MaxAvailability to benefit from our Far Sync instance

DGMGRL> edit configuration set protection mode as MaxAvailability;
Succeeded.
DGMGRL> show configuration verbose

Configuration - dgb_db12c

  Protection Mode: MaxAvailability
  Databases:
  db12c_prim - Primary database
    db12c_fs   - Far Sync
      db12c_stby - Physical standby database

  Properties:
    FastStartFailoverThreshold      = '30'
    OperationTimeout                = '30'
    TraceLevel                      = 'USER'
    FastStartFailoverLagLimit       = '30'
    CommunicationTimeout            = '180'
    ObserverReconnect               = '0'
    FastStartFailoverAutoReinstate  = 'TRUE'
    FastStartFailoverPmyShutdown    = 'TRUE'
    BystandersFollowRoleChange      = 'ALL'
    ObserverOverride                = 'FALSE'

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

That’s it, configuration is done.

Here are the LOG_ARCHIVE_DEST_n parameters from each database.

DATABASE LOG_ARCHIVE_DEST_1 LOG_ARCHIVE_DEST_2
PRIMARY location=USE_DB_RECOVERY_FILE_DEST, valid_for=(ALL_LOGFILES,ALL_ROLES) service=”db12ce_fs”, SYNC AFFIRM delay=0 optional compression=disable max_failure=0 max_connections=1 reopen=300 db_unique_name=”db12c_fs” net_timeout=30, valid_for=(online_logfile,all_roles)
FAR SYNC location=USE_DB_RECOVERY_FILE_DEST, valid_for=(ALL_LOGFILES,ALL_ROLES) service=”db12ce_standby”, ASYNC NOAFFIRM delay=0 optional compression=disable max_failure=0 max_connections=1 reopen=300 db_unique_name=”db12c_stby” net_timeout=30, valid_for=(standby_logfile,all_roles)
STANDBY location=USE_DB_RECOVERY_FILE_DEST, valid_for=(ALL_LOGFILES,ALL_ROLES)

Conclusion

Far Sync is a very good solution when your standby geographically distant from your primary and you can’t choose the MaxAvailaibility protection mode for performance reasons.
It is also possible with this solution to choose an alternate archive destination for primary database in the event of a failure on Far Sync instance, in this case the primary database will send the data directly to the standby database asynchronously.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.