The steps below outline how to convert an Oracle 12c non-container database to a pluggable database in the multitenant architecture. Oracle has moved all future releases to the multitenant architecture so conversion will eventually be necessary.

These steps are written for Oracle 12.1; however, the basic premise and steps remain similar for later versions.

---------------------------
--- ENVIRONMENT INFORMATION
ORACLE_HOME: /u01/app/oracle/product/12.1.0.2/
NON-CDB DATABASE NAME: SANDBOX
CDB DATABASE NAME: CDB1
PDB DATABASE NAME: SANDBOX
---------------------------

1. Create database parameter file and create all referenced directory paths

[oracle@bigdatalite ~] vi $ORACLE_HOME/dbs/initCDB1.ora
DB_NAME = CDB1
DB_BLOCK_SIZE = 8192
DB_CREATE_FILE_DEST = /u01/app/oracle/oradata
DB_RECOVERY_FILE_DEST = /u01/app/oracle/fast_recovery_area
CONTROL_FILES = ('/u01/app/oracle/oradata/CDB1/control01.ctl', '/u01/app/oracle/fast_recovery_area/CDB1/controlfile/control2.ctl')

2. Set environment and startup database off of the parameter file

export ORACLE_HOME=/u01/app/oracle/product/12.1.0.2/dbhome_1
export ORACLE_SID=CDB1
sqlplus / as sysdba
SYS@CDB1> startup nomount pfile='$ORACLE_HOME/dbs/initCDB1.ora';

3. Create container database

SYS@CDB1>
CREATE DATABASE CDB1
USER SYS IDENTIFIED BY <PASSWORD>
USER SYSTEM IDENTIFIED BY <PASSWORD>
CHARACTER SET AL32UTF8 NATIONAL CHARACTER SET AL16UTF16
EXTENT MANAGEMENT LOCAL
DEFAULT TEMPORARY TABLESPACE TEMP01
UNDO TABLESPACE UNDOTBS01
ENABLE PLUGGABLE DATABASE
/

4. Run catcdb.sql script to create all components required by a CDB

@?/rdbms/admin/catcdb.sql

5. Prepare the non-CDB environment for conversion.

The first step is to shutdown the non-CDB database, open in read-only mode, and create the XML file needed for CDB conversion

export ORACLE_SID=SANDBOX
sqlplus / as sysdba
--- check number of invalid objects and compile (if necessary)
SYS@SANDBOX> select * from dba_objects where status <> 'VALID';

no rows selected

SYS@SANDBOX> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

SYS@SANDBOX> startup open read only;
ORACLE instance started.

Total System Global Area 1073741824 bytes
Fixed Size		    2932632 bytes
Variable Size		  377487464 bytes
Database Buffers	  687865856 bytes
Redo Buffers		    5455872 bytes
Database mounted.
Database opened.

SYS@SANDBOX> show con_name;

CON_NAME
------------------------------
SANDBOX

SYS@SANDBOX>
BEGIN
DBMS_PDB.DESCRIBE(pdb_descr_file => '/tmp/SANDBOXNonPDB.xml');
END;
/

PL/SQL procedure successfully completed.

SYS@SANDBOX> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.

6. On the CDB, check pluggable compatibility.

[oracle@bigdatalite ~]$ export ORACLE_SID=CDB1
[oracle@bigdatalite ~]$ echo $ORACLE_SID
CDB1
[oracle@bigdatalite ~]$ sqlplus / as sysdba

SQL*Plus: Release 12.1.0.2.0 Production on Tue Jun 30 22:40:13 2020

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


Connected to:
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options

SYS@CDB1> show con_name;

CON_NAME
------------------------------
CDB$ROOT

SYS@CDB1> SET SERVEROUTPUT ON;
DECLARE
compatible CONSTANT VARCHAR2(3) := CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY(pdb_descr_file => '/tmp/SANDBOXNonPDB.xml')
WHEN TRUE THEN 'YES'
ELSE 'NO'
END;
BEGIN
DBMS_OUTPUT.PUT_LINE(compatible);
END;

YES

PL/SQL procedure successfully completed.

7. If the CHECK_PLUG_COMPATIBILITY returns “YES,” everything should be in order.

However, review the PDB_PLUG_IN_VIOLATIONS view for errors/warnings and correct as necessary.

SYS@CDB1>col cause for a20
col name for a20
col message for a35 word_wrapped
select name,cause,type,message,status from PDB_PLUG_IN_VIOLATIONS where name='SANDBOX'
/

NAME		     CAUSE		  TYPE
-------------------- -------------------- ---------
MESSAGE 			    STATUS
----------------------------------- ---------
SANDBOX 	     Non-CDB to PDB	  WARNING
PDB plugged in is a non-CDB,	    PENDING
requires noncdb_to_pdb.sql be run.

8. Create a pluggable database using the XML file generated earlier.

If necessary, you can include the FILE_NAME_CONVERT parameter here to convert data file paths to a separate location. By default, the files will be copied to the location specified in the DB_CREATE_FILE_DEST parameter mentioned above. Additionally, I chose to use the default COPY parameter to retain the previous files to be deleted later. If you want to perform a direct conversion, include NOCOPY instead.

SYS@CDB1> CREATE PLUGGABLE DATABASE SANDBOX USING '/tmp/SANDBOXNonPDB.xml';

Pluggable database created.

9. Run the $ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql script

SYS@CDB1> show pdbs;

    CON_ID CON_NAME			  OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
	 2 PDB$SEED			  READ ONLY  NO
	 3 SANDBOX			  MOUNTED
	 
SYS@CDB1> alter session set CONTAINER=SANDBOX;

Session altered.

SYS@CDB1> show con_name;

CON_NAME
------------------------------
SANDBOX

SYS@CDB1> @$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql
...
PL/SQL procedure successfully completed.

10. Open the pdb and review for potential errors

SYS@CDB1> show error
No errors.

SYS@CDB1> show con_name;

CON_NAME
------------------------------
SANDBOX
SYS@CDB1> show pdbs;

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         3 SANDBOX                        MOUNTED

SYS@CDB1> ALTER PLUGGABLE DATABASE OPEN;

Pluggable database altered.

SYS@CDB1> show pdbs;

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         3 SANDBOX                        READ WRITE NO

SYS@CDB1> select message,time from pdb_plug_in_violations;

no rows selected

11. Check invalid objects and compile if necessary

SYS@CDB1> select * from dba_objects where status <> 'VALID';

no rows selected

It's as simple as that! We now have a completed migration from non-container to container architecture. If you have any questions or comments, reach out to us here or in the comment section below.