LinkedIn pixel

Discover How to Migrate to Oracle AI Database 26ai with Near-Zero Downtime

  • Centroid
  • $
  • Blog
  • $
  • Discover How to Migrate to Oracle AI Database 26ai with Near-Zero Downtime

By Navdeep Saini, Senior Director, Cloud and Technology, Centroid

 

If you need to move a pluggable database (PDB) to Oracle AI Database 26ai but can’t afford a long outage to get there, Oracle Zero Downtime Migration (ZDM) 26.1 has a workflow built for exactly that: refreshable PDB cloning.

ZDM 26.1 introduced the PDB Cloning migration workflow, which gives you three cloning options: cold, hot, and refreshable. Cold and hot cloning copy the PDB once and cut over; refreshable cloning keeps a clone of your source PDB on the target continuously in sync until you’re ready to switch over, so the actual cutover window is just minutes, not hours.

This blog walks through the process of using refreshable PDB cloning to migrate a 19c database to Oracle AI Database 26ai end to end including installing ZDM, building the response file, running the migration in two stages, and troubleshooting for a component-mismatch error you may hit along the way.

Refreshable PDB Cloning

The refreshable cloning workflow splits your migration into two stages, controlled by the pause after option:

  • Stage 1 clones the source PDB into the target CDB and starts refreshing it on a schedule the ZDM_PDB_REFRESH_INTERVAL parameter controls how often, in minutes.
  • Stage 2 is triggered when you resume the job, stops the refresh, performs the final sync, and switches your application over to the target.

As you can imagine, this is great for production databases where you want the bulk of the data transfer to happen well ahead of your cutover window, leaving only a small final delta to apply when you actually flip over.

The Environment

For demonstration purposes, this walkthrough uses OCI Oracle Base Database Service running Oracle AI Database 26ai, version 23.26.1.0.0, as the target.

  • Source: hostname ebsai, IP 10.0.0.253, DB name EBSCDB, DB unique name EBSCDB, PDB name EBSDB
  • Target: hostname smzap-26ai, IP 10.0.0.172, DB name EBS26AI, DB unique name EBS26AI
  • ZDM service host: hostname smzap-zdm

Prerequisites: Installing and Configuring ZDM

Before you can run any migration, ZDM needs to be installed and configured on its own host. The following steps were performed once on the ZDM service host (smzap-zdm).

1.Install required OS packages

As root, install the OS packages ZDM depends on:

[root@smzap-zdm ~]# dnf install -y expect libnsl glibc-devel libstdc++ libaio bc unzip tar

2. Create the OS users and groups

[root@smzap-zdm ~]# groupadd oinstall

[root@smzap-zdm ~]# groupadd dba

[root@smzap-zdm ~]# useradd -m -g oinstall -G dba zdmuser

[root@smzap-zdm ~]# passwd zdmuser

[root@smzap-zdm ~]# mkdir -p /u01/app/zdmhome /u01/app/zdmbase

[root@smzap-zdm ~]# chown -R zdmuser:oinstall /u01/app

[root@smzap-zdm ~]# chmod -R 775 /u01/app

3. Download and stage the ZDM kit

Download the ZDM kit from Oracle Software Delivery Cloud (eDelivery). Search for Oracle Zero Downtime Migration, select the 26.1 release for Linux x86-64, and download. The file is V1055491-01.zip (~1.1 GB). SCP it to smzap-zdm:/tmp/zdm_kit/.

4. Install ZDM

As zdmuser, unzip and run the installer:

[zdmuser@smzap-zdm ~]$ mkdir -p /tmp/zdm_kit

[zdmuser@smzap-zdm ~]$ cd /tmp/zdm_kit

[zdmuser@smzap-zdm zdm_kit]$ cp /path/to/V1055491-01.zip .

[zdmuser@smzap-zdm zdm_kit]$ unzip V1055491-01.zip

[zdmuser@smzap-zdm zdm_kit]$ cd zdm26.1

[zdmuser@smzap-zdm zdm26.1]$ ./zdminstall.sh setup \\\\

oraclehome=/u01/app/zdmhome \\\\

oraclebase=/u01/app/zdmbase \\\\

ziploc=/tmp/zdm_kit/zdm26.1/zdm_home.zip

Expected output ends with:

Adding Certs to ZDM

Adding java jre to ZDM

ZDM service setup finished successfully.

Important: the kit must be staged outside $ZDM_HOME. If you unzip directly into /u01/app/zdmhome, the installer silently skips laying down bin/zdmcli.

5. Start the ZDM service and check status

[zdmuser@smzap-zdm ~]$ /u01/app/zdmhome/bin/zdmservice start

[zdmuser@smzap-zdm ~]$ /u01/app/zdmhome/bin/zdmservice status

Running: true

Conn String: jdbc:derby:/u01/app/zdmbase/derbyRepo;create=true

RMI port: 8897

HTTP port: 8898

SSH port: 22

Wallet path: /u01/app/zdmbase/crsdata/smzap-zdm/security

[zdmuser@smzap-zdm ~]$ /u01/app/zdmhome/bin/zdmcli -build

6. Generate an SSH key for ZDM

ZDM connects to your source and target hosts over SSH, so generate a dedicated key pair and copy it to both:

[zdmuser@smzap-zdm ~]$ ssh-keygen -t rsa -b 4096 -f /home/zdmuser/.ssh/zdm_rsa -N “”

[zdmuser@smzap-zdm ~]$ ssh-copy-id -i /home/zdmuser/.ssh/zdm_rsa.pub oracle@ebsai

[zdmuser@smzap-zdm ~]$ ssh-copy-id -i /home/zdmuser/.ssh/zdm_rsa.pub oracle@smzap-26ai

7. Grant passwordless sudo on the source and target

As root on each host (ebsai and smzap-26ai), allow the oracle OS user to run sudo without a password. ZDM needs this to perform privileged steps during the migration:

[root@ebsai ~]# echo ‘oracle ALL=(ALL) NOPASSWD:ALL’ > /etc/sudoers.d/oracle ; chmod 440 /etc/sudoers.d/oracle

[root@smzap-26ai ~]# echo ‘oracle ALL=(ALL) NOPASSWD:ALL’ > /etc/sudoers.d/oracle ; chmod 440 /etc/sudoers.d/oracle

8. Validate SSH connectivity from the ZDM host

Confirm the ZDM host can reach both source and target as Oracle, and that sudo works without a password prompt:

[zdmuser@smzap-zdm ~]$ ssh -i /home/zdmuser/.ssh/zdm_rsa oracle@ebsai “hostname; id”

ebsai

uid=54321(oracle) gid=54321(oinstall) …

 

[zdmuser@smzap-zdm ~]$ ssh -i /home/zdmuser/.ssh/zdm_rsa oracle@smzap-26ai “hostname; id”

smzap-26ai

uid=54321(oracle) gid=54321(oinstall) …

 

[zdmuser@smzap-zdm ~]$ ssh -i /home/zdmuser/.ssh/zdm_rsa oracle@ebsai “sudo -n id”

uid=0(root) gid=0(root) …

 

[zdmuser@smzap-zdm ~]$ ssh -i /home/zdmuser/.ssh/zdm_rsa oracle@smzap-26ai “sudo -n id”

uid=0(root) gid=0(root) …

With all checks passing, the ZDM host is ready to run migrations.

Running the Migration

Step 1: Create the response file

On the ZDM host, create a response file describing the refreshable clone migration. The key parameters here are ZDM_PDB_CLONE_METHOD=REFRESHABLE and ZDM_PDB_REFRESH_INTERVAL, which sets how often (in minutes) the target PDB refreshes from the source:

[zdmuser@smzap-zdm ~]$ vi /home/zdmuser/zdm_pdb_clone_refreshable.rsp

TGT_DB_UNIQUE_NAME=EBS26AI

MIGRATION_METHOD=ONLINE_PHYSICAL

DATA_TRANSFER_MEDIUM=DBLINK

PLATFORM_TYPE=NON_CLOUD

ZDM_PDB_CLONE_METHOD=REFRESHABLE

ZDM_SRC_PDB_NAME=EBSDB

ZDM_TGT_PDB_NAME=EBSDB_26AI

ZDM_PDB_REFRESH_INTERVAL=5

ZDM_SWITCHOVER=FALSE

Step 2: Evaluate the migration

Before running the real thing, run zdmcli with -eval to validate the migration end to end without making any changes:

[zdmuser@smzap-zdm ~]$ $ZDMHOME/bin/zdmcli migrate database \\\\

-rsp /home/zdmuser/zdm_pdb_clone_refreshable.rsp \\\\

-sourcedb EBSCDB \\\\

-sourcenode ebsai \\\\

-srcauth zdmauth \\\\

-srcarg1 user:oracle \\\\

-srcarg2 identity_file:/home/zdmuser/.ssh/zdm_rsa \\\\

-srcarg3 sudo_location:/usr/bin/sudo \\\\

-targetnode smzap-26ai \\\\

-tgtauth zdmauth \\\\

-tgtarg1 user:oracle \\\\

-tgtarg2 identity_file:/home/zdmuser/.ssh/zdm_rsa \\\\

-tgtarg3 sudo_location:/usr/bin/sudo \\\\

-targethome /u01/app/oracle/product/26.0.0/dbhome_1 \\\\

-tgttdekeystorepasswd \\\\

-ignore PATCH_CHECK \\\\

-eval

 

Enter source database EBSCDB SYS password:

Enter target container database TDE keystore password:

 

Operation “zdmcli migrate database” scheduled with the job ID “1”.

Check the job status:

[zdmuser@smzap-zdm ~]$ $ZDMHOME/bin/zdmcli query job -jobid 1

 

Job ID: 1

User: zdmuser

Job Type: “EVAL”

Current status: SUCCEEDED

Result file path: “/home/zdmuser/zdmbase/chkbase/scheduled/job-1-.log”

Job execution elapsed time: 1 minutes 58 seconds

ZDM_GET_SRC_INFO ………… PRECHECK_PASSED

ZDM_GET_TGT_INFO ………… PRECHECK_PASSED

ZDM_PRECHECKS_SRC ……….. PRECHECK_PASSED

ZDM_PRECHECKS_TGT ……….. PRECHECK_PASSED

ZDM_SETUP_SRC …………… PRECHECK_PASSED

ZDM_SETUP_TGT …………… PRECHECK_PASSED

ZDM_PREUSERACTIONS ……….. PRECHECK_PASSED

ZDM_PREUSERACTIONS_TGT ……. PRECHECK_PASSED

ZDM_VALIDATE_SRC …………. PRECHECK_PASSED

ZDM_VALIDATE_TGT …………. PRECHECK_PASSED

ZDM_POSTUSERACTIONS ………. PRECHECK_PASSED

ZDM_POSTUSERACTIONS_TGT …… PRECHECK_PASSED

ZDM_CLEANUP_SRC ………….. PRECHECK_PASSED

ZDM_CLEANUP_TGT ………….. PRECHECK_PASSED

Step 3: Start the migration and pause before switchover

Now run the same command for real, but this time use -pauseafter to stop the job once the ZDM_FINALIZE_TGT phase completes. This is the phase where the target PDB clone is created and refreshing on the schedule defined by ZDM_PDB_REFRESH_INTERVAL, everything up to your actual cutover happens here, ahead of time:

[zdmuser@smzap-zdm ~]$ $ZDMHOME/bin/zdmcli migrate database \\\\

-rsp /home/zdmuser/zdm_pdb_clone_refreshable.rsp \\\\

-sourcedb EBSCDB \\\\

-sourcenode ebsai \\\\

-srcauth zdmauth \\\\

-srcarg1 user:oracle \\\\

-srcarg2 identity_file:/home/zdmuser/.ssh/zdm_rsa \\\\

-srcarg3 sudo_location:/usr/bin/sudo \\\\

-targetnode smzap-26ai \\\\

-tgtauth zdmauth \\\\

-tgtarg1 user:oracle \\\\

-tgtarg2 identity_file:/home/zdmuser/.ssh/zdm_rsa \\\\

-tgtarg3 sudo_location:/usr/bin/sudo \\\\

-targethome /u01/app/oracle/product/26.0.0/dbhome_1 \\\\

-tgttdekeystorepasswd \\\\

-ignore PATCH_CHECK \\\\

-pauseafter ZDM_FINALIZE_TGT

 

Enter source database EBSCDB SYS password:

Enter target container database TDE keystore password:

 

Operation “zdmcli migrate database” scheduled with the job ID “2”.

Check the job status:

[zdmuser@smzap-zdm ~]$ $ZDMHOME/bin/zdmcli query job -jobid 2

 

Job ID: 2

User: zdmuser

Job Type: “MIGRATE”

Current status: PAUSED

Current Phase: “ZDM_FINALIZE_TGT”

Result file path: “/home/zdmuser/zdmbase/chkbase/scheduled/job-2-.log”

Job execution elapsed time: 35 minutes 12 seconds

ZDM_GET_SRC_INFO …………. COMPLETED

ZDM_GET_TGT_INFO …………. COMPLETED

ZDM_PRECHECKS_SRC ………… COMPLETED

ZDM_PRECHECKS_TGT ………… COMPLETED

ZDM_SETUP_SRC ……………. COMPLETED

ZDM_SETUP_TGT ……………. COMPLETED

ZDM_PREUSERACTIONS ……….. COMPLETED

ZDM_PREUSERACTIONS_TGT ……. COMPLETED

ZDM_VALIDATE_SRC ………….. COMPLETED

ZDM_VALIDATE_TGT ………….. COMPLETED

ZDM_DISCOVER_SRC ………….. COMPLETED

ZDM_COPYFILES ……………… COMPLETED

ZDM_PREPARE_TGT ……………. COMPLETED

ZDM_CLONE_PDB_TGT ………….. COMPLETED

ZDM_FINALIZE_TGT ……………. COMPLETED

ZDM_SWITCHOVER_TGT ………….. PENDING

ZDM_SWITCHOVER_SRC ………….. PENDING

ZDM_NONCDBTOPDB_CONVERSION …… PENDING

ZDM_DATAPATCH_TGT ……………. PENDING

ZDM_POST_DATABASE_OPEN_TGT ……. PENDING

ZDM_POSTUSERACTIONS ………….. PENDING

ZDM_POSTUSERACTIONS_TGT ………. PENDING

ZDM_CLEANUP_SRC ………………. PENDING

ZDM_CLEANUP_TGT ……………….. PENDING

Pause After Phase: “ZDM_FINALIZE_TGT”

At this point you can check the PDB status on the target database and confirm it’s actively refreshing:

SQL> set lines 300

col pdb_name for a15

col refresh_mode for a15

select con_id, pdb_name, status, refresh_mode, refresh_interval from dba_pdbs;

CON_ID PDB_NAME        STATUS    REFRESH_MODE    REFRESH_INTERVAL

—— ————— ——— ————— —————-

3      EBSDB_26AI      REFRESHING AUTO            5

2      PDB$SEED        NORMAL    NONE

This is the state you can sit in for as long as you need. The target keeps refreshing every 5 minutes while you plan your cutover window.

Step 4: Resume the job to switch over

When you’re ready to cut your application over, resume the paused job. ZDM stops the refresh, applies the final delta, and switches over:

[zdmuser@smzap-zdm ~]$ $ZDMHOME/bin/zdmcli resume job -jobid 2

Check the job status again you should see every phase, including the switchover and post-open phases, complete:

[zdmuser@smzap-zdm ~]$ $ZDMHOME/bin/zdmcli query job -jobid 2

 

Job ID: 2

User: zdmuser

Job Type: “MIGRATE”

Current status: SUCCEEDED

Current Phase: “ZDM_CLEANUP_TGT”

Result file path: “/home/zdmuser/zdmbase/chkbase/scheduled/job-2-.log”

Job execution elapsed time: 38 minutes 45 seconds

ZDM_GET_SRC_INFO …………. COMPLETED

ZDM_GET_TGT_INFO …………. COMPLETED

ZDM_PRECHECKS_SRC ………… COMPLETED

ZDM_PRECHECKS_TGT ………… COMPLETED

ZDM_SETUP_SRC ……………. COMPLETED

ZDM_SETUP_TGT ……………. COMPLETED

ZDM_PREUSERACTIONS ……….. COMPLETED

ZDM_PREUSERACTIONS_TGT ……. COMPLETED

ZDM_VALIDATE_SRC ………….. COMPLETED

ZDM_VALIDATE_TGT ………….. COMPLETED

ZDM_DISCOVER_SRC ………….. COMPLETED

ZDM_COPYFILES ……………… COMPLETED

ZDM_PREPARE_TGT ……………. COMPLETED

ZDM_CLONE_PDB_TGT ………….. COMPLETED

ZDM_FINALIZE_TGT ……………. COMPLETED

ZDM_SWITCHOVER_TGT ………….. COMPLETED

ZDM_SWITCHOVER_SRC ………….. COMPLETED

ZDM_NONCDBTOPDB_CONVERSION …… COMPLETED

ZDM_DATAPATCH_TGT ……………. COMPLETED

ZDM_POST_DATABASE_OPEN_TGT ……. COMPLETED

ZDM_POSTUSERACTIONS ………….. COMPLETED

ZDM_POSTUSERACTIONS_TGT ………. COMPLETED

ZDM_CLEANUP_SRC ………………. COMPLETED

ZDM_CLEANUP_TGT ……………….. COMPLETED

Finally, confirm the PDB on the target is now a normal, fully switched-over PDB:

SQL> set lines 300

col pdb_name for a15

col refresh_mode for a15

select con_id, pdb_name, status, refresh_mode, refresh_interval from dba_pdbs;

 

CON_ID PDB_NAME        STATUS    REFRESH_MODE    REFRESH_INTERVAL

—— ————— ——— ————— —————-

3      EBSDB_26AI      NORMAL    NONE

2      PDB$SEED        NORMAL    NONE

And that’s it, your 19c PDB is now running on Oracle AI Database 26ai, with a cutover window measured in minutes instead of hours.

Troubleshooting: Registry Components Mismatch (PRGZ-3944 / ORA-65346)

During ZDM_CLONE_PDB_TGT, you may find the target CDB refuses to clone the source PDB because components present in the source PDB are missing in the target CDB:

PRGZ-3944 : SQL statements to clone a pluggable database (PDB) EBSDB

to a pluggable database EBSDB_26AI on the target multitenant

container database (CDB) EBS26AI failed.

ORA-65346 : The PDB version is lower and components (APS) are missing in CDB.

Diagnose

Compare dba_registry on the source and target CDB$ROOT to identify the missing components. Run this on both the source (EBSCDB) and target (EBS26AI) CDB$ROOT:

set lines 200 pages 200

col comp_id for a10

col comp_name for a45

col version for a30

col status for a12

select comp_id, comp_name, version, status from dba_registry order by comp_id;

In this environment, the source 19c PDB carried APS (OLAP Analytic Workspace) and XOQ (OLAP API) with status OPTION OFF. The 26ai target CDB had no entry for either component at all. The clone-time validator requires matching component presence, regardless of whether OLAP is actually used.

Fix (on the target CDB, as Oracle)

  1. Connect to CDB$ROOT on the target:

ALTER SESSION SET CONTAINER=CDB$ROOT;

  1. Install OLAP Analytic Workspace (APS) objects:

@?/olap/admin/olap.sql SYSAUX TEMP

  1. Install OLAP API (XOQ) objects:

@?/olap/admin/catxoq.sql

If the 26ai binary doesn’t have the OLAP kernel option enabled, these scripts complete but the registry rows show OPTION OFF. Update the registry so the clone validator accepts them:

UPDATE registry$ SET status = 1 WHERE cid IN (‘APS’,’XOQ’);

COMMIT;

— Verify

select comp_id, status from dba_registry where comp_id in (‘APS’,’XOQ’);

— expected: VALID for both

Warning: do NOT run utlrp.sql or any dictionary validation script between this fix and the ZDM job. The validator recomputes component state from binary feature flags and will reset APS/XOQ back to OPTION OFF, causing the same ORA-65346 on the next attempt. Run utlrp.sql only after the clone has succeeded and the PDB has been opened post-cutover.

Resume

After applying the fix, resume the failed ZDM job – it will automatically retry ZDM_CLONE_PDB_TGT:

[zdmuser@smzap-zdm ~]$ $ZDMHOME/bin/zdmcli resume job -jobid 2

Why This Approach Is Worth Using

Stepping back, here’s what the walkthrough above actually did. You installed and configured ZDM 26.1 on a dedicated host OS package, the zdmuser account, SSH trust, and passwordless sudo to both the source (ebsai) and target (smzap-26ai) hosts. From there, you built a response file telling ZDM to use the REFRESHABLE PDB clone method with a 5-minute refresh interval, ran an eval pass to validate the plan with zero risk, and then kicked off the real migration with pause after ZDM_FINALIZE_TGT.

That single flag is what splits the migration into two stages: ZDM clones EBSDB into the target CDB as EBSDB_26AI and keeps it continuously refreshing, then sits and waits. When you were ready, resuming the job triggered the final sync and switchover, converting EBSDB_26AI from a REFRESHING clone into a NORMAL, fully operational PDB on Oracle AI Database 26ai.

The reason this is worth the extra setup is the cutover math. A traditional cold clone or full export/import must move all of your data, which for a multi-terabyte EBS database can take hours inside the maintenance window your business actually feels. Refreshable PDB cloning moves that bulk transfer out of the window entirely: the clone is created and kept in sync days or even weeks ahead of time, refreshing automatically every ZDM_PDB_REFRESH_INTERVAL minutes. When the time comes to cut over, ZDM only has to apply the last few minutes of changes, so your actual outage shrinks to the time it takes to run the final sync, switchover, and datapatch phases, typically minutes, not hours.

This makes the approach particularly useful for production databases with strict change-control windows, think E-Business Suite, ERP, or other systems where the business can tolerate a short maintenance window but not an extended one. It’s also valuable when you’re migrating across platforms (on-premises to OCI, as in this example) where network transfer time for the initial copy is the dominant cost: refreshable cloning lets that transfer happen well in advance and on its own schedule, decoupled from your go-live date. And because the job pauses cleanly at ZDM_FINALIZE_TGT, you get a natural checkpoint to run validation, application testing, or, as covered in the troubleshooting section, fix registry component mismatches like the ORA-65346 / PRGZ-3944 error before you commit to the final switchover.

Ready to modernize your Oracle environment with minimal downtime? Whether you’re planning a PDB migration or a broader database transformation, Centroid’s Oracle consultants can help every step of the way. Reach out to Centroid to explore how we can simplify your migration and maximize the value of your Oracle investments.

Explore More Insights

Get your customized JDE cloud migration roadmap

Unlock a clear path to a more efficient, scalable Oracle JD Edwards environment with OCI. Sign up for a consultation with our experts, and we’ll provide a cloud migration roadmap designed for your business needs. 

You're one step closer to AI-powered insights.

Fill out the form to request your complimentary software assessment. Our experts will review your Oracle EBS environment and provide personalized recommendations to help you maximize its value with EBS VisionIQ.

Subscribe to the Centroid BlogWire

Get the Latest Cloud and IT Insights—Delivered Right to Your Inbox Every Month!

By submitting this form you agree to receive communications from Centroid. You can opt-out at any time. Privacy Policy. Please enter a valid company email to ensure delivery.