Let’s Talk at Oracle AI World

At Oracle AI World next month, we have some pretty cool things to show you. But in between all our sessions and labs, we still have time to meet you.

We want you to get the most out of Oracle AI World and we are there to answer all your questions. We can help you with:

  • Upgrades
  • Patching
  • Migrations
  • AutoUpgrade
  • Data Pump
  • Cloud Premigration Advisor Tool

The Small Things

For quick questions, informal conversations, or even a selfie, come visit us at the Oracle AI World Hub.

Our team will have a dedicated booth next to the other database booths, and someone will be there throughout the event. Stop by and say hello – we’d be happy to talk.

The Bigger Things

For more complex questions or topics that require a deeper discussion, let’s arrange a private meeting.

We can talk about:

  • Upgrades, migrations and patching in general
  • Your specific challenges
  • An upcoming project where you would value our input
  • The future of Oracle AI Database and related tools

We’d also love to hear your feedback::

  • What has your experience been with our tools?
  • What could we improve?
  • How can we make the tools more useful for you?

We can’t help you with:

  • Service requests
  • License issues
  • Sales and commercial discussions

How Can I Schedule a Meeting?

First, take a few minutes to prioritize the topics you’d like to discuss. Meeting availability will be limited, so let’s focus on what matters most to you.

Then send me an email at daniel.overby.hansen@oracle.com. Please introduce yourself and your company, and let me know what you’d like to discuss.

I can’t guarantee that we’ll have time to meet everyone, but I guarantee that I’ll do my best to find a spot in our calendar.

See you in Las Vegas!

8 Hours of Intense Learning at AI World

In little more than a month, Oracle AI World 2026 starts in Las Vegas.

Sunday is the first day of the conference – and it’s all about learning.

Together with Oracle University, we’re hosting a full-day training session on upgrades, patching, and migration.

Together with Oracle University we’re hosting a full-day training session on upgrades, patching and migration.

Join Mike Dietrich, Daniel Overby Hansen, Rodrigo Jorge, and Alex Zaballa for a workshop featuring real-world customer cases and practical examples of upgrade, migration, and consolidation techniques and strategies. Explore the power and possibilities of Oracle AI Database 26ai. Learn how to prepare for Oracle AI Database 26ai and leverage the latest enhancements in AutoUpgrade. Discover how to take patching to the next level, ease operations in the multitenant architecture, get Data Pump on steroids, simplify migration to Oracle ADB for beginners and experts, and explore the coolest and best new features for DBAs in Oracle AI Database 26ai.

Sign up here

Oracle University Training at Oracle AI World

What’s In It For You?

You will get:

  • An intense learning with enough time to dive into the details.
  • The latest updates on how AI affects security in tech and what that means for patching.
  • Our best practices for operating your databases in a multitenant architecture.
  • A unique opportunity to learn from our entire Product Management team, including Mr. Upgrade himself, Mike Dietrich.
  • All tech, no marketing!

Details

The event takes place on Sunday October 25 from 09:00 to 17:00. Be sure to bring:

  • Your laptop – we have exercises planned for the hands-on lab.
  • Loads of questions.
  • An open mind and a willingness to learn.

Seats are limited, so don’t wait too long to sign up.

See you in Las Vegas!

How to Export/Import A Single Queue Using Data Pump

In a recent project, a customer used Advanced Queueing (AQ), and I had to move a single queue from one database to another.

In Oracle AI Database, you can use Data Pump to move queues. According to the documentation, exporting and importing a queue is straightforward, but there are some caveats to be aware of.

How to Export a Queue

I want to export the ORDER_Q queue in the APPUSER schema.

  1. Under the hood, a queue consists of a queue table. Often, the queue uses an object type for its payload. I start by finding the queue table name and payload type:

    select q.queue_table, qt.object_type
    from   dba_queues q, dba_queue_tables qt 
    where  q.owner='APPUSER' and q.name='ORDER_Q'
    and    q.owner=qt.owner and q.queue_table =qt.queue_table;
    
       QUEUE_TABLE        OBJECT_TYPE
    ______________ __________________
    ORDER_QT       APPUSER.ORDER_T
    
  2. I prepare a Data Pump parfile named queue_table_export.par. It exports the queue table:

    directory=dpdir
    dumpfile=order_qt.dmp
    logfile=order_q_export.log
    tables=APPUSER.ORDER_QT
    exclude=statistics
    
    • The tables parameter is the queue table for the queue I want to export. I find it using the query above.
  3. Then, I export the queue table:

    expdp ... parfile=queue_table_export.par
    
  4. Next, I create a new parfile named payload_type_export.par. It exports the object_type or payload_type:

    directory=dpdir
    dumpfile=queue_types.dmp
    logfile=queue_types_export.log
    schemas=appuser
    include=type:"IN ('ORDER_T')"
    
    • To export types, I must perform a schema export.
    • I use the include parameter to include only types and further limit the export to the ORDER_T type.
  5. Then, I export the type:

    expdp ... parfile=payload_type_export.par
    

How to Import

  1. I start by importing the type:

    impdp ... dumpfile=queue_types.dmp
    
  2. Then, I import the queue table:

    impdp ... dumpfile=order_qt.dmp
    
    • Data Pump imports the queue table and all messages.
    • It also calls the AQ API to create the queue infrastructure.
  3. I connect to the database and start the queue:

    BEGIN
    DBMS_AQADM.START_QUEUE(
    	queue_name => 'APPUSER.ORDER_Q'
    );
    END;
    /
    
    • Note that I start the queue by its name ORDER_Q. It was created automatically during the import of the queue table.
  4. That’s it. I’ve moved the queue and can start using it.

What Happens During Import

Let’s see how Data Pump uses the AQ API when it imports the queue table.

  1. I start Data Pump to extract the DDL from the dump file:
    impdp ... dumpfile=order_qt.dmp sqlfile=order_qt.sql
    
    • Data Pump reads the dump file and extracts the statements needed to perform this import.
    • It doesn’t perform the import.
    • The statements are written to the text file specified by sqlfile.
  2. I examine the text file. This is what Data Pump would do during an import.
    • Data Pump starts by creating the queue table:
      CREATE TABLE "APPUSER"."ORDER_QT"
         (    "Q_NAME" VARCHAR2(128 BYTE),
              "MSGID" RAW(16),
              "CORRID" VARCHAR2(128 BYTE),
              "PRIORITY" NUMBER,
              ...
      
    • Next come a few indexes:
      CREATE INDEX "APPUSER"."AQ$_ORDER_QT_I"
         ON "APPUSER"."ORDER_QT" ("Q_NAME", "STATE", "ENQ_TIME", "STEP_NO", "CHAIN_NO", "LOCAL_ORDER_NO")
         ...
      
    • Finally, the call to the AQ API to create the queue:
      BEGIN
      SYS.DBMS_AQ_IMP_INTERNAL.IMPORT_QUEUE_TABLE('ORDER_QT',1,16801800,2,0,0,'', SYS.DBMS_AQ_IMP_INTERNAL.DBVER_10i, '00:00');
      COMMIT;
      END;
      /
      
      BEGIN
      SYS.DBMS_AQ_IMP_INTERNAL.IMPORT_QUEUE(HEXTORAW('598D4E9609226B60E0635301000A0A08'),'ORDER_QT','AQ$_ORDER_QT_E',1,0,0,0,0,'exception queue');
      COMMIT;
      END;
      /
      
      BEGIN
      SYS.DBMS_AQ_IMP_INTERNAL.IMPORT_QUEUE(HEXTORAW('598D4E9609236B60E0635301000A0A08'),'ORDER_QT','ORDER_Q',0,5,0,0,0,'');
      COMMIT;
      END;
      /		
      
    • You can’t see the rows being loaded into the queue, but that happens too. All messages in the queue are also exported.
  • The DBMS_AQ_IMP_INTERNAL is an internal API. Don’t call it yourself.

What About a Full or Schema Export

If you perform a full or schema mode export, it’s simple. Data Pump exports all the required objects, including the types.

The only thing you must do is to start the queues after the import.

What If

The payload type must exist when you import the queue table. If you try to import the queue table without the type, Data Pump throws an error:

Processing object type TABLE_EXPORT/TABLE/TABLE
ORA-39117: Type needed to create table is not included in this operation. Failing sql is:
CREATE TABLE "APPUSER"."ORDER_QT" ("Q_NAME" VARCHAR2(128 BYTE), "MSGID" RAW(16), "CORRID" VARCHAR2(128 BYTE), "PRIORITY" NUMBER, "STATE" NUMBER, "DELAY" TIMESTAMP (6), "EXPIRATION" NUMBER, "TIME_MANAGER_INFO" TIMESTAMP (6), "LOCAL_ORDER_NO" NUMBER, "CHAIN_NO" NUMBER, "CSCN" NUMBER, "DSCN" NUMBER, "ENQ_TIME" TIMESTAMP (6), "ENQ_UID" VARCHAR2(128 BYTE), "ENQ_TID" VARCHAR2(30 BYTE), "DEQ_TIME" TIMESTAMP (6), "DEQ_UID" VARCHAR2(128 BYTE), "DEQ_TID" VARCHAR2(30 BYTE), "RETRY_COUNT" NUMBER, "EXCEPTION_QSCHEMA" VARCHAR2(128 BYTE), "EXCEPTION_QUEUE" VARCHAR2(128 BYTE), "STEP_NO" NUMBER, "RECIPIENT_KEY" NUMBER, "DEQUEUE_MSGID" RAW(16), "SENDER_NAME" VARCHAR2(128 BYTE), "SENDER_ADDRESS" VARCHAR2(1024 BYTE), "SENDER_PROTOCOL" NUMBER, "USER_DATA" "APPUSER"."ORDER_T" , "USER_PROP" "SYS"."ANYDATA" ) USAGE QUEUE SEGMENT CREATION IMMEDIATE PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255  NOCOMPRESS LOGGING STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) TABLESPACE "USERS"  OPAQUE TYPE ("USER_PROP") STORE AS SECUREFILE LOB (ENABLE STORAGE IN ROW CHUNK 8192 CACHE  NOCOMPRESS  KEEP_DUPLICATES  STORAGE(INITIAL 106496 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT))

That’s It

You can use Data Pump to move queues around. For table-mode exports, remember to export the payload type separately.

A few interesting links:

Happy queueing!

AutoUpgrade New Features: Create and Use Your Own Gold Images

There are several advantages to using gold images to install new Oracle homes:

  • You know all servers get the exact same Oracle home.
  • You can install faster because you don’t need to apply all the patches.
  • They fit very well with automation.
  • They’re easier to test and work well with configuration management.

When you install an Oracle home using AutoUpgrade, you can also create your own gold images. Later, you can deploy the gold image to new servers.

Create Gold Image

I will use AutoUpgrade to install a new Oracle home with the desired patches and create a gold image.

  1. I’ve already downloaded the patches.
  2. Here’s my config file:
    global.global_log_dir=/home/oracle/autoupgrade/log
    install1.download_folder=/home/oracle/patch-repo
    install1.source_home=/u01/app/oracle/product/19
    install1.target_home=/u01/app/oracle/product/19_32
    install1.create_gold_image=db_home_%RELEASE%_%UPDATE%_%TIMESTAMP%.zip
    install1.patch=recommended
    
    • I’ve already downloaded the patches to download_folder.
    • I want to create a new Oracle home in the target_home location.
    • AutoUpgrade copies the settings from the source_home.
    • After installing the new Oracle home, AutoUpgrade creates a gold image in download_folder. Instead of specifying the name of the gold image, I can also set create_gold_image=yes and let AutoUpgrade generate a name.
    • I set patch=recommended to get the recommended patches: latest Release Update, OPatch, MRP, OJVM, and Data Pump bundle patches.
  3. I start AutoUpgrade to install the new Oracle home:
    java -jar autoupgrade.jar -config install-home.cfg -patch -mode create_home
    
    • In 19c, the installation takes longer because AutoUpgrade must apply the Release Update.
    • In 26ai, this process is much faster because Oracle delivers gold images with the latest Release Update already applied.
  4. When AutoUpgrade completes, I can find the gold image in my download_folder.
  5. It took 15 minutes to install the Oracle home and apply all the patches, plus five minutes to generate the gold image.

Install From Gold Image

Now I move to a different server. I need a new Oracle home and I’ll use the gold image.

  1. Here’s my AutoUpgrade config file:
    global.global_log_dir=/home/oracle/autoupgrade/log
    install1.download_folder=/home/oracle/patch-repo
    install1.source_home=/u01/app/oracle/product/19
    install1.target_home=/u01/app/oracle/product/19_32
    install1.patch=GOLDIMAGE:db_home_19_32_20260819113026.zip
    
    • Notice the patch parameter. I specify the gold image instead of individual patches.
  2. I start AutoUpgrade to install the new Oracle home:
    java -jar autoupgrade.jar -config install-home.cfg -patch -mode create_home
    
    • AutoUpgrade extracts the gold image and performs the installation.
    • There are no patches to apply. The gold image is already up to date.
  3. That’s it! I now have an Oracle home with exactly the same patches.
  4. It took just two minutes to install the gold image. That’s much faster than the 15 minutes it took for a regular installation.

That’s It

If you’re not already using gold images, you should get started. AutoUpgrade makes them easy to create and deploy.

Happy patching!

AutoUpgrade New Features: Download 26ai Release Update Rather Than Gold Image

Starting with Oracle AI Database 26ai, Oracle delivers fully updated gold images in addition to just the Release Update.

This is very convenient because:

  • It significantly shortens the installation time of a new Oracle home because the Release Update has already been applied.
  • It includes an updated OPatch.
  • It includes an updated OCW component.
  • It includes an updated JDK and Perl installation.

AutoUpgrade downloads the gold image automatically and you get to enjoy the much shorter installation time.

But sometimes you want just the Release Update.

Download Release Update Patch File

  • Here’s my AutoUpgrade config file:

    global.global_log_dir=/home/oracle/autoupgrade/logs
    global.keystore=/home/oracle/autoupgrade/keystore
    global.folder=/home/oracle/autoupgrade/patches
    
    patch1.platform=LINUX.X64
    patch1.target_version=26
    patch1.patch=RU
    patch1.gold_image=no
    
    • I set gold_image=no to tell AutoUpgrade to download the Release Update patch instead of the gold image.
  • I start AutoUpgrade in download mode:

    java -jar autoupgrade.jar -patch -config download.cfg -mode download
    
  • AutoUpgrade locates the latest Release Update and starts the download.

    AutoUpgrade Patching 26.4.260701 launched with default internal options
    Processing config file ...
    Loading AutoUpgrade Patching keystore
    AutoUpgrade Patching keystore is loaded
    
    ------------------------------------------------------
    Downloading files to /home/oracle/autoupgrade/patches
    ------------------------------------------------------
    DATABASE RELEASE UPDATE 23.26.3.0.0
        File: p39578879_230000_Linux-x86-64.zip - VALIDATED
    ------------------------------------------------------
    
  • You can distinguish between the Release Update patch and the gold image by their descriptions:

    • Gold image: DATABASE RELEASE UPDATE 23.26.3.0.0(GOLD IMAGE)
    • Patch file: DATABASE RELEASE UPDATE 23.26.3.0.0

That’s It

Gold images are the fastest way to provision a new Oracle home. But when you need the Release Update patch instead, AutoUpgrade lets you choose.

Happy patching!

How to Use Data Pump with Exadata Exascale Storage

Do you know that feeling when you get new toys?

A short while ago, in a server room far, far away …

… a brand-new, shiny Oracle Exadata Exascale was left unguarded, so I decided to try out a few things.

Here’s how to export to and import from Exadata Exascale storage.

Prerequisites

  1. I create a directory for the Data Pump dump files pointing to the Exascale vault:
    create directory dumpdir as '@MYVAULT1/CDB26/SALES/DUMPDIR';
    
    • MYVAULT1 is the name of my vault. Notice the @ sign, which denotes Exascale vaults, like + in ASM.
    • I can specify subdirectories (CDB26/SALES/DUMPDIR) to organize my files. However, there’s no concept of directories in Exascale, so these are really path prefixes.
    • Unlike a regular file system or ASM, I don’t have to create the matching file system directory.
  2. I create another directory for my Data Pump log files:
    create directory logdir as '/u02/app/oracle/admin/CDB26/SALES/logdir';
    
    • I can’t use the Exascale directory for log files.
    • Similar to ASM, I can’t store log files in Exascale.
  3. I create the matching file system directory for logdir:
    mkdir -p /u02/app/oracle/admin/CDB26/SALES/logdir
    
    • In Oracle RAC, I should place the directory in a cluster file system or ensure that the folder exists on all nodes.
  4. Finally, I create a user to perform the Data Pump jobs:
    create user dpuser identified by <password>;
    alter user dpuser default tablespace users;
    alter user dpuser quota unlimited on users;
    grant datapump_exp_full_database to dpuser; 
    grant datapump_imp_full_database to dpuser; 
    

Export

  • Here’s how to start an export:

    expdp dpuser/<password>@<connect-string> \
    	dumpfile=dumpdir:myexp%L.dmp \
    	logfile=logdir:myexp-export.log \
    	...
    
    • I write the dump file to my Exascale vault by specifying the database directory (dumpdir) and then the dump file name specification. I’m using the %L wildcard to allow Data Pump to create additional files.
    • Data Pump must write the log file to a real file system, so I use logdir which points to a local file system.
  • At the end of the export, Data Pump writes the names of my dump files:

    04-AUG-26 11:08:36.114: Dump file set for DPUSER.SYS_EXPORT_SCHEMA_01 is:
    04-AUG-26 11:08:36.114:   @MYVAULT1/CDB26/SALES/DUMPDIR/myexp01.dmp
    04-AUG-26 11:08:36.145: Job "DPUSER"."SYS_EXPORT_SCHEMA_01" successfully completed at Tue Aug 4 11:08:36 2026 elapsed 0 00:01:03
    

Import

  • Here’s how to start an import:
    impdp dpuser/<password>@<connect-string> \
    	dumpfile=dumpdir:myexp%L.dmp \
    	logfile=logdir:myexp-import.log \
    	...
    
    • I configure the dumpfile and logfile parameters the same way as in the export.
    • I can use the %L wildcard in the dump file specification for imports as well. Data Pump automatically finds the required dump files.

Pro Tips

Happy Data Pumping!

AutoUpgrade New Features: The Patch Overview

I trust you’ve already used AutoUpgrade to download patches. If not, you’re missing out big time.

Here’s a nifty new feature that makes AutoUpgrade fit better into your automation and gives you an overview of what you’ve downloaded already.

The Download JSON File

  • AutoUpgrade constructs and maintains a JSON file named patches_info.json.
  • AutoUpgrade stores the file in the download folder (config file entry folder).
  • It contains information about all the patches AutoUpgrade has downloaded.
  • The file is cumulative, so it contains information about not just the latest download but also previous ones.

Example

Here’s a sample output:

{
    "patchFolder": "/home/oracle/patches",
    "patches": [
        {
            "description": "DATABASE RELEASE UPDATE 23.26.3.0.0(GOLD IMAGE)",
            "platform": "Linux x86-64",
            "releaseUpdate": "23.26.3.0.0",
            "files": [
                {
                    "name": "p39581612_230000_Linux-x86-64.zip",
                    "checksum": "DDBEBAC94B5F0B7D3FF4910AB01DB8FCDD3390A7",
                    "checksum-256": "2CAFECB11DBDD7F81C55DEE9FC846AA7E8F8C265721C1B8AB4B23EF13F94643D"
                }
            ]
        },
        {
            "description": "OPatch 12.2.0.1.52 for DB 23.0.0.0.0 (Jul 2026)",
            "platform": "Linux x86-64",
            "files": [
                {
                    "name": "p6880880_230000_Linux-x86-64.zip",
                    "checksum": "21EF498D3ECA4E734467A02FD0A799C464008726",
                    "checksum-256": "8C0D19B7774CD2E0443D2FC2BD29D3A784383199BEA3867CD4D39E2D32BFA6CC"
                }
            ]
        }
    ]
}

Checksum

After downloading a file, AutoUpgrade automatically checks the integrity of the file by calculating and verifying the checksum.

If there is a discrepancy, AutoUpgrade deletes the file and informs you.

If you want to verify it manually, you can find the expected checksum in the JSON file.

Human Readable

JSON is good for machines, but bad for humans, so here’s a party trick to beautify the output:

jq -r '
["TYPE","DESCRIPTION","PLATFORM","FILE","SHA1","SHA256"],
(.patches[] |
 [
   (if .description|test("RELEASE UPDATE") then "RU"
    elif .description|test("OPatch") then "OPATCH"
    elif .description|test("OJVM") then "OJVM"
    elif .description|test("DATAPUMP") then "DPBP"
    else "PATCH" end),
   .description,
   (.platform // "Generic"),
   .files[0].name,
   .files[0].checksum,
   .files[0]["checksum-256"]
 ]) | @tsv
' patches_info.json | column -t -s $'\t'

This command turns the JSON file into a tabular format:

TYPE    DESCRIPTION                                      PLATFORM      FILE                               SHA1                                      SHA256
RU      DATABASE RELEASE UPDATE 23.26.3.0.0(GOLD IMAGE)  Linux x86-64  p39581612_230000_Linux-x86-64.zip  DDBEBAC94B5F0B7D3FF4910AB01DB8FCDD3390A7  2CAFECB11DBDD7F81C55DEE9FC846AA7E8F8C265721C1B8AB4B23EF13F94643D
OPATCH  OPatch 12.2.0.1.52 for DB 23.0.0.0.0 (Jul 2026)  Linux x86-64  p6880880_230000_Linux-x86-64.zip   21EF498D3ECA4E734467A02FD0A799C464008726  8C0D19B7774CD2E0443D2FC2BD29D3A784383199BEA3867CD4D39E2D32BFA6CC

Thanks to Abhilash Kumar for the tip.

Happy patching!

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.

Automating AutoUpgrade: Populating the Keystore

A customer had to move hundreds of PDBs using AutoUpgrade and refreshable clone PDBs. As a cool customer, they wanted to automate the entire process.

The PDBs are encrypted, so AutoUpgrade needs the source and target TDE keystore passwords. AutoUpgrade stores these passwords in its own keystore until they are needed.

You can manually load the passwords into the AutoUpgrade keystore using the load password console (-load_password).

But loading passwords manually doesn’t fit very well with automation.

The Solution

For security reasons, there is no native way in AutoUpgrade to load these passwords besides typing them manually.

Loading passwords via response files or command line parameters exposes the sensitive information, e.g., in your command history.

But if you accept the risk, you can load passwords using the expect command. You’ll need to place the passwords in clear-text in a file for a short period. When the loading completes, you can remove the file and the passwords are now safely stored in the AutoUpgrade keystore.

Loading Passwords Using Expect

  1. Here’s my AutoUpgrade config file called sales.cfg:

    global.autoupg_log_dir=/home/oracle/autoupgrade/logs
    global.keystore=/home/oracle/autoupgrade/keystore
    upg1.sid=CDB19
    upg1.target_cdb=CDB26
    upg1.pdbs=SALES
    upg1.source_home=/u01/app/oracle/product/19.0.0.0/dbhome_1
    upg1.target_home=/u01/app/oracle/product/23.0.0.0/dbhome_1
    upg1.target_pdb_copy_option.SALES=file_name_convert=NONE
    upg1.source_dblink.SALES=CLONE_LINK_SALES 300
    upg1.start_time=01/01/2030 08:03:00
    
    • I’ve configured the location of the AutoUpgrade keystore using the global.keystore parameter.
  2. I create an expect file called sales.exp. I set the executable flag and ensures no others can read the file:

    touch /dev/shm/sales.exp
    chmod 700 /dev/shm/sales.exp
    
    • Since the file will contain my passwords, I place it in /dev/shm which is a tmpfs or RAM-based file system. I don’t want the file on persistent storage.
  3. I add the following to my expect file.

    #!/usr/bin/expect
    
    spawn java -jar autoupgrade.jar -config sales.cfg -load_password
    expect "Enter password:"
    send -- "MyS3cr3tPassw0rd#\r"
    expect "Enter password again:\r"
    send -- "MyS3cr3tPassw0rd#\r"
    expect "TDE>\r"
    send -- "add CDB19\r"
    expect "Enter your secret/Password:\r"
    send -- "Databas3CDB19#\r"
    expect "Re-enter your secret/Password:\r"
    send -- "Databas3CDB19#\r"
    expect "TDE>\r"
    send -- "add CDB26\r"
    expect "Enter your secret/Password:\r"
    send -- "Databas3CDB26#\r"
    expect "Re-enter your secret/Password:\r"
    send -- "Databas3CDB26#\r"
    expect "TDE>\r"
    send -- "save\r"
    expect "Select auto-login mode for the AutoUpgrade keystore"
    send -- "YES\r"
    expect "TDE>\r"
    send -- "exit\r"
    expect eof	
    
    • Using the spawn command I start the AutoUpgrade load password console.
    • I can wait for AutoUpgrade to print certain information using the expect command.
    • Then I can send the appropriate response – a command or a password – using the send command.
    • Be sure to add the \r at the end of your commands or passwords. All the passwords end with a # so you can see how the control character is appended.
    • This file contains the passwords in clear-text. Make sure the file is protected with restrictive file permissions.
  4. I start the password loading using expect:

    expect /dev/shm/sales.exp
    
    • expect starts the AutoUpgrade load password console and inputs the passwords when needed.
  5. I remove the expect file:

    rm /dev/shm/sales.exp
    
  6. Now that the keystore is populated with the TDE keystore passwords, I can move on with the process.

MOS Credentials For Patch Downloading

Pardon me for sidetracking a bit.

  • You can use the same approach to populate the keystore with MOS credentials for patch downloading.
  • Here’s an example of an expect file:
    #!/usr/bin/expect
    
    spawn java -jar autoupgrade.jar -patch -config download.cfg -load_password
    expect "Enter password:"
    send -- "MyS3cr3tPassw0rd#\r"
    expect "Enter password again:\r"
    send -- "MyS3cr3tPassw0rd#\r"
    expect "MOS>\r"
    send -- "add -user ash@weyland-yutani.com\r"
    expect "Enter your secret/Password:\r"
    send -- "MyS3cr3tMOSPassw0rd#\r"
    expect "Re-enter your secret/Password:\r"
    send -- "MyS3cr3tMOSPassw0rd#\r"
    expect "MOS>\r"
    send -- "save\r"
    expect "Select auto-login mode for the AutoUpgrade keystore"
    send -- "YES\r"
    expect "MOS>\r"
    send -- "exit\r"
    expect eof
    
    • Replace MyS3cr3tPassw0rd# with the password you want for the AutoUpgrade keystore.
    • Replace ash@weyland-yutani.com with your MOS username.
    • Replace MyS3cr3tMOSPassw0rd# with your MOS password.

That’s It

With expect you can automate the loading of passwords into the AutoUpgrade keystore.

I consider it safer to load passwords manually, but to fully automate the process you must cut a corner.

I suggest using a unique keystore for each of your AutoUpgrade invocations. This makes it easier to automate. AutoUpgrade can also create a shared keystore that you can create once and then distribute to other servers.

Happy upgrading!