Autonomous Database makes cloning a single API call, which means teams clone a lot. Choosing the right kind of clone controls cost, data exposure and how stale the copy is.
Clone types
| Type | What you get | Typical use |
|---|---|---|
| Full clone | Complete copy of data and metadata at that moment | Test with production-like data, troubleshooting |
| Metadata clone | Schema, objects, code, no data | Dev environments, CI schemas |
| Clone from backup (point in time) | Full copy as of a timestamp in backup retention | Recover data after a bad change, audit an old state |
| Refreshable clone | Read-only copy you can refresh from the source on demand | Reporting offload, read-only analytics, rehearsing upgrades |
Full and metadata clones
oci db autonomous-database create-from-clone \
--compartment-id $TEST_COMP --source-id $PROD_ADB \
--clone-type FULL --db-name ORDTEST1 --display-name orders-test-1 \
--admin-password "$ADMIN_PW" --compute-model ECPU --compute-count 2 --data-storage-size-in-tbs 1
oci db autonomous-database create-from-clone \
--compartment-id $DEV_COMP --source-id $PROD_ADB \
--clone-type METADATA --db-name ORDDEV1 --display-name orders-dev-1 \
--admin-password "$ADMIN_PW" --compute-model ECPU --compute-count 2
The clone gets its own wallet, its own ADMIN password, and its own network settings. Set the network access (private endpoint or ACLs) as part of creation; do not let a production data clone land with public access.
Caution
A full clone contains production personal data. Put it in a compartment with production-level access controls, or mask it before anyone else gets access.
Masking after a full clone
Use Data Safe data masking (or your own scripts) as the first step after a clone, before granting access:
-- minimal example: scramble emails and phones in a test clone
UPDATE app.customers
SET email = 'user' || customer_id || '@example.test',
phone = '000' || LPAD(MOD(customer_id, 10000000), 7, '0');
COMMIT;
Automate it: clone, mask, then open access, all in one pipeline.
Clone from a backup timestamp
oci db autonomous-database create-from-backup-timestamp \
--compartment-id $RECOVERY_COMP --autonomous-database-id $PROD_ADB \
--timestamp "2026-10-28T09:15:00Z" --clone-type FULL \
--db-name ORDPIT1 --display-name orders-pit-0915 --admin-password "$ADMIN_PW" \
--compute-model ECPU --compute-count 2
This is the cleanest way to recover rows deleted by mistake: clone to just before the change, then copy the rows back over a database link or with Data Pump.
Refreshable clones
oci db autonomous-database create-refreshable-clone \
--compartment-id $REPORT_COMP --source-id $PROD_ADB \
--db-name ORDRPT --display-name orders-reporting \
--refreshable-mode MANUAL --compute-model ECPU --compute-count 4
Command names and parameters have changed across CLI versions (on some versions this is create-from-clone with --is-refreshable-clone); check oci db autonomous-database --help.
Refresh it:
oci db autonomous-database update --autonomous-database-id $RPT_ADB --refreshable-mode AUTOMATIC \
--auto-refresh-frequency-in-seconds 3600
# or a one-off manual refresh to the latest point
oci db autonomous-database manual-refresh --autonomous-database-id $RPT_ADB
What to know:
- The clone is read-only while it is refreshable. Reports that create temporary tables or write logs need a different schema strategy.
- During a refresh, connections are interrupted. Schedule refreshes outside reporting hours.
- The source must be refreshed within a maximum staleness window (the docs give the current limit), or the clone must be disconnected and becomes a normal clone.
- Disconnect turns it into a regular, writable database; reconnecting is possible only within a limited time.
oci db autonomous-database update --autonomous-database-id $RPT_ADB --is-refreshable-clone false
Upgrade and change rehearsal
- Create a refreshable clone of production.
- Refresh it right before the rehearsal; disconnect it so it is writable.
- Run the application release scripts, measure duration, test.
- Delete it afterwards.
You get production-sized timing without touching production.
Cost control
| Practice | Effect |
|---|---|
| Small ECPU count on clones, scale only during tests | Pays for what you use |
Stop clones out of hours (oci db autonomous-database stop) | Compute not billed while stopped; storage still billed |
| Expiry tags plus a scheduled cleanup | Stops clone sprawl |
| Metadata clones for dev | No data storage, no data exposure |
Find old clones:
oci search resource structured-search --query-text \
"query autonomousdatabase resources where timeCreated < '2026-09-01T00:00:00Z'" \
--query 'data.items[].{name:"display-name", comp:"compartment-id"}' --output table
Prevent it next time
- One pipeline for full clones that always masks before access.
- Refreshable clones for reporting instead of letting BI tools query production.
- Expiry tags mandatory on every clone (tag defaults on clone compartments).