Cloud Lab: Oracle GoldenGate CDC

Learn enterprise-grade Change Data Capture with Oracle GoldenGate. Capture changes from Oracle databases with guaranteed delivery, conflict resolution, and bidirectional replication capabilities.

Overview

Oracle GoldenGate (OGG) is an enterprise-grade, real-time data integration and replication platform that has been the gold standard for mission-critical CDC workloads for over two decades. Unlike open-source solutions, GoldenGate provides durable, checkpoint-based delivery with effectively-once apply, active-active replication, and sophisticated conflict detection and resolution. (As with all CDC tooling, the wire delivery is fundamentally at-least-once; correctness comes from idempotent apply on the target, not from any end-to-end exactly-once guarantee across systems.)

Key differences from Debezium and AWS DMS:

  • Effectively-Once Apply: At-least-once delivery with checkpoint-based, effectively-once apply (idempotent upsert on the primary key, ordered by log position) β€” not end-to-end exactly-once across systems
  • Bidirectional Replication: Active-active configurations with automatic conflict detection and resolution
  • Heterogeneous Support: Replicate between different database platforms (Oracle to PostgreSQL, MySQL to SQL Server, etc.)
  • Trail File Architecture: Persistent, replayable change logs for disaster recovery and data auditing
  • Enterprise Features: Compression, encryption, data transformation, filtering, and mapping capabilities
  • Zero Downtime: Database migrations and upgrades without application interruption
  • Commercial Support: 24/7 Oracle support with SLAs and consulting services

Trade-offs: GoldenGate requires commercial licensing (five-figures-per-processor list pricing; verify against the current Oracle price list), has a steeper learning curve with proprietary configuration syntax, and typically requires dedicated infrastructure and DBA expertise.

Prerequisites

  • Oracle GoldenGate License: Commercial license or Oracle Cloud GoldenGate service subscription
  • Source Database: Oracle Database 11g or later (XE edition works for testing)
  • Target Database: Oracle, PostgreSQL, MySQL, SQL Server, or any supported target
  • Operating System: Linux (RHEL/OEL/Ubuntu), Windows, or Solaris
  • Disk Space: Minimum 10GB for trail files and GoldenGate binaries
  • Network: Stable connection between source and target (Manager port 7809 by default)
  • Database Privileges: DBA-level access for setting up supplemental logging and GoldenGate users

πŸ’‘ Free Testing Options

Option 1: Oracle GoldenGate Free: up to 5 GB per database, non-production (not restricted to XE)
Option 2: Oracle Cloud Free Tier includes GoldenGate service for 30 days
Option 3: Download GoldenGate trial from Oracle Technology Network (OTN) - 30 days evaluation

Architecture

GoldenGate uses a distributed architecture with multiple specialized processes:

SOURCE SYSTEM                     TARGET SYSTEM
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Oracle Database    β”‚           β”‚  Target Database    β”‚
β”‚                     β”‚           β”‚  (Oracle/PG/MySQL)  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚           β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ Redo Logs    β”‚   β”‚           β”‚   β”‚ Target Tablesβ”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚           β”‚   β””β”€β”€β”€β”€β”€β”€β–²β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚         β”‚           β”‚           β”‚          β”‚          β”‚
β”‚         β–Ό           β”‚           β”‚          β”‚          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚           β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   EXTRACT    │───┼──────┐    β”‚   β”‚   REPLICAT   β”‚  β”‚
β”‚  β”‚  (Capture)   β”‚   β”‚      β”‚    β”‚   β”‚   (Apply)    β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚      β”‚    β”‚   β””β”€β”€β”€β”€β”€β”€β–²β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚         β”‚           β”‚      β”‚    β”‚          β”‚          β”‚
β”‚         β–Ό           β”‚      β”‚    β”‚          β”‚          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚      β”‚    β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Trail File  β”‚   β”‚      β”‚    β”‚   β”‚  Trail File  β”‚  β”‚
β”‚  β”‚  (Local)     β”‚   β”‚      β”‚    β”‚   β”‚  (Remote)    β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚      β”‚    β”‚   β””β”€β”€β”€β”€β”€β”€β–²β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚         β”‚           β”‚      β”‚    β”‚          β”‚          β”‚
β”‚         β–Ό           β”‚      β”‚    β”‚          β”‚          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚      β”‚    β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  DATA PUMP   │───┼──────┼────┼──▢│   SERVER     β”‚  β”‚
β”‚  β”‚  (Transfer)  β”‚   β”‚      β”‚    β”‚   β”‚  (Receive)   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚      β”‚    β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                     β”‚      β”‚    β”‚                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚      β”‚    β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   MANAGER    │◀──┼──────┴────┼──▢│   MANAGER    β”‚  β”‚
β”‚  β”‚ (Port 7809)  β”‚   β”‚           β”‚   β”‚ (Port 7809)  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚           β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                Network Connection

Component Descriptions

Extract Process
Reads transaction logs (redo logs for Oracle, binlog for MySQL) and captures DML and DDL operations. Writes captured data to local trail files in GoldenGate's proprietary format.
Trail Files
Persistent, sequential files storing change data. Local trails store data on source system; remote trails store data on target system after network transfer. Trail files are versioned (e.g., ./dirdat/aa000001, aa000002).
Data Pump (Optional)
Secondary extract process that reads local trail files and sends data over network to remote system. Provides network-level buffering and compression. Can be omitted for simple configurations where Extract and Replicat are on the same network with low latency.
Replicat Process
Reads remote trail files and applies transactions to target database. Handles data type conversions, filtering, transformation, and conflict detection. Supports parallel apply for high throughput.
Manager Process
Control process that starts/stops other processes, allocates disk space for trail files, monitors process health, and handles network communication. Must be running on both source and target systems.
Collector (Server)
Receiver process on target system that accepts data from Data Pump and writes to remote trail files. Started automatically by Manager when Data Pump connects.

Lab Setup

Step 1: Install Oracle GoldenGate

Download GoldenGate from Oracle Technology Network or Oracle Cloud. This example uses Oracle GoldenGate 21c for Oracle Database.

⚠️ Legacy path: Classic Architecture (GGSCI)

The fbo_ggs shiphome + GGSCI + CREATE SUBDIRS + ADD EXTRACT flow below is the Classic Architecture, which is deprecated in 21c and removed in GoldenGate 23ai β€” the current release. 23ai ships Microservices Architecture (MA) only, configured through the web-based Admin Client / REST services rather than GGSCI. Follow the steps below only if you are targeting a legacy 21c Classic deployment; new deployments should use Microservices Architecture on 23ai.

# Extract GoldenGate binaries
unzip 211000_fbo_ggs_Linux_x64_Oracle_shiphome.zip
cd fbo_ggs_Linux_x64_Oracle_shiphome/Disk1

# Run installer (GUI mode)
./runInstaller

# Or use silent installation
./runInstaller -silent \
  -responseFile /path/to/oggcore.rsp \
  ORACLE_HOME=/u01/app/oracle/product/21.0.0/oggcore \
  INSTALL_OPTION=ORA21c

# Set environment variables
export OGG_HOME=/u01/app/oracle/product/21.0.0/oggcore
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$OGG_HOME/lib
export PATH=$OGG_HOME:$PATH

Step 2: Create GoldenGate Subdirectories

# Navigate to GoldenGate home
cd $OGG_HOME

# Create required directories using GGSCI
./ggsci

GGSCI> CREATE SUBDIRS

# This creates:
# ./dirprm  - Parameter files
# ./dirdat  - Trail files (local and remote)
# ./dirchk  - Checkpoint files
# ./dirdmp  - Dump files for troubleshooting
# ./dirpcs  - Process status files
# ./dirrpt  - Report files
# ./dirwlt  - Wallet files for encryption
# ./dirdef  - Data definition files

GGSCI> EXIT

Step 3: Configure Source Database (Oracle)

Enable supplemental logging to capture before/after images of changed rows.

-- Connect as SYSDBA
sqlplus / as sysdba

-- Enable archive log mode (required for mining redo logs)
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;

-- Enable minimal supplemental logging
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;

-- Enable force logging (recommended for production)
ALTER DATABASE FORCE LOGGING;

-- Verify settings
SELECT LOG_MODE, SUPPLEMENTAL_LOG_DATA_MIN, FORCE_LOGGING 
FROM V$DATABASE;
-- Should show: ARCHIVELOG, YES, YES

-- Create GoldenGate administrative user
CREATE TABLESPACE ggadmin_tbs 
DATAFILE '/u01/oradata/ORCL/ggadmin01.dbf' 
SIZE 500M AUTOEXTEND ON;

CREATE USER ggadmin IDENTIFIED BY "YOUR_SECURE_PASSWORD"
DEFAULT TABLESPACE ggadmin_tbs
QUOTA UNLIMITED ON ggadmin_tbs;

-- Grant required privileges
GRANT CREATE SESSION TO ggadmin;
GRANT ALTER SESSION TO ggadmin;
GRANT CONNECT TO ggadmin;
GRANT RESOURCE TO ggadmin;
GRANT SELECT ANY DICTIONARY TO ggadmin;
GRANT FLASHBACK ANY TABLE TO ggadmin;
GRANT SELECT ANY TABLE TO ggadmin;
GRANT INSERT ANY TABLE TO ggadmin;
GRANT UPDATE ANY TABLE TO ggadmin;
GRANT DELETE ANY TABLE TO ggadmin;
GRANT ALTER ANY TABLE TO ggadmin;
GRANT LOCK ANY TABLE TO ggadmin;

-- For Oracle 12c+ with PDBs, grant across CDB
-- NOTE: GRANT DBA is heavy-handed. The documented approach is to grant the
-- least-privilege GoldenGate admin role via DBMS_GOLDENGATE_AUTH, e.g.:
--   EXEC DBMS_GOLDENGATE_AUTH.GRANT_ADMIN_PRIVILEGE('ggadmin', container => 'ALL');
GRANT DBA TO ggadmin CONTAINER=ALL;

-- Enable supplemental logging for specific schemas/tables
ALTER TABLE hr.employees ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
ALTER TABLE hr.departments ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;

Step 4: Configure Manager Process

Create parameter file $OGG_HOME/dirprm/mgr.prm on both source and target systems:

-- Manager parameter file (mgr.prm)
PORT 7809
DYNAMICPORTLIST 7810-7820
AUTOSTART ER *
AUTORESTART ER *, RETRIES 3, WAITMINUTES 2
PURGEOLDEXTRACTS ./dirdat/*, USECHECKPOINTS, MINKEEPDAYS 7
LAGREPORTHOURS 1
LAGINFOMINUTES 30
LAGCRITICALMINUTES 60

Start Manager:

cd $OGG_HOME
./ggsci

GGSCI> START MANAGER
GGSCI> INFO MANAGER
-- Should show: Manager is running

GGSCI> EXIT

Step 5: Configure Extract Process

Create parameter file $OGG_HOME/dirprm/ext1.prm on the source system:

-- Extract parameter file (ext1.prm)
EXTRACT ext1
USERID ggadmin, PASSWORD YOUR_SECURE_PASSWORD
EXTTRAIL ./dirdat/aa
DISCARDFILE ./dirrpt/ext1.dsc, PURGE
WARNLONGTRANS 2h, CHECKINTERVAL 30m
FETCHOPTIONS FETCHPKUPDATECOLS, USELATESTVERSION

-- DDL support (optional)
DDL INCLUDE MAPPED

-- Table mappings with filtering
TABLE hr.employees, SQLPREDICATE (department_id IN (10, 20, 30));
TABLE hr.departments;
TABLE hr.job_history;

Register Extract with the database (for Integrated Extract mode - recommended for Oracle 11g+):

./ggsci

GGSCI> DBLOGIN USERID ggadmin, PASSWORD YOUR_SECURE_PASSWORD

-- Register Extract with LogMiner server
GGSCI> REGISTER EXTRACT ext1 DATABASE

-- Add Extract
GGSCI> ADD EXTRACT ext1, INTEGRATED TRANLOG, BEGIN NOW

-- Add local trail file
GGSCI> ADD EXTTRAIL ./dirdat/aa, EXTRACT ext1, MEGABYTES 500

-- Start Extract
GGSCI> START EXTRACT ext1

-- Verify status
GGSCI> INFO EXTRACT ext1, DETAIL

GGSCI> EXIT

Step 6: Configure Data Pump (Optional but Recommended)

Create parameter file $OGG_HOME/dirprm/dpump1.prm on the source system:

-- Data Pump parameter file (dpump1.prm)
EXTRACT dpump1
USERID ggadmin, PASSWORD YOUR_SECURE_PASSWORD
RMTHOST target-hostname, MGRPORT 7809, COMPRESS
RMTTRAIL ./dirdat/bb
PASSTHRU

-- Source trail that Data Pump reads from
TABLE hr.employees;
TABLE hr.departments;
TABLE hr.job_history;
./ggsci

-- Add Data Pump process
GGSCI> ADD EXTRACT dpump1, EXTTRAILSOURCE ./dirdat/aa

-- Add remote trail on target
GGSCI> ADD RMTTRAIL ./dirdat/bb, EXTRACT dpump1, MEGABYTES 500

-- Start Data Pump
GGSCI> START EXTRACT dpump1

-- Verify
GGSCI> INFO EXTRACT dpump1

GGSCI> EXIT

Step 7: Configure Target Database

On target system (can be different database type):

-- For Oracle target
sqlplus / as sysdba

CREATE USER ggadmin IDENTIFIED BY "YOUR_SECURE_PASSWORD";
GRANT CONNECT, RESOURCE, DBA TO ggadmin;

-- Create target schema if it doesn't exist
CREATE USER hr IDENTIFIED BY "YOUR_SECURE_PASSWORD";
GRANT CONNECT, RESOURCE TO hr;
GRANT UNLIMITED TABLESPACE TO hr;

-- Create target tables (schema should match source or use COLMAP)
-- Can use DDL replication or create manually

Step 8: Configure Replicat Process

Create parameter file $OGG_HOME/dirprm/rep1.prm on the target system:

-- Replicat parameter file (rep1.prm)
REPLICAT rep1
ASSUMETARGETDEFS
USERID ggadmin, PASSWORD YOUR_SECURE_PASSWORD
DISCARDFILE ./dirrpt/rep1.dsc, PURGE
REPERROR (DEFAULT, DISCARD)

-- Map source tables to target tables
-- Can rename schemas/tables or transform data
MAP hr.employees, TARGET hr.employees, &
  COLMAP (USEDEFAULTS, &
    salary = salary * 1.1, &
    updated_at = @DATENOW());

MAP hr.departments, TARGET hr.departments;
MAP hr.job_history, TARGET hr.job_history;

⚠️ REPERROR (DEFAULT, DISCARD) silently drops errored rows

REPERROR (DEFAULT, DISCARD) sends any row that errors on apply to the discard file and keeps going. That is convenient in a lab, but it means failed changes are silently skipped β€” the target is no longer a faithful copy of the source, which is incompatible with any "guaranteed delivery" claim. In production, route errors to an exception table (EXCEPTIONSONLY / an exceptions MAP) and monitor the discard file, so nothing is dropped without a record and a path to reconcile it.

./ggsci

GGSCI> DBLOGIN USERID ggadmin, PASSWORD YOUR_SECURE_PASSWORD

-- Add Replicat
GGSCI> ADD REPLICAT rep1, EXTTRAIL ./dirdat/bb, BEGIN NOW

-- Start Replicat
GGSCI> START REPLICAT rep1

-- Verify
GGSCI> INFO REPLICAT rep1, DETAIL

-- Check lag (should be minimal)
GGSCI> LAG REPLICAT rep1

GGSCI> EXIT

Verification

1. Generate Test Data on Source

-- Connect to source database
sqlplus hr/password@source_db

-- Insert records
INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, job_id, department_id)
VALUES (1001, 'John', 'Doe', 'john.doe@example.com', SYSDATE, 'IT_PROG', 60);

INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, job_id, department_id)
VALUES (1002, 'Jane', 'Smith', 'jane.smith@example.com', SYSDATE, 'SA_REP', 80);

COMMIT;

-- Update record
UPDATE employees SET salary = 75000 WHERE employee_id = 1001;
COMMIT;

-- Delete record
DELETE FROM employees WHERE employee_id = 1002;
COMMIT;

2. Verify Replication on Target

-- Connect to target database
sqlplus hr/password@target_db

-- Check if changes were replicated
SELECT employee_id, first_name, last_name, salary 
FROM employees 
WHERE employee_id IN (1001, 1002);

-- Should show employee 1001 with updated salary
-- Employee 1002 should be deleted

3. Monitor GoldenGate Processes

./ggsci

-- Check all processes
GGSCI> INFO ALL

-- Detailed status for specific process
GGSCI> INFO EXTRACT ext1, DETAIL
GGSCI> INFO EXTRACT dpump1, DETAIL
GGSCI> INFO REPLICAT rep1, DETAIL

-- Check lag (time difference between capture and apply)
GGSCI> LAG EXTRACT ext1
GGSCI> LAG REPLICAT rep1

-- View statistics
GGSCI> STATS EXTRACT ext1, TOTAL
GGSCI> STATS REPLICAT rep1, TOTAL

-- Check for errors
GGSCI> VIEW REPORT ext1
GGSCI> VIEW REPORT rep1

GGSCI> EXIT

4. Monitor Trail Files

# Check trail file sizes and sequence
cd $OGG_HOME/dirdat
ls -lh aa* bb*

# View trail file contents
cd $OGG_HOME
./ggsci

GGSCI> OBEY ./dirprm/logdump.prm

# Or use logdump utility directly
./logdump

LOGDUMP> OPEN ./dirdat/aa000001
LOGDUMP> GHDR ON
LOGDUMP> DETAIL ON
LOGDUMP> USERTOKEN ON
LOGDUMP> NEXT 10
-- Shows next 10 transactions

LOGDUMP> EXIT

5. Check Database Statistics

-- Source database
SELECT * FROM dba_capture WHERE capture_name LIKE '%EXT1%';

-- Verify redo log generation
SELECT name, value FROM v$sysstat 
WHERE name LIKE '%redo%';

-- Check GoldenGate heartbeat table (if configured)
SELECT * FROM ggadmin.gg_heartbeat ORDER BY hb_timestamp DESC;

Vendor-Specific Gotchas

⚠️ Common Issues and Solutions

1. OGG-00868: Cannot determine archive log location

Issue: Extract fails to start with "Cannot determine archive log location" error.

Solution: Ensure database is in ARCHIVELOG mode and LOG_ARCHIVE_DEST is set:

ALTER SYSTEM SET LOG_ARCHIVE_DEST_1='LOCATION=/u01/app/oracle/oradata/arch' SCOPE=BOTH;
ALTER DATABASE ARCHIVELOG;
-- Restart database
SHUTDOWN IMMEDIATE;
STARTUP;

2. OGG-01163: Bad column length

Issue: Replicat fails with "Bad column length" when replicating VARCHAR2(4000) columns.

Solution: Use DEFGEN utility to generate source definitions for target:

./defgen PARAMFILE dirprm/defgen.prm

# defgen.prm contents:
DEFSFILE ./dirdef/hr.def
USERID ggadmin, PASSWORD YOUR_SECURE_PASSWORD
TABLE hr.*;

Then update Replicat parameter file:

REPLICAT rep1
SOURCEDEFS ./dirdef/hr.def
-- rest of parameters

3. Extract Lag Increasing

Issue: Extract lag keeps growing, indicating Extract cannot keep up with transaction volume.

Solution: Tune Extract performance:

-- Add to ext1.prm
TRANLOGOPTIONS INTEGRATEDPARAMS (MAX_SGA_SIZE 1024)
BR_CHECKPOINT_INTERVAL 10
-- Increase trail file size
ADD EXTTRAIL ./dirdat/aa, EXTRACT ext1, MEGABYTES 1000

4. OGG-01668: Replicat REPERROR Table Not Found

Issue: Replicat stops when encountering table mapping errors.

Solution: Use HANDLECOLLISIONS during initial load, then remove:

-- For initial synchronization only
REPLICAT rep1
HANDLECOLLISIONS
MAP hr.employees, TARGET hr.employees;

-- After initial load, edit parameter file to remove HANDLECOLLISIONS
-- and restart Replicat

5. Trail File Disk Space Exhaustion

Issue: Trail files fill up disk space, causing Extract to abend.

Solution: Configure automatic trail file purging in mgr.prm:

PORT 7809
PURGEOLDEXTRACTS ./dirdat/*, USECHECKPOINTS, MINKEEPDAYS 2
-- Keeps trail files for 2 days after checkpoint passes them

6. Conflict Detection and Resolution

For bidirectional (active-active) replication, use built-in conflict detection:

-- In Replicat parameter file
REPLICAT rep1
-- Use timestamps for conflict detection
RESOLVECONFLICT (UPDATEROWEXISTS, (DEFAULT, USEMAX(updated_at)))
RESOLVECONFLICT (INSERTROWEXISTS, (DEFAULT, OVERWRITE))
RESOLVECONFLICT (DELETEROWMISSING, (DEFAULT, IGNORE))
MAP hr.employees, TARGET hr.employees;

Caveat: USEMAX(updated_at) is wall-clock last-writer-wins β€” it keeps whichever row carries the higher timestamp. That is subject to clock skew between nodes, so a laggy or misaligned clock can let a stale write win. This site's guidance is to order changes by log position / SCN, not by a wall-clock timestamp; treat timestamp-based resolution as a pragmatic tie-break for active-active only, and keep clocks tightly synchronized (e.g. NTP) if you rely on it.

7. Performance Tuning: Parallel Replicat

For high-volume workloads, use Coordinated Replicat (parallel apply):

-- Add coordinated Replicat
GGSCI> ADD REPLICAT rep1, COORDINATED, EXTTRAIL ./dirdat/bb, BEGIN NOW

-- Parameter file with parallel threads
REPLICAT rep1
USERID ggadmin, PASSWORD YOUR_SECURE_PASSWORD
MAP hr.*, TARGET hr.*, THREAD(4);
-- Uses 4 parallel threads for apply

8. OGG-01403: Max Cascade Depth Reached

Issue: Replication loop detected in multi-tier replication topology.

Solution: Use TRANLOGOPTIONS EXCLUDETAG to prevent loops:

-- On intermediate Extract
EXTRACT ext_middle
TRANLOGOPTIONS EXCLUDETAG 00
-- rest of parameters

Advanced Features

Data Transformation and Filtering

GoldenGate supports complex transformations using built-in functions:

-- Column mapping with transformations
MAP hr.employees, TARGET dwh.dim_employees, &
  COLMAP (USEDEFAULTS, &
    full_name = @STRCAT(first_name, ' ', last_name), &
    salary_usd = salary * 1.0, &
    etl_insert_date = @DATENOW(), &
    is_active = 1);

-- Row filtering with WHERE clause
MAP hr.employees, TARGET hr.employees, &
  WHERE (department_id IN (10, 20, 30) AND salary > 50000);

-- Column filtering
MAP hr.employees, TARGET hr.employees_light, &
  COLMAP (employee_id, first_name, last_name, email);

DDL Replication

Replicate schema changes automatically:

-- Enable DDL capture (source)
EXTRACT ext1
DDL INCLUDE MAPPED OBJTYPE 'TABLE'
DDL INCLUDE MAPPED OPTYPE CREATE, ALTER, DROP

-- Enable DDL apply (target)
REPLICAT rep1
DDL INCLUDE MAPPED

Encryption and Compression

-- Encrypt trail files
EXTRACT ext1
ENCRYPTTRAIL AES256, KEYNAME master_key

-- Compress network traffic
EXTRACT dpump1
RMTHOST target-host, MGRPORT 7809, COMPRESS

Monitoring and Alerting

-- Create heartbeat table for monitoring
CREATE TABLE ggadmin.gg_heartbeat (
  hb_timestamp TIMESTAMP,
  lag_seconds NUMBER
);

-- Add heartbeat to Extract
EXTRACT ext1
TABLE ggadmin.gg_heartbeat, TOKENS (TK-TS = @GETENV('GGHEADER','TIMESTAMP'));

-- Query lag from heartbeat
SELECT 
  EXTRACT(DAY FROM (SYSTIMESTAMP - hb_timestamp)) * 86400 +
  EXTRACT(HOUR FROM (SYSTIMESTAMP - hb_timestamp)) * 3600 +
  EXTRACT(MINUTE FROM (SYSTIMESTAMP - hb_timestamp)) * 60 +
  EXTRACT(SECOND FROM (SYSTIMESTAMP - hb_timestamp)) AS lag_seconds
FROM ggadmin.gg_heartbeat;

Oracle Cloud GoldenGate

Oracle Cloud offers GoldenGate as a fully managed service (GoldenGate Cloud Service / GCS) that eliminates infrastructure management:

  • Deployment Models: Oracle Cloud Infrastructure (OCI) native or hybrid (cloud + on-premises)
  • Automatic Patching: Managed updates and security patches
  • Built-in Monitoring: OCI Monitoring integration with metrics and alarms
  • Web Console: GUI-based configuration instead of command-line GGSCI
  • Pricing: Consumption-based (per OCPU-hour) or monthly subscription

Quick Start with OCI GoldenGate

# Using OCI CLI
oci goldengate deployment create \
  --compartment-id ocid1.compartment.oc1..xxx \
  --display-name "gg-prod-deployment" \
  --subnet-id ocid1.subnet.oc1.xxx \
  --license-model LICENSE_INCLUDED \
  --cpu-core-count 2 \
  --is-auto-scaling-enabled true \
  --deployment-type OGGCORE

# Connect via web console
https://goldengate.us-ashburn-1.oci.oraclecloud.com/deployments/

Cost Considerations

Oracle GoldenGate pricing (indicative only β€” verify against the current Oracle Technology Global Price List, which changes over time):

  • On-Premises License: perpetual, roughly five-figures-per-processor list price plus ~22% annual support; confirm current figures against the Oracle price list
  • Named User Plus: per-named-user list price with a per-processor minimum user count; confirm current figures against the Oracle price list
  • Oracle Cloud (OCI): consumption-based per-OCPU-hour billing; confirm the current OCI GoldenGate rate
  • GoldenGate Free: free, up to 5 GB per database, non-production use (not restricted to Oracle XE)

Infrastructure Costs:

  • Source system: Minimal CPU overhead (1-5% for Extract)
  • Target system: CPU for Replicat (depends on transaction volume)
  • Disk space: Plan for 7-30 days of trail file retention (estimate 1-5GB per million transactions)
  • Network bandwidth: ~10-50% of database transaction log size (with compression)

Tip: For testing, use GoldenGate Free edition with Oracle XE. For production, consider OCI GoldenGate if you're already in Oracle Cloud to avoid upfront licensing costs.

GoldenGate vs. Debezium vs. DMS

Aspect Oracle GoldenGate AWS DMS Debezium
Deployment Self-hosted or OCI managed Fully managed Self-hosted
CDC Method Log-based (redo/archive logs) Log-based Log-based
Latency Sub-second to seconds Seconds Sub-second
Bidirectional Yes (built-in conflict resolution) No No (requires external logic)
Heterogeneous Yes (Oracle↔MySQL↔PostgreSQL↔SQL Server) Yes (limited combinations) Limited (via Kafka to JDBC sink)
Data Format Proprietary trail files Parquet, CSV, or native JSON (Kafka messages)
Transformation Rich (COLMAP, filtering, functions) Basic (table mappings, filters) Medium (SMTs in Kafka Connect)
Delivery Semantics At-least-once delivery; effectively-once apply via checkpoints + PK At-least-once At-least-once (Kafka guarantees)
Licensing Commercial (five-figures-per-processor list pricing; verify current list) Pay-per-use (verify current AWS DMS pricing) Open source (Apache 2.0)
Best For Enterprise Oracle shops, active-active, zero-downtime migrations AWS-native stacks, simple pipelines Event-driven apps, Kafka ecosystems

When to Choose GoldenGate

  • βœ… You have existing Oracle licenses or Oracle Cloud subscription
  • βœ… Need active-active (bidirectional) replication with conflict resolution
  • βœ… Require durable delivery with effectively-once apply across complex multi-tier topologies
  • βœ… Zero-downtime database migrations or version upgrades are critical
  • βœ… Heterogeneous replication between different database vendors
  • βœ… Enterprise support with SLAs is required
  • βœ… Need persistent, replayable change logs for auditing or disaster recovery

When NOT to Choose GoldenGate

  • ❌ Budget-constrained projects (Debezium is free)
  • ❌ Simple unidirectional replication (DMS or Debezium are easier)
  • ❌ Event-driven microservices (Debezium + Kafka is better fit)
  • ❌ Limited DBA resources (GoldenGate has steep learning curve)
  • ❌ Cloud-native, serverless architecture preferred (DMS is simpler)

Next Steps

  • Enable Monitoring: Set up OEM (Oracle Enterprise Manager) GoldenGate plug-in for centralized monitoring
  • Implement Heartbeat: Create heartbeat tables to track end-to-end lag
  • Configure Alerting: Set up SNMP traps or scripts to alert on lag thresholds, process failures
  • Test Failover: Document and practice Extract/Replicat failover procedures
  • Optimize Performance: Use Coordinated Replicat for parallel apply on high-volume tables
  • Implement DDL Replication: Automate schema change propagation
  • Security Hardening: Enable trail file encryption, use Oracle Wallet for password management
  • Document Runbooks: Create operational procedures for common maintenance tasks