Continuing with trying to finish additional blog posts which have been on my list for a while, is a review of the methods of migrating a Non-Container Database (Non-CDB) to a Container Database (CDB) with Pluggables.
I wish this was easier and Oracle gave you a complete “in-place” method to do this, but the only way to get a Non-CDB (pre-12c database) to a CDB is to create a new database and migrate the Non-CDB into the new CDB as a PDB.
I will make the assumption that the creation of the new CDB is complete. So lets look at some methods of creating / migrating the PDB and their pros and cons:
In either case, you need to start with creating the XML file which will describe the new PDB:
On the Non-CDB:
SHUTDOWN IMMEDIATE; startup mount exclusive; alter database open read only;
Create the PDB Describe XML File:
BEGIN DBMS_PDB.DESCRIBE( pdb_descr_file => '/export/home/oracle/nonCDBToPDB.xml'); END; / shutdown immediate;
Verify the XML File on the new CDB:
SET SERVEROUTPUT ON DECLARE hold_var boolean; begin hold_var := DBMS_PDB.CHECK_PLUG_COMPATIBILITY(pdb_descr_file=>'/export/home/oracle/nonCDBToPDB.xml'); if hold_var then dbms_output.put_line('YES'); else dbms_output.put_line('NO'); end if; end; /
Check for errors:
set lines 300 col cause for a25 col message for a150 set pagesize 9999 select name,cause,action,type,message,status from PDB_PLUG_IN_VIOLATIONS;
Before you can proceed, all errors contained in PDB_PLUG_IN_VIOLATIONS must be resolved. Next are 2 out of the 3 methods to migrate an Non-CDB to PDB. I will leave the “COPY” method out of this post as it is not feasible to move any of the databases I deal with on a day to day basis using ‘COPY’.
Create the PDB using “NOCOPY”. While “NOCOPY” is the fastest, it could be the most problematic long term because this function leaves all datafiles where they came from and since the new CDB is likely to be on the same host, the naming differences could be confusing at some point. Nonetheless, for demonstration, the command is quite easy:
CREATE PLUGGABLE DATABASE devpdb USING '/export/home/oracle/nonCDBToPDB.xml' NOCOPY TEMPFILE REUSE;
Based on my testing, the method I liked the most was the ‘MOVE’ option. To some, this may seem invasive, but for my environments this was the best option because the new file names are also corrected to contain the correct OMF path names based on the new CDB. While this method wasn’t as fast as NOCOPY, in my 18TB environment with 1200 datafiles, this command finished in just over 30 minutes. Pretty acceptable in my book:
CREATE PLUGGABLE DATABASE devpdb USING '/export/home/oracle/nonCDBToPDB.xml' MOVE TEMPFILE REUSE;
Finishing off the migration to the new PDB is the same regardless of the migration method:
Verify the PDB:
select name,guid, open_mode from v$pdbs; col pdb_name for a15 select pdb_name, status from dba_pdbs;
Clean up the PDB. This by far was one of the longest operations of the whole conversion:
alter session set container=devpdb; $ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql
Check for errors:
set lines 300 col cause for a25 col message for a50 col action for a100 set pagesize 9999 select name,cause,action,type,message,status from PDB_PLUG_IN_VIOLATIONS;
In my case, the only remaining violations that I had were some orphan database services that were stuck in the metadata. To clean this up you can execute:
alter session set container=; select SERVICE_ID,NAME,NETWORK_NAME,PDB FROM CDB_SERVICES ORDER BY PDB,SERVICE_ID; select SERVICE_ID,NAME,NETWORK_NAME FROM DBA_SERVICES ORDER BY SERVICE_ID; exec dbms_service.delete_service('')
Ensure that all pluggables are open and open on restart:
alter pluggable database all open; alter pluggable database all save state;
As with anything in our business, adequate testing goes a long way and these were my observations in my environment. If your experience varies, I sure would like to hear about it.