Upgrade Encrypted Oracle Database 19c Non-CDB to 26ai and Convert to PDB Using Refreshable Clone PDB

Let me show you how to upgrade an encrypted non-CDB to Oracle AI Database 26ai. Since this release only supports the multitenant architecture, you must also convert it to a PDB.

To preserve the source database for rollback and to minimize downtime, I’ll use AutoUpgrade and refreshable clone PDBs.

How to Upgrade and Convert

AutoUpgrade and refreshable clone PDBs give you the option of moving the database to a different host. If you want to stay on the same host, just imagine source and target hosts are the same.

Start by familiarizing yourself with the restrictions on refreshable clone PDB for non-CDBs.

1. Preparations

I’ve already prepared my database.

I’ve also installed a new Oracle home and created a new CDB, or decided to use an existing one. The CDB can be on the same or a different system than the source non-CDB.

  1. In the source non-CDB, I create a user:
    create user dblinkuser identified by ... ;
    grant create session, 
    create pluggable database, 
    select_catalog_role to dblinkuser;
    grant read on sys.enc$ to dblinkuser;
    
    • I need the user so I can connect from the CDB via a database link.
    • I’ll drop it after the upgrade.
  2. In my target CDB, as SYS, I create a database link connecting to my source non-CDB:
    create database link clonepdb 
    connect to dblinkuser identified by ...
    using 'source-db-alias';
    

2. Analyze

I must run the pre-upgrade analysis on the source system.

  1. I create an AutoUpgrade config file for the analysis. I call it upgrade26-analyze.cfg:
    global.global_log_dir=/home/oracle/autoupgrade/upgrade26-analyze
    upg1.source_home=/u01/app/oracle/product/19
    upg1.target_version=26
    upg1.sid=FTEX
    upg1.target_cdb=CDB26
    upg1.target_is_remote=yes
    
    • Since the target Oracle home doesn’t exist on my source system, I omit target_home.
    • Without the target Oracle home, AutoUpgrade can’t deduce the version I’m upgrading to, so I must specify target_version=26.
    • I specify target_is_remote=yes because the CDB is on another system. This causes AutoUpgrade to skip a few checks that it would normally run.
  2. I start AutoUpgrade in analyze mode:
    java -jar autoupgrade.jar -config upgrade26-analyze.cfg -mode analyze
    
  3. I check the pre-upgrade summary report:
    cd /home/oracle/autoupgrade/kraken/cfgtoollogs/upgrade/auto/status
    vi status.log
    

3. Initial Clone

  1. I create a config file on my target system. I call it upgrade26.cfg:
    global.global_log_dir=/home/oracle/autoupgrade/upgrade26
    global.keystore=/home/oracle/autoupgrade/keystore
    upg1.source_home=/tmp
    upg1.source_base=/u01/app/oracle
    upg1.target_home=/u01/app/oracle/product/26
    upg1.sid=FTEX
    upg1.target_cdb=CDB26
    upg1.source_dblink.FTEX=CLONEPDB 1800
    upg1.target_pdb_name.FTEX=PDB1
    upg1.start_time=19/01/2038 03:14:07
    upg1.parallel_pdb_creation_clause.FTEX=2
    upg1.target_pdb_copy_option.FTEX=file_name_convert=NONE
    upg1.drop_dblink=yes
    
    • I set source_home to /tmp because it doesn’t exist on the target system. I set source_base to the Oracle base of my target system.
    • sid is the database that I want to upgrade and convert.
    • target_cdb is the SID of the database where the non-CDB ends up.
    • source_dblink.<sid> is the name of the database link and the refresh rate in seconds.
    • target_pdb_name.<sid> allows me to rename the database. I strongly recommend that you rename the database if your CDB is on the same system. Otherwise, you’ll have a service name collision to deal with.
    • start_time is when AutoUpgrade performs the final refresh and starts the upgrade/conversion. I set it far out in the future, so I can better control the final refresh using the proceed command. Leave a comment if you know what happens at the specified time. :-)
    • parallel_pdb_creation_clause.<sid> limits the number of parallel processes used by the CDB to make the initial copy. Set it at a reasonable level that doesn’t overload the source database.
    • target_pdb_copy_option.<sid> allows me to specify the location of the data files. I use OMF and let the database decide where to put the files.
    • drop_dblink instructs AutoUpgrade to drop the database link when it’s no longer needed.
  2. I start the AutoUpgrade password console to load the target CDB keystore password:
    java -jar autoupgrade.jar -config upgrade26.cfg -load_password
    
    • This is required because my database is encrypted.
    • AutoUpgrade prompts me for the AutoUpgrade keystore password. This is a password to protect the AutoUpgrade keystore; not the database keystore.
  3. I want to add the database keystore password of the target CDB:
    TDE> add CDB26
    
    • CDB26 is the SID of the database and matches the target_cdb parameter in the config file.
    • I must enter the database keystore password.
  4. I save the database keystore password in the AutoUpgrade keystore:
    TDE> save
    
    • I agree to create an auto-login keystore and enter yes when prompted.
  5. Exit from the password console:
    TDE> exit
    
  6. Next, I start AutoUpgrade in deploy mode:
    java -jar autoupgrade.jar -config upgrade26.cfg -mode deploy
    
    • AutoUpgrade copies the data files over the database link.
    • Rolls the copies of the data files forward with redo from the source non-CDB.
    • There’s no outage. The source database remains open.
  7. Leave the AutoUpgrade session running.
    • Since the session might run for a while, better start it with tmux, screen, or similar.
    • Don’t use nohup because you must be able to interact with AutoUpgrade.
    • If your session disconnects, just restart AutoUpgrade with the same command.

4. Upgrade And Convert

The maintenance window has started, and users have left the database.

  1. On the source system, I run the pre-upgrade fixups on the source database:

    java -jar autoupgrade.jar -config upgrade26-analyze.cfg -mode fixups 
    
    • AutoUpgrade informs me that it can’t run certain preupgrade fixups because the target Oracle home doesn’t exist on the source system. This is expected and ignorable.
  2. Next, I switch to the target system. From the AutoUpgrade console, I instruct AutoUpgrade to proceed with the upgrade:

    upg> proceed -job 100
    
    • AutoUpgrade performs a final refresh.
    • Then, it disconnects the PDB from the source.
    • Then, starts the upgrade and conversion.
  3. While the job progresses, I monitor it:

    upg> lsj -a 30
    
    • The -a 30 option automatically refreshes the information every 30 seconds.
    • I can also use status -job 100 -a 30 to get detailed information about a specific job.
  4. In the end, AutoUpgrade completes the upgrade:

    Job 101 completed
    ------------------- Final Summary --------------------
    Number of databases            [ 1 ]
    
    Jobs finished                  [1]
    Jobs failed                    [0]
    Jobs restored                  [0]
    Jobs pending                   [0]
    
    Please check the summary report at:
    /home/oracle/autoupgrade/upgrade26/cfgtoollogs/upgrade/auto/status/status.html
    /home/oracle/autoupgrade/upgrade26/cfgtoollogs/upgrade/auto/status/status.log
    
    • This includes the post-upgrade checks and fixups.
  5. I review the Autoupgrade Summary Report. The path is printed to the console:

    vi /home/oracle/autoupgrade/upgrade26/cfgtoollogs/upgrade/auto/status/status.log
    
  6. I take care of the post-upgrade tasks.

  7. I update any profiles or scripts that use the database.

  8. I ensure that the source non-CDB is shut down.

    • If source non-CDB and target CDB are on the same system, AutoUpgrade stops the source non-CDB. You can override this using the parameter close_source.
    • When I’m sure I won’t need the source non-CDB anymore, I can delete it.
  9. I can remove the database link user:

    drop user dblinkuser cascade;
    
  10. Recreate the connection services.

  11. If you’ve configured Data Guard on your target CDB, you must restore the PDB on all standbys. Check the appendix for details.

That’s It!

With AutoUpgrade, you can easily upgrade your encrypted non-CDB and convert it to a PDB. For maximum protection, AutoUpgrade lets me preserve the source non-CDB in case I need to roll back.

Check the other blog posts related to upgrade to Oracle AI Database 26ai.

Happy upgrading!

Appendix

What If I Have Data Guard

Refreshable clone PDB doesn’t propagate fully to the standbys. The plug-in operation happens with deferred recovery.

After plug-in on the primary database, the standbys don’t protect the PDB. You must first restore the PDB to each standby database.

Also, check pages 210-221 in Move to Oracle Database 23ai – Everything you need to know about Oracle Multitenant – part 1.

Draining the Source Non-CDB

When your maintenance window starts, you must kick users off.

In a previous blog post, I gave an idea on how you can do that. Whatever you do, don’t restart the source database. It’ll break the refreshable clone PDB.

Does It Work Cross-Platform

Refreshable clone PDB does not work for cross-endian migrations (like AIX to Linux), but cross-platform should work fine (like Windows to Linux).

What If My Database Is A RAC Database?

  • Ensure that all instances can resolve the database link connection identifier and that the database link works from all instances. The CREATE PLUGGABLE DATABASE statement scales out on all instances for the initial cloning.
  • In your config file, when specifying the sid parameter you must use the SID on the node where AutoUpgrade runs. If my database is called DB19 and it runs on host1 which is instance 1 in my cluster, I’d specify:
    upg1.sid=DB191
    
  • Recreate services in the target CDB using srvctl. If you have many services, consider export/import of the services.

Other Config File Parameters

The config file shown above is a basic one. Let me address some of the additional parameters you can use.

  • timezone_upg: AutoUpgrade upgrades the database time zone file after the actual upgrade. This requires an additional restart of the database and might take significant time if you have lots of TIMESTAMP WITH TIME ZONE data. If so, you can postpone the time zone file upgrade or perform it in a more time-efficient manner.

  • before_action / after_action: Extend AutoUpgrade with your own functionality by using scripts before or after the job.

Compatible

During plug-in, the PDB automatically inherits the compatible setting of the target CDB. You don’t have to raise the compatible setting manually.

Typically, the target CDB has a higher compatible and the PDB raises it on plug-in. This means you don’t have the option of downgrading.

If you want to preserve the option of downgrading, be sure to set the compatible parameter in the target CDB to the same value as the source CDB.

Upgrade Oracle Database 19c Non-CDB to 26ai and Convert to PDB

Let me show you how to upgrade a non-CDB to Oracle AI Database 26ai. Since this release only supports the multitenant architecture, you must also convert it to a PDB.

How to Upgrade and Convert

I’ve already prepared my database and installed a new Oracle home. I’ve also created a new container database or decided to use an existing one.

The maintenance window has started, and users have left the database.

  1. This is my AutoUpgrade config file:

    global.global_log_dir=/home/oracle/autoupgrade/logs/FTEX-CDB26
    upg1.source_home=/u01/app/oracle/product/19
    upg1.target_home=/u01/app/oracle/product/26
    upg1.sid=FTEX
    upg1.target_cdb=CDB26
    upg1.export_rman_backup_for_noncdb_to_pdb=yes
    upg1.target_pdb_name=PDBFTEX
    upg1.target_pdb_copy_option=file_name_convert=none
    
    • I specify the source and target Oracle homes. I’ve already installed the target Oracle home.
    • sid contains the SID of my database.
    • target_cdb specifies the SID of the container where I plug into.
    • export_rman_backup_for_noncdb_to_pdb instructs AutoUpgrade to export RMAN metadata using DBMS_PDB.EXPORTRMANBACKUP. This makes it easier to use pre-plugin backups (see appendix).
    • target_pdb_name tells AutoUpgrade to rename the PDB.
    • target_pdb_copy_option instructs AutoUpgrade to copy the data files on plug-in and generate new OMF names. If I omit the parameter, AutoUpgrade reuses the data files. See the appendix for more details on copying or re-using data files.
    • Check the appendix for additional parameters.
  2. I start AutoUpgrade in deploy mode:

    java -jar autoupgrade.jar -config FTEX-CDB26.cfg -mode deploy
    
    • AutoUpgrade starts by analyzing the database for upgrade readiness and executes the pre-upgrade fixups.
    • Next, it creates a manifest file and shuts down the non-CDB.
    • Finally, it plugs the database in and follows with an upgrade and non-CDB to PDB conversion.
  3. While the job progresses, I monitor it:

    upg> lsj -a 30
    
    • The -a 30 option automatically refreshes the information every 30 seconds.
    • I can also use status -job 100 -a 30 to get detailed information about a specific job.
  4. In the end, AutoUpgrade completes the upgrade:

    Job 101 completed
    ------------------- Final Summary --------------------
    Number of databases            [ 1 ]
    
    Jobs finished                  [1]
    Jobs failed                    [0]
    Jobs restored                  [0]
    Jobs pending                   [0]
    
    Please check the summary report at:
    /home/oracle/autoupgrade/logs/FTEX-CDB26/cfgtoollogs/upgrade/auto/status/status.html
    /home/oracle/autoupgrade/logs/FTEX-	CDB26/cfgtoollogs/upgrade/auto/status/status.log
    
    • This includes the post-upgrade checks and fixups.
  5. I review the Autoupgrade Summary Report. The path is printed to the console:

    vi /home/oracle/autoupgrade/logs/FTEX-CDB26/cfgtoollogs/upgrade/auto/status/status.log
    
  6. I take care of the post-upgrade tasks.

  7. I update any profiles or scripts that use the database.

  8. AutoUpgrade removes the non-CDB entry from /etc/oratab and Grid Infrastructure.

    • However, AutoUpgrade doesn’t remove:
      • Database files, like PFile, SPFile, password file, control file, and redo logs.
      • Database directory, like diagnostic_dest, adump, or db_recovery_file_dest.
      • Data files or temp files
    • I can remove the above file and directories when I’m sure that I won’t need a rollback.
    • If I plug in and reuse the data files (omit target_pdb_copy_option), the data files remain in the non-CDB location. Take care you don’t delete them by mistake; they are now used by the PDB.

That’s It!

With AutoUpgrade, you can easily upgrade your non-CDB and convert it to a PDB. For maximum flexibility, AutoUpgrade lets me copy or reuse the data files.

Check the other blog posts related to upgrade to Oracle AI Database 26ai.

Happy upgrading!

Appendix

Rollback Options

When you convert a non-CDB to a PDB, you can’t use Flashback Database as a rollback method. You need to rely on other methods, like:

  • Copy data files by using target_pdb_copy_option.
  • RMAN backups.
  • Storage snapshots.

In this blog post, I copied the data files (using target_pdb_copy_option). This means the original data files are left untouched. In case of a rollback, I just need to reinstate the non-CDB instance (FTEX).

java -jar autoupgrade.jar -config cdb1.cfg -restore -jobs 101
  • In the jobs parameter, I specify the job ID that originally upgraded the database.
  • AutoUpgrade now recreates the FTEX instance using the original files (data files, control file, redo logs, and so on).

Copy or Re-use Data Files

When you plug into a CDB and convert your database to a PDB, you must decide what to do with the data files.

Copy Re-use
Plug-in Time Slow, needs to copy data files. Fast, re-uses existing data files.
Disk space Need room for a full copy of the data files. No extra disk space.
Rollback Source data files are left untouched. Re-open source database. Check remove_rac_config. Source database unusable. Rely on other rollback method.
AutoUpgrade Enable using target_pdb_copy_option. Default. Omit parameter target_pdb_copy_option.
Location after plug-in The data files are copied to the desired location. The data files are left in the non-CDB location. Don’t delete them by mistake. Consider moving them using online data files move.
Syntax used CREATE PLUGGABLE DATABASE ... COPY CREATE PLUGGABLE DATABASE ... NOCOPY

target_pdb_copy_option

Use this parameter only when you want to copy the data files.

  • target_pdb_copy_option=file_name_convert=('/u02/oradata/FTEX', '/u02/oradata/PDBFTEX','search-1','replace-1') When you have data files in a regular file system. The value is a list of pairs of search/replace strings.
  • target_pdb_copy_option=file_name_convert=none When you want data files in ASM or use OMF in a regular file system. The database automatically generates new file names and puts data files in the right location.
  • target_pdb_copy_option=file_name_convert=('+DATA/FTEX', '+DATA/PDBFTEX') This is a very rare configuration. Only when you have data files in ASM, but don’t use OMF. If you have ASM, I strongly recommend using OMF.

You can find further explanation in the documentation.

Move

The CREATE PLUGGABLE DATABASE statement also has a MOVE clause in addition to COPY and NOCOPY. In a regular file system, the MOVE clause works as you would expect. However, in ASM, it is implemented via copy-and-delete, so you might as well use the COPY option.

AutoUpgrade doesn’t support the MOVE clause.

Pre-plugin Backups

After converting a non-CDB to PDB, you can restore a PDB using a combination of backups from before and after the plug-in operation. Backups from before the plug-in is called pre-plugin backups.

A restore using pre-plugin backups is more complicated; however, AutoUpgrade eases that by exporting the RMAN backup metadata (config file parameter export_rman_backup_for_noncdb_to_pdb).

I suggest that you:

  • Start a backup immediately after the upgrade, so you don’t have to use pre-plugin backups.
  • Practice restoring with pre-plugin backups.

What If My Database Is A RAC Database?

There are no changes to the procedure if you have an Oracle RAC database. AutoUpgrade detects this and sets CLUSTER_DATABASE=FALSE at the appropriate time. It also removes the non-CDB from the Grid Infrastructure configuration.

What If I Use Oracle Restart?

No changes. AutoUpgrade detects this and automatically removes the non-CDB from the Grid Infrastructure configuration.

What If My Database Is Encrypted

AutoUpgrade fully supports upgrading an encrypted database.

You’ll need to input the non-CDB database keystore password into the AutoUpgrade keystore. You can find the details in a previous blog post.

In the container database, AutoUpgrade always adds the database encryption keys to the unified keystore. After the conversion, you can switch to an isolated keystore.

Other Config File Parameters

The config file shown above is a basic one. Let me address some of the additional parameters you can use.

  • timezone_upg: AutoUpgrade upgrades the database time zone file after the actual upgrade. This requires an additional restart of the database and might take significant time if you have lots of TIMESTAMP WITH TIME ZONE data. If so, you can postpone the time zone file upgrade or perform it in a more time-efficient manner.

  • raise_compatible: If you want to raise the initialization parameter COMPATIBLE immediately after the upgrade, you can use this parameter. Don’t use it if you have standby databases, because there’s a specific procedure for raising COMPATIBLE in a Data Guard configuration. Don’t use it if you want to keep the option of downgrading.

  • before_action / after_action: Extend AutoUpgrade with your own functionality by using scripts before or after the job.

AutoUpgrade New Features: Control Start Time When Using Refreshable Clone PDBs

When you migrate or upgrade with refreshable clone PDBs, you sometimes want to decide when the final refresh happens. Perhaps you must finish certain activities in the source database before moving on.

I’ve discussed this in a previous post, but now there’s a better way.

The Final Refresh Dilemma

In AutoUpgrade, the final refresh happens at the time specified by the config file parameter start_time. This is the cut-over time where no further changes to the source database, gets replicated in the target database.

Overview of the phases when using refreshable clone PDBs

You specify start_time in the config file, and then you start the job. Typically, you start it a long time before start_time to allow the creation of the new PDB.

So, you must specify start_time in the config file and that’s when you believe the final refresh should happen. But things might change in your maintenance window. Perhaps it takes a little longer to shut down your application or there’s a very important batch job that must finish. Or perhaps you can start even earlier.

In that case, a fixed start time is not very flexible.

The Solution

You can use the proceed command in the AutoUpgrade console to adjust the start time, i.e., the final refresh.

  1. Get the latest version of AutoUpgrade:

    wget https://download.oracle.com/otn-pub/otn_software/autoupgrade.jar
    
  2. Start the job in deploy mode as you normally would:

    java -jar autoupgrade.jar ... -mode deploy
    
    • AutoUpgrade now starts the CLONEPDB stage and begins to copy the database.
  3. Wait until the job reaches the REFRESHPDB stage:

    +----+-------+----------+---------+-------+----------+-------+--------------------+
    |Job#|DB_NAME|     STAGE|OPERATION| STATUS|START_TIME|UPDATED|             MESSAGE|
    +----+-------+----------+---------+-------+----------+-------+--------------------+
    | 100|  CDB19|REFRESHPDB|EXECUTING|RUNNING|  14:10:29| 4s ago|Starts in 54 minutes|
    +----+-------+----------+---------+-------+----------+-------+--------------------+
    Total jobs 1
    
    • In this stage, AutoUpgrade is waiting for start_time to continue the migration. It refreshes the PDB with redo from the source at the specified refresh interval.
    • I must start well before the maintenance window, so AutoUpgrade has enough time to copy the database.
  4. You can now change the start time. If you want to perform the final refresh and continue immediately, use the proceed command:

    proceed -job 100
    

    Or, you can change the start time:

    proceed -job 100 -newStartTime 29/03/2025 02:00:00
    

    Or, you can change the start time to a relative value, example 1 hour 30 min from now:

    proceed -job 100 -newStartTime +1h30m
    
  5. After the final refresh, AutoUpgrade disconnects the refreshable clone PDB, turns it into a regular PDB, and moves on with the job.

Wrapping Up

AutoUpgrade offers complete control over the process. You define a start time upfront, but as things change, you can adjust it in flight.

Refreshable clone PDBs are a fantastic method for non-CDB to PDB migrations and for upgrades of individual PDBs.

There are a few quirks to be aware of, and if you are using Data Guard bear in mind that you can only plug in with deferred recovery. Other than that – it’s just to say…

Happy migrating, happy upgrading!

Further Reading

A Few Details about Using Refreshable Clone PDB for Non-CDB to PDB Migration

Our team has been advocating the use of refreshable clone PDB for non-CDB to PDB migrations using AutoUpgrade. It is a great feature and our entire team loves it – so does many of the customers we work with.

However, in a recent non-CDB to PDB migration, we encountered some issues with refreshable clone PDB and AutoUpgrade.

Can My Target Container Database Be a RAC Database?

Yes, this works perfectly fine.

Be aware that CREATE PLUGGABLE DATABASE statement scales out on all nodes in your cluster. By default, the database also uses parallel processes, so potentially, this will put quite a load on the source non-CDB. Consider restricting the use of parallel processes using the AutoUpgrade config file parameter:

upg1.parallel_pdb_creation_clause=4

Since the creation scales out on all nodes, all nodes must be able to resolve the connect identifier to the source non-CDB. If you use an alias from tnsnames.ora, be sure to add that on all nodes. Failure to do so will lead to an error during the CREATE PLUGGABLE DATABASE command:

ERROR at line 1:
ORA-65169: error encountered while attempting to copy file
+DATAC1/SRCDB/DATAFILE/system.262.1178083869
ORA-17627: ORA-12154: TNS:could not resolve the connect identifier specified
ORA-17629: Cannot connect to the remote database server

What Happens If the Source Database Extends a Data File?

If the source database extends a data file – either through AUTOEXTEND ON NEXT or manually by a user – the target database extends the matching data file as well. Here is an extract from the target alert log when it extends a data file:

2024-08-27T07:01:26.671975+00:00
PDB1(4):Media Recovery Log +RECOC1/SRCDB/partial_archivelog/2024_08_27/thread_2_seq_4.276.1178089277
2024-08-27T07:01:32.773191+00:00
PDB1(4):Resize operation completed for file# 26, fname +DATA/TGTCDB_HBZ_FRA/20A568D1FD5DB0A6E0633D01000AC89B/DATAFILE/srctbs02.290.1178089287, old size 10240K, new size 1058816K

It works with smallfile and bigfile tablespaces.

What Happens If I Create a Tablespace on the Source Database?

The target database attempts to create the same tablespace.

For this to work, one of the following must be true:

If either one of the above isn’t true, you’ll receive an error during ALTER PLUGGABLE DATABASE ... REFRESH:

ORA-00283: recovery session canceled due to errors
ORA-01274: cannot add data file that was originally created as
'+DATAC1/SRCDB/DATAFILE/srctbs04.282.1178091655'
You can use PDB_FILE_NAME_CONVERT instead.

It works with smallfile and bigfile tablespaces.

What Happens If I Add a Data File to an Existing Tablespace?

The target database attempts to add a matching data file.

The target database must be able to translate the data file location according to the section above.

2024-08-27T06:51:19.294612+00:00
PDB1(4):Media Recovery Log +RECOC1/SRCDB/partial_archivelog/2024_08_27/thread_2_seq_4.276.1178088679
2024-08-27T06:51:20.268208+00:00
PDB1(4):Successfully added datafile 25 to media recovery
PDB1(4):Datafile #25: '+DATA/TGTCDB_HBZ_FRA/20A568D1FD5DB0A6E0633D01000AC89B/DATAFILE/srctbs01.289.1178088681'

What Happens If I Set a Tablespace Read-Only?

The refreshable clone PDB does not support this. Neither is going the other way: setting a tablespace read-write.

If you do so, the database reports an error:

alter pluggable database pdb2 refresh
*
ERROR at line 1:
ORA-00283: recovery session canceled due to errors
ORA-65339: unsupported operation on the source PDB

From the alert log:

2024-08-28T05:23:02.893946+00:00
PDB2(6):Error! unsupported source PDB operation: 21
2024-08-28T05:23:02.994035+00:00
PDB2(6):Media Recovery failed with error 65339

Operation 21 is setting a tablespace read-only. If you set a tablespace read-write, the database reports operation 20 instead.

PDB2(7):Error! unsupported source PDB operation: 20

You will not be able to refresh the PDB anymore. You must re-create the refreshable clone PDB.

What Happens If I Restart the Source Database?

Refreshable clone PDB does not support restarting the source database.

When you restart the source database, the source database places a special marker in the redo stream. This even happens for a clean shutdown (SHUTDOWN NORMAL). The target CDB does not understand how to recover beyond this marker.

alter pluggable database pdb2 refresh
*
ERROR at line 1:
ORA-00283: recovery session canceled due to errors
ORA-65339: unsupported operation on the source PDB

From the alert log:

2024-08-28T05:27:00.451985+00:00
PDB2(4):Error! unsupported source PDB operation: 3
2024-08-28T05:27:00.710236+00:00
PDB2(4):Media Recovery failed with error 65339

Operation 3 is the source database restart.

You will not be able to refresh the PDB anymore. You must re-create the refreshable clone PDB.

How Do I Drain My Source Database Before Migration?

Right before the migration, when you cut the connection from the source non-CDB to the target PDB, it could be useful to restart the database. But that’s not possible.

I suggest that you:

  • Ensure that the target CDB connects to the source non-CDB using a dedicated service. This applies to the database link that you establish between the two databases.
  • Stop all other services and specify a drain timeout.
  • Shut down the application that connects to the source non-CDB.
  • Kill sessions manually.

Remember that the target database connects to the source database via a database link, so stopping the database listener is not an option. Nor is enabling RESTRICTED SESSION.

Update: Armando managed to perform the migration using restricted session. Check his comment (see below) for details.

What Happens If I Restart the Target Container Database?

You can safely restart the target CDB while you have a refreshable clone PDB. This works fine.

What About NOLOGGING Operations?

You can’t perform NOLOGGING operations on the source database.

Since refreshable clone PDB relies on redo, then a NOLOGGING operation on the source will prevent that data from going to the target. When you try to query the NOLOGGING table on the target database after the migration, you will receive an error:

SQL> select count(*) from t1
       *
ERROR at line 1:
ORA-28304: Oracle encrypted block is corrupt (file # 186, block # 131)
ORA-01110: data file 186:
'+DATA/TGTCDB_HBZ_FRA/20CF181D4A925E06E0633D01000ACB50/DATAFILE/srctbs01.297.117
8266961'
ORA-26040: Data block was loaded using the NOLOGGING option

Thanks to Marcelo for leaving a comment. He suggests that you set the source non-CDB in FORCE LOGGING mode. This is a good idea to avoid this potential nightmare:

alter database force logging;

You can read more about NOLOGGING operations in The Gains and Pains of Nologging Operations (Doc ID 290161.1).

What About Hot Backups?

You can’t perform hot backup operations on the source database.

If you do so, you’ll run into the following error:

2025-11-21T14:31:06.845676+00:00
SALES(4):Error! unsupported source PDB operation: 1
2025-11-21T14:31:07.845923+00:00
SALES(4):Media Recovery failed with error 65339

Please note that I’m not referring to RMAN online backups. I’m talking about the old-school ALTER DATABASE BEGIN BACKUP and ALTER DATABASE END BACKUP commands.

Any restrictions on data types or object types?

No. The refreshable clone is a physical copy of the database, so there are no restrictions on data types or object types.

Services

You must recreate your services after the migration. Neither database managed services nor Clusterware managed services survive the migration.

Further Readin

Summary

Despite these minor restrictions, migration from non-CDB to PDB using refreshable clone PDB and AutoUpgrade is still a very handy method. Knowing the restrictions upfront ensures that you can successfully migrate the database.

Happy migrating!