Note:
- This tutorial requires access to Oracle Cloud. To sign up for a free account, see Get started with Oracle Cloud Infrastructure Free Tier.
- It uses example values for Oracle Cloud Infrastructure credentials, tenancy, and compartments. When completing your lab, substitute these values with ones specific to your cloud environment.
Set up Bidirectional Replication Between Two Oracle Heatwave MySQL managed instances using OCI GoldenGate
Introduction
Oracle Cloud Infrastructure GoldenGate (OCI GoldenGate) is a fully managed service that helps data engineers move data in real-time, at scale, from one or more data management systems to OCI databases. Design, run, orchestrate, and monitor data replication tasks in a single interface without having to allocate or manage any compute environments. OCI GoldenGate supports several sources and targets, including MySQL and Oracle HeatWave MySQL database service.
In this tutorial, we will guide you how to set up bidirectional replication using OCI GoldenGate between two Oracle HeatWave MySQL instances in OCI.
Objectives
- Set up bidirectional replication between two Oracle HeatWave MySQL managed instances using OCI GoldenGate in OCI.
Prerequisites
-
Source and target Oracle HeatWave MySQL instances must be using
InnoDB
engine and must be running on versions5.7
or8.*
. -
For bidirectional replication, it is recommended to use same version of MySQL instance on source and target.
-
The
binlog_expire_logs_second
instance parameter on source and target instances must be set to atleast 72 hours. -
The
binlog_row_metadata
instance parameter on source and target instances must be set to full to allow Data Definition Language (DDL) replication.Note: Instance parameters can only be changed by creating a Custom Configuration. For more information, see Creating a Custom Configuration for MySQL.
-
Review supported data types. For more information, see MySQL: Supported Data Types, Objects, and Operations.
-
Review DDL replication limitations. For more information, see Using DDL Replication.
-
Target instance should be created ahead of time from source using one of these methods:
- Method 1: Using MySQL shell utilities like
util.dumpInstance
andutil.loadDump
. - Method 2: Through OCI Console based backup and restore option.
- Method 3: Using OCI GoldenGate for initial Extract and Replicat to perform the initial data load. In this tutorial this method has been used (Task 7).
- Method 1: Using MySQL shell utilities like
-
By design, the heartbeat table DDLs are ignored by the Extract. You should create the heartbeat table manually at the target.
-
Bastion host with MySQL client installed.
-
Ingress rules and updated security lists to allow communication between source, target, bastion and OCI GoldenGate.
Task 1: Deploy OCI GoldenGate
-
Log in to the OCI Console, search for GoldenGate, select GoldenGate service and click Create Deployment.
-
Enter the following information and click Create.
- Name: Enter
MySQLggdeployment1
. - Deployment Type: Select Data replication.
- Select Technology: Select MySQL.
- Select Version: Enter
21.15
. - Hardware configuration: Enter # of OCPUs.
- Subnet selection: Select subnet.
- License Type Select license type.
- Instance name: Enter
GGInstance1
. - Credential Store: Select GoldenGate (create a new password secret or select an existing one).
- Name: Enter
Task 2: Create Users in Oracle HeatWave MySQL Instances
-
Use OCI Bastion host to connect to source and target MySQL instances and create users for OCI GoldenGate Extract and Replicat processes. Run the following query:
-
On source MySQL instance.
> create user 'ggsuser_S'@'%' identified by "<password>"; > grant all privileges on airportdb.* to 'ggsuser_S'@'%' with grant option; > Grant select, process, replication slave, replication client on *.* to 'ggsuser_S'@'%';
-
On target MySQL instance.
> create user 'ggsuser_T'@'%' identified by "<password>"; > grant all privileges on airportdb.* to 'ggsuser_T'@'%' with grant option; > Grant select, process, replication slave, replication client on *.* to 'ggsuser_T'@'%';
-
Task 3: Set up Connections in OCI GoldenGate Deployment
-
Go to the OCI GoldenGate deployment page and click Connections to set up the connection.
-
Enter the connection information.
-
Repeat the above steps to add both source and target connections.
-
Select Deployments and click Assigned Connections to assign the connections to the deployment.
Task 4: Set up Ingress Rules and Security Lists for OCI GoldenGate Console
-
Set up ingress rules and update security lists to allow communication between the Oracle HeatWave MySQL instances, OCI GoldenGate deployment and OCI Bastion compute.
Note: If you are using VPN then you can skip this step.
Follow the steps listed here: Option B: Use your own bastion on OCI Compute.
ssh -i <private-ssh-key-of-bastion-compute> opc@<bastion-compute-public-ip> -L 443:<GoldenGategate-deployment-hostname>:443 -N
-
Test the connections for both source and target databases in OCI Console and through OCI GoldenGate Console.
-
Validate the MySQL instance connections within OCI Console.
-
Validate the same connections from the OCI GoldenGate Console.
-
Task 5: Create the Extract and Replicat Processes
-
Create a primary Extract (
EXT1
).-
Log in to the OCI GoldenGate Console.
-
Go to Overview and click + in the Extracts section.
-
Enter the Extract information.
-
Edit the parameter file as needed. The following parameter file captures all changes in
classicmodels
database including DDL changes.EXTRACT ext1 USERIDALIAS MySQLpoc1, DOMAIN OracleGoldenGate EXTTRAIL e1 DDL INCLUDE MAPPED TRANLOGOPTIONS FETCHPARTIALJSON TABLE classicmodels.*;
Note: The
MySQLpoc1
is a source instance. -
Start the Extract and note down the Global Transaction Identifier (GTID) on the source.
MySQL> select @@gtid_executed, @@gtid_purged\G *************************** 1. row *************************** @@gtid_executed: 3b631a96-6aa7-11ef-95c0-02001701769c:1-94 <--- make a note of this GTID @@gtid_purged: 3b631a96-6aa7-11ef-95c0-02001701769c:1-72 1 row in set (0.00 sec) MySQL>
Start the Extract and keep it running all the time, even when you are still working on setting up the target database to ensure all changes are captured.
-
-
Create a primary Replicat (
REP1
).-
Log in to the OCI GoldenGate Console.
-
Go to Overview and click + in the Replicat section.
Note: The checkpoint table name should be prefixed with the database/schema name in lowercase. Failure to do so will cause checkpoint table creation to fail.
For example,
classicmodels.OCIGG_CHECKPOINT_REP1
.It is recommended to create a separate dedicated database/schema (for example,
ggadmin
schema) for checkpoint table.MySQL> create database ggadmin; Query OK, 1 row affected (0.01 sec) MySQL> grant all privileges on ggadmin.* to 'ggsuser_T'@'%' with grant option; Query OK, 0 rows affected (0.00 sec) MySQL> grant all privileges on ggadmin.* to 'ggsuser_S'@'%' with grant option; Query OK, 0 rows affected (0.00 sec)
-
Edit the parameter file as needed. The following parameter file replicates all objects under the
classicmodels
database along with DDL changes.REPLICAT rep1 USERIDALIAS MySQLpoc2, DOMAIN OracleGoldenGate DDL INCLUDE MAPPED MAP classicmodels.*, TARGET classicmodels.*;
Note: The
MySQLpoc2
is a target instance. -
Since this is the primary Replicat and it was started for the first time, it will start applying from trail file 0. However if you want to alter the Replicat to start from a particular GTID then follow the steps:
-
Go to Replicat section in the OCI GoldenGate Console.
-
Select the replicat, click Alter, Edit, BEGIN, select GTID and enter the GTID.
-
-
-
So far we have set up the unidirectional for both Data Manipulation Language (DML) and DDL replication. Once the unidirectional replication is in sync, we can proceed with bidirectional replication.
-
Repeat step 5.1 and step 5.2, but this time we reverse the source and target details. The source database instance will now act as target instance and target instance will act as source instance.
- Source: Enter
MySQLpoc2
. - Target: Enter
MySQLpoc1
. - For this use case, we have used a second database
airportdb
. You can setup bidirectional replication for the same database.
- Source: Enter
-
Add primary Extract (
EXT2
).EXTRACT ext2 USERIDALIAS MySQLpoc2, DOMAIN OracleGoldenGate EXTTRAIL e2 DDL INCLUDE MAPPED TRANLOGOPTIONS FILTERTABLE ggadmin.OCIGG_CHECKPOINT_REP* -- from 23ai GG use EXCLUDEFILTERTABLE TABLE airportdb.*;
-
Manually create checkpoint table as this is a Classic Replicat. Only Classic and Coordinated Replicats are supported for bidirectional replication.
For example: ggadmin.OCIGG*CHECKPOINT_REP`- Add primary REPLICAT REP2:` REPLICAT rep2 USERIDALIAS MySQLpoc1, DOMAIN OracleGoldenGate DDL INCLUDE MAPPED MAP airportdb.*, TARGET airportdb.\_;
-
Task 6: Run DDL and DML Tests
Now that the bidirectional setup is completed, it is time to run simple DML and DDL tests.
--DML test from classicmodels database on source MySQLpoc1
MySQLpoc1> select count(*) from weatherdata;
+----------+
| count(*) |
+----------+
| 4626432 |
+----------+
1 row in set (0.19 sec)
MySQLpoc1> insert into weatherdata values ('2005-01-02','04:50:00',-8.1,3,57.0,990.00,38.00,'Nebel-Schneefall',61);
Query OK, 1 row affected (0.00 sec)
MySQLpoc1> select count(*) from weatherdata;
+----------+
| count(*) |
+----------+
| 4626433 |
+----------+
1 row in set (0.23 sec)
-DDL replication test from classicmodels database on source MySQLpoc1
MySQLpoc1> create table test (name char(5));
Query OK, 0 rows affected (0.02 sec)
MySQL> insert into test values ('cj');
Query OK, 1 row affected (0.00 sec)
MySQL>
--Now Let's check if the above DML and DDLs got replicated to target MySQLpoc2
MySQLpoc2> select count(*) from weatherdata;
+----------+
| count(*) |
+----------+
| 4626433 | <--- row count matches to source
+----------+
1 row in set (0.37 sec)
MySQLpoc2>
MySQLpoc2> select * from test;
+------+
| name |
+------+
| cj | <-- table CJ got replicated
+------+
1 row in set (0.00 sec)
MySQL>
-- Now testing Bi directional
-- on target (MySQLpoc2)
MySQLpoc2> select * from test;
+------+
| name |
+------+
| cj |
+------+
1 row in set (0.00 sec)
MySQLpoc2> insert into test values ('cj2');
Query OK, 1 row affected (0.01 sec)
MySQLpoc2> select * from test;
+------+
| name |
+------+
| cj |
| cj2 |
+------+
2 rows in set (0.00 sec)
MySQLpoc2> insert into test values ('cjs3');
Query OK, 1 row affected (0.00 sec)
MySQLpoc2> select * from test;
+------+
| name |
+------+
| cj |
| cj2 |
| cjs3 |
+------+
3 rows in set (0.00 sec)
MySQLpoc2>
--On source (MySQLpoc1):
--DML on the target got REPLICATed on the source
MySQLpoc1> select * from test;
+------+
| name |
+------+
| cj |
| cj2 |
| cjs3 |
+------+
3 rows in set (0.00 sec)
MySQL>
Task 7: Set up Initial Load Extract
-
Set up Initial load Extract if you want to leverage OCI GoldenGate to perform the initial loading of data into the target database.
-
Log in to the OCI GoldenGate Console.
-
Go to Overview and click + in the Extract section. This is very similar to creating a primary Extract, the only difference is to select Extract type as Initial Load when creating a Extract.
Parameter file for initial load Extract.
Parameter file for initial load EXTRACT: EXTRACT EXTIL USERIDALIAS MySQLpoc1, DOMAIN OracleGoldenGate EXTFILE il , PURGE TABLE airportdb.*; MAP_PARALLELISM 4 MIN_APPLY_PARALLELISM 2 MAX_APPLY_PARALLELISM 10 SPLIT_TRANS_RECS 1000 CHUNK_SIZE 1 GB
-
-
Similarly set up a Replicat that will read the trail files generated by initial load Extract. This Replicat and the initial load Extract will both be dropped once the initial load is complete.
-
On target database, make sure all tables are empty. Drop/Disable all the Foreign Keys on target. Disable Triggers and Indexes on target to improve initial load performance.
Note: Take a backup for the schema objects DDLs before dropping any.
-
The following is the order in which Extract and Replicat processes should be created if using initial load Extract for initial data load.
-
Create a primary Extract for source (do not start the process yet).
-
Create an initial load Extract for source (do not start the process yet) and capture the GTID on source.
-
Create a Replicat to process the trail files generated by initial load Extract for target (do not start the process yet).
Note: There is no separate Replicat type for initial load.
-
Create a primary Replicat for target (do not start the process yet).
-
Use the same checkpoint table for both initial load Replicat and the primary Replicat. Initial load Replicat points to initial Extract trail files and primary Replicat points to primary Extract trail files (both trail files are different).
-
-
The following is the order in which the processes should be started when using initial load Extract.
-
Start the primary Extract and make a note of the GTID that it registers with.
-
Start the Replicat that was created for initial load Extract.
-
Edit the initial load Extract and alter it to start with GTID that you got when starting primary Extract.
-
Start the primary Replicat.
Note:
- Start the primary Replicat only after both initial load Extract and Replicat for initial load are in sync (LAG 0).
- Create or enable the foreign keys before starting the primary Replicat.
Create indexes (if you dropped them earlier to improve initial load performance) before starting the primary Replicat.
-
-
Limitations
-
Only Classic and Coordinated Replicats support bidirectional and multi-directional replication, parallel Replicat is not supported.
-
Auto increment column issues.
-
If a table has one column and that is not primary key or unique key then mapping fails because the combination of all columns for that table is same on source and target.
-
Data types, DDL and other feature limitations.
-
When using Active-Active replication, the time zones must be the same on both systems so that timestamp-based conflict resolution and detection can operate.
Related Links
-
Connect to Oracle Cloud Infrastructure GoldenGate using a private IP
-
MySQL: Prerequisites for Transaction Log Based DDL Configuration
-
Loading Data from File to Replicat in Microservices Architecture
-
MySQL: Supported Data Types, Objects, and Operations for OCI GoldenGate
Acknowledgments
- Author - Chakradhar Jagganagari (LIFT Implementation Specialist - Custom, 3rd party, VM Database & Apps)
More Learning Resources
Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.
For product documentation, visit Oracle Help Center.
Set up Bidirectional Replication Between Two Oracle Heatwave MySQL managed instances using OCI GoldenGate
G29670-02
Copyright ©2025, Oracle and/or its affiliates.