Cloning PDBs with TDE enabled just got a lot easier with ORDS

Based on user feedback the ORDS (Oracle REST Data Sources) team overhauled a large chunk of the Pluggable Database Lifecycle Management REST API. The process of creating Pluggable Databases (PDBs) from the seed PDB, as well as hot-cloning PDBs (including those encrypted using Transparent Data Encryption, TDE) in particular saw a redesign.

The previously used endpoint is still available, however you now have a new one at your disposal. Only the latter can be used to perform hot clones of PDBs with TDE enabled.

Please show me how it works!

Let’s walk through an example. I am assuming that your setup adheres to the prerequisites listed in the API overview page:

  • ORDS 24.1.1 or later installed and configured at Container Database (CDB) level
  • Since I’m going to clone a PDB with TDE enabled ORDS and RDBMS must be co-located on the same host
  • db.cdb.adminUser credentials are set in the pool configuration
  • Any client requires the SQL Administrator role to invoke this service

I installed ORDS against an Oracle Database Free 23ai database in the same virtual machine to comply with the 2nd pre-requisite.

Quick test

I typically perform a quick test first after installing ORDS and configuring PDB Lifecycle Management. The easiest one I can think of is listing all PDBs from the CDB:

$ curl --silent --user devops:"${API_PASSWORD}" \
  https://my-ords-server:8443/ords/_/db-api/stable/database/pdbs/ | \
  jq -r .items[].name
PDB$SEED
FREEPDB1

In the above example the devops user has been granted the SQL Administrator role. The password is provided as an environment variable in bash. I typically use jq on Linux to parse JSON results, but that’s just my preference, there are other tools that do the same job.

If you see at least those 2 PDBs in the output, you’re good to go!

Scheduler-based PDB cloning

The big change in ORDS 24.1 relates to the way the PDB cloning operation is performed. As soon as you invoke the REST endpoint a scheduler job is created and the prompt returns. You can check the job status (also via REST of course) to learn more about the progress and status.

Let’s clone FREEPDB1. Before doing that let’s check the TDE status of the CDB:

SQLcl: Release 23.4 Production on Mon May 13 12:18:02 2024

Copyright (c) 1982, 2024, Oracle.  All rights reserved.

Connected to:
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.4.0.24.05

SQL> select
  2    wrl_parameter,
  3    status,
  4    wallet_type,
  5    keystore_mode,
  6    con_id
  7  from
  8*   v$encryption_wallet;

WRL_PARAMETER                              STATUS    WALLET_TYPE    KEYSTORE_MODE       CON_ID 
__________________________________________ _________ ______________ ________________ _________ 
/opt/oracle/admin/FREE/wallet_root/tde/    OPEN      AUTOLOGIN      NONE                     1 
                                           OPEN      AUTOLOGIN      UNITED                   2 
                                           OPEN      AUTOLOGIN      UNITED                   3

As you can see, TDE is configured for all PDBs with an auto-login wallet using united mode. Time to clone the PDB! The payload is documented in the API documentation. I set db_create_file_dest in my CDB so I don’t need to worry about any file name conversions

curl --silent \
--user "devops:${API_PASSWORD}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data '{
    "new_pdb_name": "clone1",
    "source_pdb_name": "freepdb1",
    "keystore_password": "'"${KEYSTORE_PWD}"'",
    "temp_file_reuse": true
}' \
http://my-ords-server:8443/ords/_/db-api/stable/database/pdbs/ | jq .

Note: be careful with shell interpolation, it’s easy to get it wrong.

As soon as the REST endpoint is invoked, ORDS provides a summary in JSON format. Thanks to jq it is pretty-printed and formatted for readability. The key field is the job name:

{
  "owner": "SYS",
  "job_name": "DBAPI_V8J2C54SO9WUZRDZ20240513102945",
  "job_subname": null,
  "instance_id": null,
  "destination_owner": null,
...

Using this job name you can query the job status. Again, there is a lot of detail available, however all I care about is the status:

curl --silent --user "devops:${API_PASSWORD}" \
  https://my-ords-server:8443/ords/_/db-api/stable/database/scheduler/jobs/SYS,DBAPI_V8J2C54SO9WUZRDZ20240513102945 | \
  jq -r .status
SUCCEEDED

The ords server process emits a line with the jobLink each time the API invoked. I grabbed the URL from there and simply pasted it into the console.

The alert.log contains the details of the command issued, and the output, as you would expect:

2024-05-13 10:42:12.601000 +00:00
CREATE PLUGGABLE DATABASE clone1
 FROM freepdb1 
 TEMPFILE REUSE
 KEYSTORE IDENTIFIED BY * 
 AUDSYS.AUD$UNIFIED (SQL_TEXT) - CLOB populated
KZTDE: TDE keystore backup was taken : /opt/oracle/admin/FREE/wallet_root/tde/ewallet_2024051310421282.p12
2024-05-13 10:42:14.036000 +00:00
****************************************************************
Pluggable Database CLONE1 with pdb id - 5 is created as UNUSABLE.
If any errors are encountered before the pdb is marked as NEW,
then the pdb must be dropped
local undo-1, localundoscn-0x0000000000000130
****************************************************************

...

****************************************************************
Post plug operations are now complete.
Pluggable database CLONE1 with pdb id - 5 is now marked as NEW.
****************************************************************
2024-05-13 10:42:16.795000 +00:00
Opening pdb with Resource Manager plan: DEFAULT_PLAN
Completed: Pluggable database CLONE1 opened read write 
Completed: ALTER PLUGGABLE DATABASE clone1 OPEN READ WRITE

Summary

ORDS 24.1.1 introduces a hot-clone process for PDBs. Why is this a big deal for me? I am a great fan of modern software development principles. A DevOps culture is essential to releasing changes more frequently, with higher confidence.

Continuous Integration (CI) pipelines allow developers to run a multitude of automated tests, and they typically need a test environment for their backend code. Cloning a CI database using REST APIs is a great way to integrate database testing into the pipeline. As a result, the probability of issues with the release should be further reduced.