I recently ran a Proof of Concept with Oracle Exadata Database Service for Exascale (ExaDB-XS) deployed on OCI with Azure interconnect for a large European insurance company. The goal was to demonstrate how ExaDB-XS can provision child environments (test, dev, analytics) without duplicating storage and in seconds, not hours.
This article is the workbook I built for that PoC. It is designed so you can follow along step by step on your own ExaDB-XS environment. Each exercise includes the commands to run; you should record the output yourself to confirm the expected behavior at each stage.
The workbook is organized in four parts:
- Prerequisites: Environment and connectivity
- PDB Snapshots: Manual creation, space verification, and automatic carousel
- Thin Clones: From a live PDB and from a snapshot
- Refreshable PDB + Thin Clones: The advanced pattern for automated child environment refresh
Important: Database release must be 26ai and you must create the exascale vault with the “smart storage” type.
Language Disclaimer: There are a few segment names and columns in spanish. You can choose to keep them or replace them with an alternative less attractive language names.
Starting point
All exercises in this workbook are performed via SQL*Plus from the operating system of the ExaDB-XS compute node. PDBs created via SQL command are supported, but note that they take approximately 45 minutes to become visible in the OCI web console (a periodic synchronization process). If you need immediate console visibility, use the OCI Console, CLI, SDKs, or Terraform instead.
All exercises consist of creating and managing clones. Do not modify the source PDB directly – always work on clones. This way, there is no need to restore the source PDB between exercises.
You can fully do all the exercises working via remote SQL connection or locally from one of the ExaDB-XS nodes. In this case we will connect locally so you can familiarize with the nodes. Again, the reason of doing it via commands is for better understanding (with the added benefit that you can also practice them in an Exascale VM cluster in ExaC@C, if you have access to one). The last exercise will use the ExaDB-XS console to showcase it’s options as well.
The connection requires uploading your public key through the OCI web console beforehand. In our PoC, we uploaded the key from a jump host for convenience:
[oracle@jumphost ~]$ ssh opc@<exaxs-node-ip>[opc@exaxs1-wsjjr ~]$ sudo su - oracle
We load the environment and check the PDBs. We will start with a precreated source PDB already contaning several TB of data:
[oracle@exaxs1-wsjjr ~]$ . CDBPOC.env[oracle@exaxs1-wsjjr ~]$ sqlplus / as sysdbaSQL> show pdbsCON_ID CON_NAME OPEN MODE RESTRICTED---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 <YOUR_SOURCE_PDB> READ WRITE NO
You should see your source PDB open in READ WRITE mode. This is the PDB we will use as the source for all exercises. Again, in this case, we want the database to be of a certain size so that the thin cloning examples are meaningful.
PDB Snapshots
A PDB Snapshot in Exascale is a point-in-time reference based on an SCN. It is not a full database: it has no data dictionary of its own, no undo, and no temporary tablespace. This means you cannot open a snapshot directly. However, it serves as the foundation for creating thin clones almost instantly.
In Exascale, snapshots are always space-efficient thanks to the redirect-on-write technology of the Storage Vault. No data is copied; only the point-in-time (SCN) is recorded and sparse references are created. The additional space consumed by a newly created snapshot is negligible.
Before creating any snapshot, record the current space usage in the Exascale Storage Vault. We will compare this value after each operation to verify that no data duplication occurs.
You can check this in the OCI Console on the VM Cluster main page (under “Exascale database storage”), or via SQL:
SQL> show con_nameCON_NAME------------------------------CDB$ROOTSQL> set linesize 999SQL> column vault_name format a10SQL> column total_gb format 999999999SQL> column usado_gb format 999999999SQL> column libre_gb format 999999999SQL> SELECT VAULT_NAME, ROUND(HC_SPACE_PROV/1024/1024/1024/3, 0) AS total_gb, ROUND(HC_SPACE_USED/1024/1024/1024/3, 0) AS usado_gb, ROUND((HC_SPACE_PROV - HC_SPACE_USED)/1024/1024/1024/3, 0) AS libre_gb FROM V$EXA_VAULT ORDER BY 1; VAULT_NAME TOTAL_GB USADO_GB LIBRE_GB---------- ---------- ---------- ----------(record your values here)
Important: The free and total space shown in the console and in V$EXA_VAULT is physical (raw) space. In ExaDB-XS the redundancy is always triple mirror, so we divide by 3 to get the net usable space.
Now we will create a manual snapshot:
SQL> ALTER SESSION SET CONTAINER = <YOUR_SOURCE_PDB>;SQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED---------- ------------------------------ ---------- ----------(record your values here)
Verify the PDB is open READ WRITE, then create the snapshot:
SQL> SET TIMING ONSQL> ALTER PLUGGABLE DATABASE SNAPSHOT snapshot_1;SQL> SET TIMING OFF(record the elapsed time)
The elapsed time should be between 1 and 3 seconds, even for a multi-terabyte PDB. Now query the existing snapshots:
SQL> column SNAPSHOT_NAME format a20SQL> column SNAPSHOT_SCN format 999999999999SQL> column SNAPSHOT_TIME format 999999999999SQL> column FULL_SNAPSHOT_PATH format a50SQL> column CON_NAME format a20SQL> SELECT CON_NAME, SNAPSHOT_NAME, SNAPSHOT_SCN, SNAPSHOT_TIME, FULL_SNAPSHOT_PATH FROM DBA_PDB_SNAPSHOTS ORDER BY SNAPSHOT_SCN; (record your output here)
To drop an individual snapshot:
ALTER PLUGGABLE DATABASE DROP SNAPSHOT snapshot_1;
Now we need to verify that the snapshot consumed no additional space. The vault space should not have increased. Views like DBA_PDB_SNAPSHOTFILE show the existence of the snapshot files but do not reflect the real physical storage consumption in ExaDB-XS. We will run the previous v$EXA_VAULT query again:
SQL> show con_nameCON_NAME------------------------------CDB$ROOTSQL> set linesize 999SQL> column vault_name format a10SQL> column total_gb format 999999999SQL> column usado_gb format 999999999SQL> column libre_gb format 999999999SQL> SELECT VAULT_NAME, 2 ROUND(HC_SPACE_PROV/1024/1024/1024/3, 0) AS total_gb, 3 ROUND(HC_SPACE_USED/1024/1024/1024/3, 0) AS usado_gb, 4 ROUND((HC_SPACE_PROV - HC_SPACE_USED)/1024/1024/1024/3, 0) AS libre_gb 5 FROM V$EXA_VAULT 6 ORDER BY 1; VAULT_NAME TOTAL_GB USADO_GB LIBRE_GB---------- ---------- ---------- ----------(record your output)
Compare previous and last outputs and verify that consumed space is virtually identical.
PDB Snapshot Carousel (automatic snapshots)
Configure automatic snapshots every 24 hours from within the source PDB:
SQL> ALTER SESSION SET CONTAINER = <YOUR_SOURCE_PDB>;SQL> SHOW CON_NAMECON_NAME------------------------------<YOUR_SOURCE_PDB>
First, check the current snapshot mode:
SQL> COLUMN PDB_NAME FORMAT A20SQL> COLUMN SNAPSHOT_MODE FORMAT A15SQL> SELECT PDB_NAME, SNAPSHOT_MODE, SNAPSHOT_INTERVAL AS INTERVAL_MINUTES, SNAPSHOT_INTERVAL/60 AS INTERVAL_HOURS FROM DBA_PDBS ORDER BY PDB_NAME; (record the current mode - likely MANUAL)
Enable automatic snapshots every 24 hours:
SQL> ALTER PLUGGABLE DATABASE SNAPSHOT MODE EVERY 24 HOURS;
Confirm the change:
SQL> SELECT PDB_NAME, SNAPSHOT_MODE, SNAPSHOT_INTERVAL AS INTERVAL_MINUTES, SNAPSHOT_INTERVAL/60 AS INTERVAL_HOURS FROM DBA_PDBS ORDER BY PDB_NAME; (expected: SNAPSHOT_MODE = AUTO, INTERVAL_MINUTES = 1440, INTERVAL_HOURS = 24)
Note: The interval accepts MINUTES (max 3000) or HOURS (max 2000). Example for every 2 hours: SNAPSHOT MODE EVERY 120 MINUTES or SNAPSHOT MODE EVERY 2 HOURS. No new entry will appear in DBA_PDB_SNAPSHOTS until the interval elapses. If you need one sooner, create it manually as we did previously
Now configure the retention (maximum number of snapshots in the carousel):
SQL> column PROPERTY_NAME format a20SQL> column PROPERTY_VALUE format a20SQL> SELECT r.CON_ID, p.PDB_NAME, PROPERTY_NAME, PROPERTY_VALUE FROM CDB_PROPERTIES r, CDB_PDBS p WHERE r.CON_ID = p.CON_ID AND PROPERTY_NAME = 'MAX_PDB_SNAPSHOTS' ORDER BY CON_ID; (record your output) (default is 4096 — at 24h frequency, that's over 11 years of snapshots!)
Adjust retention to 30 snapshots (e.g. 30 days at 24h frequency) and verify:
SQL> ALTER PLUGGABLE DATABASE SET MAX_PDB_SNAPSHOTS = 30;SQL> SELECT r.CON_ID, p.PDB_NAME, PROPERTY_NAME, PROPERTY_VALUE FROM CDB_PROPERTIES r, CDB_PDBS p WHERE r.CON_ID = p.CON_ID AND PROPERTY_NAME = 'MAX_PDB_SNAPSHOTS' ORDER BY CON_ID; (record your output) (expected: PROPERTY_VALUE = 30)
Carousel behavior: The carousel is circular “FIFO”. When the maximum is reached, each new snapshot replaces the oldest one. To drop all snapshots at once, set MAX_PDB_SNAPSHOTS=0.
Thin Clones (Snapshot copies)
A thin clone (Oracle also calls them snapshot copy or snapshot clone – they are synonyms) is different from a snapshot. While a snapshot has no dictionary, undo, or temporary tablespace of its own, a thin clone does have all of these, and therefore a thin clone can be instantly opened and used as a full read/write database. In both cases, the user tablespaces are not duplicated — both use redirect-on-write technology.
Before creating any thin clone, record the vault space as a baseline:
SQL> show con_nameCON_NAME------------------------------CDB$ROOTSQL> SELECT VAULT_NAME, ROUND(HC_SPACE_PROV/1024/1024/1024/3, 0) AS total_gb, ROUND(HC_SPACE_USED/1024/1024/1024/3, 0) AS usado_gb, ROUND((HC_SPACE_PROV - HC_SPACE_USED)/1024/1024/1024/3, 0) AS libre_gb FROM V$EXA_VAULT ORDER BY 1; (record your baseline values)
Now we will create a thin clone directly from the live source PDB using copy-on-write at the storage level:
SQL> ALTER SESSION SET CONTAINER = CDB$ROOT;SQL> SET TIMING ONSQL> CREATE PLUGGABLE DATABASE PDB_THIN_NORMAL FROM <YOUR_SOURCE_PDB> 2 SNAPSHOT COPY 3 KEYSTORE IDENTIFIED BY <your_tde_wallet_password>;SQL> SET TIMING OFF(record the elapsed time)
On TDE encryption: ExaDB-XS is an OCI database service where TDE encryption is mandatory. When cloning a TDE-encrypted PDB, you must provide the wallet password so the new clone can store its encryption key. From Oracle 19.12 onward, the key is copied transparently – no manual export/import is needed (unlike earlier versions).
Open and verify:
SQL> ALTER PLUGGABLE DATABASE PDB_THIN_NORMAL OPEN;SQL> show pdbs;
You should see something like this:
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 <YOUR_SOURCE_PDB> READ WRITE NO
5 PDB_THIN_NORMAL READ WRITE NO
Now let’s inspect the data files. First, the source PDB files:
SQL> set linesize 999SQL> column file_name format a40SQL> column GB format 9999999999SQL> select file_name, SPACE_USED/1024/1024/1024 GB from v$exa_file where con_id = 3 order by file_name;(record the source PDB file names and sizes — e.g., SYSAUX, SYSTEM, UNDOTBS1, USERS, TEMP)
Now the thin clone files:
SQL> select file_name, SPACE_USED/1024/1024/1024 GB from v$exa_file where con_id = 5 order by file_name;(record the thin clone file names and sizes)
What you should observe is that the data file names in the thin clone are the same as the source PDB – they are not just identically named, they are literally the same files (pointers to the same storage blocks). This confirms it is a true thin clone. The only additional file is the TEMP tablespace, which is new and exclusive to the thin clone.
Important about
V$EXA_FILE: This view does not show the space saved by thin clone pointers. It reports the full size of the pointed-to data as if it were physically occupied. To verify the actual space savings, always useV$EXA_VAULT
Now we will verify the TEMP space behaviour. Connect to the thin clone and check the TEMP tablespace:
SQL> ALTER SESSION SET CONTAINER = PDB_THIN_NORMAL;SQL> SELECT 'TEMP', TABLESPACE_NAME, 2 ROUND(SUM(bytes)/1024/1024/1024, 2) GB 3 FROM DBA_TEMP_FILES 4 GROUP BY TABLESPACE_NAME; (you should see the inherited TEMP size from the parent — e.g., ~255 GB)
The thin clone inherits the TEMP size from the parent. However, Exascale delays physical space allocation until data is actually written. As the Oracle documentation states: physical space is consumed only when data is written to the file.
This means you may not see any increase in the vault space after creating the thin clone, unless the TEMP is actively being used. For short-lived ephemeral environments, you may want to drop and recreate a smaller TEMP tablespace.
Now, the most important check: verify that the vault space has not increased:
SQL> ALTER SESSION SET CONTAINER = CDB$ROOT;SQL> SELECT VAULT_NAME, ROUND(HC_SPACE_PROV/1024/1024/1024/3, 0) AS total_gb, ROUND(HC_SPACE_USED/1024/1024/1024/3, 0) AS usado_gb, ROUND((HC_SPACE_PROV - HC_SPACE_USED)/1024/1024/1024/3, 0) AS libre_gb FROM V$EXA_VAULT ORDER BY 1; (compare it with the previous output — the used space should be virtually identical)
The output from V$EXA_VAULT matches the data shown in the OCI web console. The vault space should not have grown significantly (specially since we have still not used the thin clone TEMP).
Create thin clone from a Snapshot (“…using snapshot”)
This is a particularly powerful strategy: you create a thin clone read/write database that represents the state of the source PDB at an exact point in the past (the snapshot’s SCN).
SQL> ALTER SESSION SET CONTAINER = CDB$ROOT;SQL> SET TIMING ONSQL> CREATE PLUGGABLE DATABASE PDB_THIN_SNAP FROM <YOUR_SOURCE_PDB> 2 USING SNAPSHOT snapshot_1 3 SNAPSHOT COPY 4 KEYSTORE IDENTIFIED BY <your_tde_wallet_password>;SQL> SET TIMING OFFSQL> ALTER PLUGGABLE DATABASE PDB_THIN_SNAP OPEN;SQL> SHOW PDBS(record your output - you'd see something like:) CON_ID CON_NAME OPEN MODE RESTRICTED---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 <YOUR_SOURCE_PDB> READ WRITE NO 5 PDB_THIN_NORMAL READ WRITE NO 6 PDB_THIN_SNAP READ WRITE NO
Important: Key point here is the combination of “using snapshot” and “snapshot copy” clause. This is only possible in Exascale systems.
Now verify the data isolation between the Thin Clone and the source database. Since PDB_THIN_SNAP is a full read/write database, we can modify data in it without any risk to the source PDB. Let’s prove it.
We will first modify a row in the thin clone:
SQL> ALTER SESSION SET CONTAINER = PDB_THIN_SNAP;SQL> select * from <schema>.<table> where <your_key_column> = <some_value>;(record the original row)SQL> UPDATE <schema>.<table> SET <column> = <new_value> WHERE <key_condition>;SQL> commit;SQL> select * from <schema>.<table> where <your_key_column> = <some_value>;(record the updated row)
Now verify the source PDB is not modified:
SQL> ALTER SESSION SET CONTAINER = <YOUR_SOURCE_PDB>;SQL> show con_nameCON_NAME------------------------------<YOUR_SOURCE_PDB>SQL> select * from <schema>.<table> where <your_key_column> = <some_value>;(the original value should be unchanged — confirming the isolation)
SO what happens now if we drop the thin clone and recreate it from the same snapshot? The recreated clone should contain the original, unmodified data from the snapshot timestamp:
SQL> ALTER SESSION SET CONTAINER = CDB$ROOT;SQL> ALTER PLUGGABLE DATABASE PDB_THIN_SNAP CLOSE IMMEDIATE;SQL> DROP PLUGGABLE DATABASE PDB_THIN_SNAP INCLUDING DATAFILES;SQL> show pdbs(PDB_THIN_SNAP should not be present now)SQL> CREATE PLUGGABLE DATABASE PDB_THIN_SNAP FROM <YOUR_SOURCE_PDB> 2 USING SNAPSHOT snapshot_1 3 SNAPSHOT COPY 4 KEYSTORE IDENTIFIED BY <your_tde_wallet_password>;SQL> ALTER PLUGGABLE DATABASE PDB_THIN_SNAP OPEN;SQL> ALTER SESSION SET CONTAINER = PDB_THIN_SNAP;SQL> select * from <schema>.<table> where <your_key_column> = <some_value>;(the original value should be back — the snapshot is immutable)
Before proceeding to the last exercise we will do some cleaning:
SQL> ALTER SESSION SET CONTAINER = CDB$ROOT;SQL> ALTER PLUGGABLE DATABASE PDB_THIN_NORMAL CLOSE IMMEDIATE;SQL> DROP PLUGGABLE DATABASE PDB_THIN_NORMAL INCLUDING DATAFILES;SQL> ALTER PLUGGABLE DATABASE PDB_THIN_SNAP CLOSE IMMEDIATE;SQL> DROP PLUGGABLE DATABASE PDB_THIN_SNAP INCLUDING DATAFILES;
Also drop the manual snapshot:
SQL> ALTER SESSION SET CONTAINER = <YOUR_SOURCE_PDB>;SQL> ALTER PLUGGABLE DATABASE DROP SNAPSHOT SNAPSHOT_1;
Automated child enviromnent refresh (Refreshable PDB + thin clones)
While thin clones can be created directly from the source PDB when both share the same vault (as we did in Part 3), this section demonstrates a more advanced pattern: creating a Refreshable PDB (a full copy) and then creating multiple thin clones from it. After the thin clones are created, we refresh the Refreshable PDB again and verify that the preexisting thin clones remain alive and unaffected.
This exercise uses the OCI Web Console for the Refreshable PDB creation.
Since the Refreshable PDB is a full copy of the database, we will use a new, smaller PDB called ORIGEN_REFRESH (with small size) to keep exercise times short.
We will start creating a reference table in the source PDB that we will use to track changes across refreshes (we will use SYS schema. You shouldn’t and you know it. But for the sake of a simpler exercise that will work):
[oracle@exaxs1-wsjjr ~]$ . CDBPOC.env[oracle@exaxs1-wsjjr ~]$ sqlplus / as sysdbaSQL> ALTER SESSION SET CONTAINER = ORIGEN_REFRESH;SQL> CREATE TABLE SYS.proyectos ( 2 id_proyecto NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, 3 nombre_cliente VARCHAR2(100), 4 presupuesto_gb NUMBER, 5 estado VARCHAR2(20) 6 );SQL> INSERT INTO SYS.proyectos (nombre_cliente, presupuesto_gb, estado) 2 VALUES ('ORIGEN', 500, 'ACTIVO');SQL> commit;SQL> exit
The Refreshable PDB will live in a different CDB (CDBPOC2), so it needs a database link back to the source CDB (CDBPOC). Create a common user in the source CDB with the required privileges:
[oracle@exaxs1-wsjjr ~]$ . CDBPOC.env[oracle@exaxs1-wsjjr ~]$ sqlplus / as sysdbaSQL> CREATE USER c##refresh_user IDENTIFIED BY <your_password>;SQL> GRANT CREATE SESSION TO c##refresh_user CONTAINER=ALL;SQL> GRANT CREATE PLUGGABLE DATABASE TO c##refresh_user CONTAINER=ALL;SQL> GRANT SYSOPER TO c##refresh_user CONTAINER=ALL;SQL> exit
This step is performed through the OCI Web Console, so you can practice console actions as well. Follow these steps:
Step 1: Navigate to the VM Cluster page, then click the “Container databases” tab.
Step 2: Select the source CDB (e.g. CDBPOC). On the database details page, click the “Pluggable Databases” tab.
Step 3: Find the source PDB (ORIGEN_REFRESH) in the list. Click the three-dot menu (⋮) on its row and select “Clone”.
Step 4: On the “Clone pluggable database” page, select the clone type: “Refreshable clone” — described as “Create a refreshable copy of the source PDB in a different database.”
Step 5: Configure the Destination:
- Compartment: select your compartment
- VM cluster:
exaxs(same cluster) - Database:
CDBPOC2(a different CDB — this is important, because we want to simulate a refreshable copy that could live on a separate infrastructure)
Step 6: Configure the New PDB:
- PDB name:
DESTINO_REFRESH - Database TDE wallet password: enter your wallet password
Step 7: Configure the Source:
- Source database SYS password: enter the SYS password for the source CDB
Step 8: Configure the Database link:
- Database link username:
c##refresh_user - Database link password: the password you set previously
- Enable thin clone: leave this UNCHECKED. We intentionally want a full copy here, because the goal is to use this Refreshable PDB as a stable base (probably in a different infrastructure, from which we will create thin clones later.
Step 9: Click “Clone”.
After a few minutes, the new PDB DESTINO_REFRESH should appear in the Pluggable Databases list of CDBPOC2 with State: Available and Refreshable clone: Yes.
Now we will perform the first refresh and verify that the reference table exists in the Refreshable PDB:
[oracle@exaxs1-wsjjr ~]$ . CDBPOC2.env[oracle@exaxs1-wsjjr ~]$ sqlplus / as sysdbaSQL> ALTER PLUGGABLE DATABASE DESTINO_REFRESH CLOSE;SQL> ALTER PLUGGABLE DATABASE DESTINO_REFRESH REFRESH;SQL> ALTER PLUGGABLE DATABASE DESTINO_REFRESH OPEN READ ONLY;SQL> ALTER SESSION SET CONTAINER = DESTINO_REFRESH;SQL> select * from proyectos;(record your output - you should see:)ID_PROYECTO NOMBRE_CLIENTE PRESUPUESTO_GB ESTADO----------- -------------------- -------------- -------------------- 1 ORIGEN 500 ACTIVO
The reference table from the source PDB has been successfully replicated.
Now we create a thin clone (read/write) from the Refreshable PDB:
[oracle@exaxs1-wsjjr ~]$ . CDBPOC2.env[oracle@exaxs1-wsjjr ~]$ sqlplus / as sysdbaSQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 DESTINO_REFRESH READ ONLY NOSQL> CREATE PLUGGABLE DATABASE PDBA FROM DESTINO_REFRESH 2 SNAPSHOT COPY 3 KEYSTORE IDENTIFIED BY <your_tde_wallet_password>;SQL> ALTER PLUGGABLE DATABASE PDBA OPEN;SQL> show pdbs(record your output - you should see:) CON_ID CON_NAME OPEN MODE RESTRICTED---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 DESTINO_REFRESH READ ONLY NO 4 PDBA READ WRITE NO
Note that PDBA is READ WRITE – it is a fully operational database. Making a change in it will prove it is independent:
SQL> ALTER SESSION SET CONTAINER = PDBA;SQL> INSERT INTO SYS.proyectos (nombre_cliente, presupuesto_gb, estado) 2 VALUES ('PDBA', 100, 'ACTIVO');SQL> commit;SQL> select * from SYS.proyectos;(record your output - you should see:)ID_PROYECTO NOMBRE_CLIENTE PRESUPUESTO_GB ESTADO----------- -------------------- -------------- -------------------- 1 ORIGEN 500 ACTIVO 21 PDBA 100 ACTIVO
PDBA now has a row that does not exist in the source PDB.
Go back to the source CDB and add a new row to the source PDB. This simulates new production data arriving:
[oracle@exaxs1-wsjjr ~]$ . CDBPOC.env[oracle@exaxs1-wsjjr ~]$ sqlplus / as sysdbaSQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 <YOUR_SOURCE_PDB> READ WRITE NO 4 ORIGEN_REFRESH READ WRITE NOSQL> ALTER SESSION SET CONTAINER = ORIGEN_REFRESH;SQL> INSERT INTO SYS.proyectos (nombre_cliente, presupuesto_gb, estado) 2 VALUES ('CLIENT2', 500, 'ACTIVO');SQL> commit;SQL> select * from SYS.proyectos;(record your output - you should see:)ID_PROYECTO NOMBRE_CLIENTE PRESUPUESTO_GB ESTADO----------- -------------------- -------------- -------------------- 1 ORIGEN 500 ACTIVO 2 CLIENT2 500 ACTIVO
The source PDB now has 2 rows.
And now, this is the key exercise. We will refresh DESTINO_REFRESH with the new data from the source, and then verify that:
- DESTINO_REFRESH reflects the updated source (2 rows)
- PDBA (the thin clone from the refreshable pdb) is and remains completely unaffected
So we proceed to refresh the refreshable PDB:
[oracle@exaxs1-wsjjr ~]$ . CDBPOC2.env[oracle@exaxs1-wsjjr ~]$ sqlplus / as sysdbaSQL> ALTER PLUGGABLE DATABASE DESTINO_REFRESH CLOSE;SQL> ALTER PLUGGABLE DATABASE DESTINO_REFRESH REFRESH;SQL> ALTER PLUGGABLE DATABASE DESTINO_REFRESH OPEN READ ONLY;
Verify DESTINO_REFRESH has the new data:
SQL> ALTER SESSION SET CONTAINER = DESTINO_REFRESH;SQL> set linesize 999SQL> select * from proyectos;(record your output - you should see:)ID_PROYECTO NOMBRE_CLIENTE PRESUPUESTO_GB ESTADO----------- -------------------- -------------- -------------------- 1 ORIGEN 500 ACTIVO 2 CLIENT2 500 ACTIVO
The Refreshable PDB now matches the source PDB (2 rows).
Now verify that PDBA is untouched:
SQL> ALTER SESSION SET CONTAINER = PDBA;SQL> select * from proyectos;(record your output - you should see:)ID_PROYECTO NOMBRE_CLIENTE PRESUPUESTO_GB ESTADO----------- -------------------- -------------- -------------------- 1 ORIGEN 500 ACTIVO 21 PDBA 100 ACTIVO
PDBA still has its own row (PDBA) and does NOT have the new row (CLIENT2) from the source. The thin clone is completely isolated from the refresh cycle.
This confirms that:
- Thin clones created from a Refreshable PDB survive the refresh of their parent
- Each thin clone is a fully independent, point-in-time copy that is not affected by subsequent refreshes
- You can maintain multiple thin clones in parallel, each representing a different point in time, without one conditioning the other
Summary
With this workbook you can try four key capabilities of ExaDB-XS with Exascale Storage Vault (or ExaC@C with Exascale VM cluster):
| Capability | Time | Extra Space |
|---|---|---|
| PDB Snapshot creation | Seconds | Negligible |
| Thin clone from live PDB | Seconds | Near zero (only TEMP) |
| Thin clone from snapshot | Seconds | Near zero (only TEMP) |
| Refreshable PDB refresh | Minutes (depends on redo volume and refresh frequency) | Full copy |
| Thin clone from Refreshable PDB | Seconds | Near zero (only TEMP) |
The combination of Refreshable PDB + thin clones is the most powerful pattern: it enables a workflow where production data flows periodically into a refreshable copy – living in the same or different infrastructure- , and multiple independent test/dev/QA environments are created as thin clones – each fully writable, fully isolated, and each consuming virtually no additional storage.
As I mentioned in previous posts, it is also perfectly possible to create a thin clone from a thin clone. So an architecture like Prod -> thin clone with datamasking -> multiple nonprod environments is also possible without duplicating one single user tablespace. We would use exactly the same “thin clone” steps shown here. The refreshable PDB exercise is useful as many times nonprod environments are not sharing the same physical infrastructure as production (not connected to the same vault), and so we need a full intermediate bastion.
I hope you’ve found this workbook useful and that it helps you understand the true potential of this fantastic technology known as exascale. See you in the next article (hopefully a shorter one)!

