Two routes
| Route | When |
|---|---|
Manual: DBMS_PDB.DESCRIBE + plug in + noncdb_to_pdb.sql | Same version (19c → 19c CDB); you want control |
AutoUpgrade with target_cdb | Upgrade and conversion in one run (e.g. 19c non-CDB → 23ai PDB). See the AutoUpgrade post |
This post covers the manual route.
1. Pre-checks
- Same database version and patch level (RU) in source and CDB, or plan an upgrade.
- Character set compatible with the CDB (an AL32UTF8 CDB accepts most; a non-matching single-byte CDB doesn't).
- Options and components installed in the non-CDB exist in the CDB (
SELECT comp_name FROM dba_registry). - Space:
NOCOPYreuses files in place (fast, no rollback without a backup);COPYduplicates them.
2. Describe the non-CDB
-- in the non-CDB, opened READ ONLY
SHUTDOWN IMMEDIATE;
STARTUP OPEN READ ONLY;
BEGIN
DBMS_PDB.DESCRIBE(pdb_descr_file => '/u01/stage/salesdb.xml');
END;
/
SHUTDOWN IMMEDIATE;
3. Check compatibility from the CDB
-- in CDB$ROOT
SET SERVEROUTPUT ON
DECLARE
ok BOOLEAN;
BEGIN
ok := DBMS_PDB.CHECK_PLUG_COMPATIBILITY(pdb_descr_file => '/u01/stage/salesdb.xml', pdb_name => 'SALESPDB');
DBMS_OUTPUT.PUT_LINE(CASE WHEN ok THEN 'COMPATIBLE' ELSE 'NOT COMPATIBLE' END);
END;
/
SELECT type, message, action FROM pdb_plug_in_violations WHERE name = 'SALESPDB' AND status <> 'RESOLVED';
Fix ERROR rows before continuing. WARNING rows (e.g. parameter differences) are usually acceptable, but read them.
4. Plug in
Take a backup of the non-CDB first, especially with NOCOPY.
CREATE PLUGGABLE DATABASE salespdb USING '/u01/stage/salesdb.xml' NOCOPY TEMPFILE REUSE;
-- or COPY with file name conversion:
-- CREATE PLUGGABLE DATABASE salespdb USING '/u01/stage/salesdb.xml' COPY
-- FILE_NAME_CONVERT = ('/u02/oradata/SALES/', '/u02/oradata/CDB1/salespdb/');
5. Convert the dictionary
ALTER SESSION SET CONTAINER = salespdb;
@?/rdbms/admin/noncdb_to_pdb.sql
This can take a while (it recompiles and rewrites dictionary objects). Then:
ALTER PLUGGABLE DATABASE salespdb OPEN;
ALTER PLUGGABLE DATABASE salespdb SAVE STATE;
SELECT name, open_mode, restricted FROM v$pdbs;
RESTRICTED = YES means there are unresolved violations; check pdb_plug_in_violations again.
6. After conversion
| Area | Action |
|---|---|
| Services | Applications connect to the PDB service name (old SID-based connections break) |
| Users | Local users moved with the PDB; common users (C##) exist only at CDB level |
| Backups | RMAN now backs up the CDB; adjust scripts to BACKUP PLUGGABLE DATABASE or the whole CDB |
| Data Guard | Standby must be a CDB too; plan the standby re-creation |
| Monitoring | Point checks at the PDB service; container-aware queries (CON_ID) |
| Scheduler jobs, DB links | Test; DB links referencing the old global name may need changes |
Warning
With
NOCOPY, the original non-CDB can no longer be opened as before, because its files now belong to the PDB. Your rollback is the backup from Step 4.
Checklist
- Version, RU, character set and components match
- Compatibility check clean
- Backup taken before NOCOPY plug-in
-
noncdb_to_pdb.sqlrun, PDB unrestricted, state saved - Services, backups, Data Guard and monitoring updated