I’ve been putting off writing this one for a while, mostly because every time I sit down to do it I remember another edge case that bit me on some engagement. But we’ve now done enough of these migrations at client sites that the pattern is stable enough to write down.
Quick framing before we start. Classic Architecture …the one with GGSCI, a Manager process, and the whole thing driven by parameter files you edit with EDIT PARAMS … is gone in the latest release. GoldenGate 23ai is delivered for the Microservices Architecture only; 23ai no longer supports Classic Architecture at all. So this isn’t really a “should we migrate” conversation anymore. It’s a “when and how” conversation. And the timing pressure is real — Premier Support for GoldenGate 19c and 21c is ending in April 2026, so a lot of shops are up against it.
One correction to a thing people often get muddled: Classic Extract and Classic Architecture are two different deprecations. Classic Extract (as opposed to Integrated Extract) was deprecated in 18c and desupported in 21c. Classic Architecture … the whole GGSCI/Manager control plane … is what’s removed in 23ai. If you’re still running a Classic Extract, you have to move to Integrated Extract before you migrate architecture; the migration utility will simply fail if a classic extract is configured
he thing people get wrong is assuming this is a rewrite. It isn’t. Your Extract and Replicat processes do the same work, read the same redo, apply the same DML. What changes is the control plane around them.
In Classic you had a Manager process listening on a port, GGSCI as your shell, and everything living under one $OGG_HOME that mixed binaries with runtime data. Microservices splits this apart:
- ServiceManager : supervises the deployment
- Administration Service : replaces Manager and GGSCI’s admin functions
- Distribution Service : replaces the pump Extract for sending trails downstream
- Receiver Service .. receives distribution paths on the target side
- Performance Metrics Service : metrics collection
And critically, binaries now live in OGG_HOME while runtime config, trails, and reports live in a separate deployment directory. That separation is genuinely nice once you get used to it … deployments can just point at a new OGG_HOME, which makes upgrades much less scary. You also get adminclient instead of GGSCI (the GGSCI-equivalent tool is still available as the Admin Client), a REST API for everything, and a web UI. The parameter file syntax itself is almost entirely unchanged, which is the good news.
One replicat note while we’re here, because it caught a colleague out: in 23ai, Integrated Replicat cannot read an EXTFILE … only non-integrated (classic-mode) Replicat can, and for OLTP workloads Oracle recommends Parallel Replicat in non-integrated mode. Keep that in mind if your config reads files rather than trails.
There are genuinely two ways to do this, and you should pick deliberately.
Path A :: the Migration Utility. Oracle ships a dedicated tool. It’s available on My Oracle Support as Patch 37274898 (KB100447), it’s interactive, and it migrates Extracts and Replicats from a Classic deployment to a Microservices deployment, converts pumps to a distribution path, and also migrates trail files, checkpoints, and associated artifacts. That “converts pumps to a distribution path automatically” bit is the big selling point — the pump conversion is the fiddliest part to do by hand. Prerequisites are mentiopned below.
- GoldenGate 19c or higher with Bundle Patch 200714 or later, and Java 1.8 JRE or later (the one shipped with GoldenGate works).
- A new Microservices deployment already created with all services running, local to the Classic deployment (or the Classic home filesystem available on the same host).
- The Classic deployment must be stopped during migration, including any server collectors; abended processes must be restarted and shut down gracefully first.
- Run the utility from a shell with the environment variables set for the Microservices deployment.
The invocation is a Java jar with a dry-run mode. Set OGG_HOME and LD_LIBRARY_PATH to the 23ai home first, then .. Note: Always run -dryrun first and read every line of what it says it will migrate.
export OGG_HOME=/u01/app/oracle/product/ogg23ai
export LD_LIBRARY_PATH=$OGG_HOME/lib
java -jar ogg-migration-package-23.4.0.0.0.jar \
-classicHome /u01/app/oracle/product/ogg19 -dryrun
Path B : rebuild by hand. The reason I still reach for this on some engagements: a rebuild forces you to look at every parameter file. I’ve never done one of these without finding a parameter sitting there since 12c doing nothing, or a table in a wildcard that should’ve been excluded three years ago. The utility faithfully preserves your accumulated cruft. If you have twelve well-documented Extracts, use the utility. If you have three and a suspicion nobody’s audited them lately, rebuild.
The rest of this post covers the manual path, because even if you use the utility you should understand what it’s doing under the hood. Before you touch anything, verify the source is clean. On the Classic side:
GGSCI> INFO ALL
GGSCI> SEND EXTRACT ext1, STATUS
GGSCI> LAG EXTRACT ext1
GGSCI> LAG REPLICAT rep1
You want Extract at EOF on redo, Replicat with zero lag and no pending transactions. Anything else and you’re migrating a mess. Then record checkpoint positions. People rush this and regret it:
GGSCI> INFO EXTRACT ext1, SHOWCH
GGSCI> INFO REPLICAT rep1, SHOWCH
Write these down somewhere outside the server … the Extract’s Recovery Checkpoint SCN especially. I once watched a team lose a checkpoint during a rushed cutover and end up repositioning from an SCN that only existed in a terminal scrollback someone had already closed.
Your checkpoint table and GoldenGate DB user carry over fine … the checkpoint table format is compatible, and DBMS_GOLDENGATE_AUTH.GRANT_ADMIN_PRIVILEGE grants don’t need redoing.
Installing Microservices alongside : Install to a new OGG_HOME. Do not install over Classic … you want both available during transition so rollback is real, not theoretical. And per Oracle’s own prereq, the new MA deployment needs to be on the same host (or the Classic home reachable there).
cd /stage/ogg23ai
./runInstaller -silent -responseFile /stage/ogg_install.rsp
Then create the deployment with the config assistant, oggca.sh, which has a silent mode I prefer for repeatability … along with some of the key oggca response entries:
export OGG_HOME=/u01/app/ogg/23ai
$OGG_HOME/bin/oggca.sh -silent -responseFile /stage/oggca.rsp
-- some of the key entries
CONFIGURATION_OPTION=ADD
DEPLOYMENT_NAME=ogg_prod
ADMINISTRATOR_USER=oggadmin
HOST_SERVICEMANAGER=dbhost01.example.com
PORT_SERVICEMANAGER=9000
SECURITY_ENABLED=false
OGG_SOFTWARE_HOME=/u01/app/ogg/23ai
OGG_DEPLOYMENT_HOME=/u01/app/ogg/deployments/ogg_prod
OGG_SCHEMA=ggadmin
PORT_ADMINSRVR=9001
PORT_DISTSRVR=9002
PORT_RCVRSRVR=9003
PORT_PMSRVR=9004
I’ve set SECURITY_ENABLED=false for readability. In production, don’t … turn on TLS and point it at a proper wallet. The extra hour isn’t worth having your REST API sitting in the clear.
Credentials: Classic used a credential store under $OGG_HOME/dircrd; Microservices has its own per deployment. Just recreate them … cleaner than copying wallet files … One important note is that the CONNECT … you’re connecting to the Administration Service over HTTP, not opening a local shell.
$OGG_HOME/bin/adminclient
OGG> CONNECT http://dbhost01:9001 AS oggadmin PASSWORD ******
OGG> ALTER CREDENTIALSTORE ADD USER ggadmin@ORCLPDB1 PASSWORD ****** ALIAS ggsrc DOMAIN OracleGoldenGate
OGG> INFO CREDENTIALSTORE
Migrating Parameter Files: Mostly copy-paste. Two differences. The DOMAIN clause .. MA credential stores are domain-scoped, and OracleGoldenGate is the default domain. And the trail: you give just the two-character prefix, resolved relative to the deployment’s dirdat. Register and add it, positioning at the checkpoint SCN you recorded (not BEGIN NOW):
-- Classic
EXTRACT ext1
USERIDALIAS ggsrc
EXTTRAIL ./dirdat/ea
TABLE SALES.ORDERS;
-- Microservices
EXTRACT ext1
USERIDALIAS ggsrc DOMAIN OracleGoldenGate
EXTTRAIL ea
TABLE SALES.ORDERS;
-- Register and add it, positioning at the checkpoint SCN you recorded (do not BEGIN NOW)
OGG> DBLOGIN USERIDALIAS ggsrc DOMAIN OracleGoldenGate
OGG> REGISTER EXTRACT ext1 DATABASE CONTAINER (ORCLPDB1)
OGG> ADD EXTRACT ext1, INTEGRATED TRANLOG, SCN 45892017334
OGG> ADD EXTTRAIL ea, EXTRACT ext1, MEGABYTES 500
One accuracy note specific to 23ai targets: Per-PDB Extract is the only supported Extract for Oracle Database 23ai, except in a DownStream Capture configuration, where you use a root-level Extract and must set the Streams Pool. That doesn’t change a 19c-source migration, but if your database is also moving to 23ai, plan the Extract mode accordingly. For Replicat, this is a good moment to move to Parallel Replicat:
OGG> DBLOGIN USERIDALIAS ggtgt DOMAIN OracleGoldenGate
OGG> ADD REPLICAT rep1, PARALLEL, EXTTRAIL ra, CHECKPOINTTABLE ggadmin.ggs_checkpoint
The PUMP replacement : Biggest conceptual change. The Classic data pump … a secondary Extract with RMTHOST/RMTTRAIL pushing to the target Manager … becomes a Distribution Path in the Distribution Service, with no parameter file. On authentication, be aware there’s a real choice here: Microservices offers USERIDALIAS target authentication (an Operator-role user on the target whose credentials are stored on the source; the path’s target auth method is set to Password and it uses the WSS secure web socket protocol) or certificate-based authentication using trusted CA certificates. Via adminclient against the Distribution Service:
OGG> CONNECT http://dbhost01:9002 AS oggadmin PASSWORD ******
OGG> ADD DISTPATH dp1 SOURCE trail://localhost/services/v2/sources?trail=ea -
TARGET wss://tgthost01:9003/services/v2/targets?trail=ra
OGG> START DISTPATH dp1
OGG> INFO DISTPATH dp1
I’ve used wss:// (secure WebSocket) for the target because that’s what you want across any network you don’t fully trust … and it’s the protocol tied to the USERIDALIAS/password method above. The Receiver Service on the target picks the path up automatically; there’s nothing to configure there beyond having it running and the port reachable. That’s a real simplification over Classic’s Manager-plus-Collector dance.
Lets discuss a real time production cutover sequence, specially what comes fiorst and second and later on as it matters the most.
– Stop Classic Extract, let pump and Replicat drain fully:
GGSCI> STOP EXTRACT ext1
GGSCI> SEND EXTRACT pump1, LOGEND
GGSCI> INFO REPLICAT rep1
Note: Wait for Replicat to show At EOF, no more records to process. Don't rush this. Its important.
– Stop pump and Replicat, record final positions, stop Manager:
GGSCI> STOP EXTRACT pump1
GGSCI> STOP REPLICAT rep1
GGSCI> INFO REPLICAT rep1, SHOWCH
GGSCI> STOP MANAGER
– Start the MA Extract at the SCN where Classic stopped:
OGG> ALTER EXTRACT ext1, SCN 45892017334
OGG> START EXTRACT ext1
– Start the path, then the Replicat:
OGG> START DISTPATH dp1
OGG> START REPLICAT rep1
– Verify with real traffic before declaring victory 🙂
OGG> INFO ALL
OGG> STATS EXTRACT ext1, TOTAL
OGG> STATS REPLICAT rep1, TOTAL
OGG> LAG REPLICAT rep1
Then do an actual data comparison … Veridata if licensed, row-count-plus-checksum on your highest-churn tables if not. I’ve seen an Extract sit happily in RUNNING while silently missing a table because a wildcard didn’t match what someone assumed.
Some of the items that might surpirse you 🙂
Ports. Four to five per deployment plus ServiceManager. If firewall changes take two weeks in your shop, start that request before the migration. Reverse proxy. Oracle recommends fronting the services with NGINX so everything comes through one port … there’s a generator script under the reverse proxy tooling. Worth doing, but I get the migration working direct-to-ports first, then add the proxy. Trail compatibility. Classic-written trails can be read by MA Replicat, so if you need to, you can point an MA Replicat at old Classic trails to drain them. Useful escape hatch. Desupported parameters (Thanks for highlighting it @Alex Lima). Audit your files. 23ai removed Integrated Replicat, dropped Blowfish encryption, removed trace-table functionality, and replaced FILTERTABLE with EXCLUDEFILTERTABLE. If any of those are lurking in a parameter file, they’ll bite you.
adminclient is not GGSCI. ADD/START/STOP/INFO/STATS behave as expected; SEND MANAGER is gone; DBLOGIN is per-service and you’ll re-issue it more often than you’d like.
The migration itself is a few hours for a typical two-node config. The real time cost is elsewhere … updating monitoring, rewriting operational scripts against the REST API instead of parsing GGSCI output, retraining whoever runs the environment at 3am. Start that early. The Extract and Replicat will be fine. It’s the ecosystem around them that takes the time.
Hope It Helped!
Prashant Dixit




