Skip to content

Migrate Non-Container Database (CDB) to Pluggable Database (PDB)

    Using DBMS_PDB

    The DBMS_PDB package allows you to generate an XML metadata file from a non-CDB 12c database, effectively allowing it to be describe it the way you do when unplugging a PDB database. This allows the non-CDB to be plugged in as a PDB into an existing CDB.

    Cleanly shutdown the non-CDB and start it in read-only mode.

    export ORACLE_SID=db12c
    sqlplus / as sysdba
    
    SHUTDOWN IMMEDIATE;
    STARTUP OPEN READ ONLY;

    Describe the non-DBC using the DBMS_PDB.DESCRIBE procedure. This procedure creates an XML file in the same way that the unplug operation does for a PDB.

    BEGIN
      DBMS_PDB.DESCRIBE(
        pdb_descr_file => '/tmp/db12c.xml');
    END;
    /

    Shutdown the non-CDB database.

    export ORACLE_SID=db12c
    sqlplus / as sysdba
    
    SHUTDOWN IMMEDIATE;

    Connect to an existing CDB and create a new PDB using the file describing the non-CDB database. Remember to configure the FILE_NAME_CONVERT parameter to convert the existing files to the new location.

    export ORACLE_SID=cdb1
    sqlplus / as sysdba
    
    CREATE PLUGGABLE DATABASE pdb6 USING '/tmp/db12c.xml'
      COPY
      FILE_NAME_CONVERT = ('/u01/app/oracle/oradata/db12c/', '/u01/app/oracle/oradata/cdb1/pdb6/');

    Switch to the PDB container and run the “$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql” script to clean up the new PDB, removing any items that should not be present in a PDB.

    ALTER SESSION SET CONTAINER=pdb6;
    
    @$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql

    Startup the PDB and check the open mode.

    ALTER SESSION SET CONTAINER=pdb6;
    ALTER PLUGGABLE DATABASE OPEN;
    
    SELECT name, open_mode FROM v$pdbs;
    
    NAME                           OPEN_MODE
    ------------------------------ ----------
    PDB6                           READ WRITE
    
    1 row selected.
    
    SQL>

    The non-CDB has now been converted to a PDB. You should backup the PDB before you start to use it.

    Using Data Pump (expdb, impdp)

    A simple option is to export the data from the non-CDB and import it into a newly created PDB directly. Provided the import is connecting using a service pointing to the relevant PDB, this is no different to any other data transfer using data pump.

    Using Replication

    Another alternative is to use a replication product like Golden Gate to replicate the data from the non-container database to a pluggable database.

    Patching Considerations

    If your instances are not at the same patch level, you will get PDB violations visible in the PDB_PLUG_IN_VIOLATIONS view. If the destination is at a higher patch level than the source, simply run the datapatch utility on the destination instance in the normal way. It will determine what work needs to be done.

    cd $ORACLE_HOME/OPatch
    ./datapatch -verbose

    Migrate a Non-CDB to a Pluggable Database (PDB) with Remote Copy

    Preparing Remote Non-CDB database

    First, let´s create a user for use in database link:

    SQL> select instance_name from v$instance;
    
    INSTANCE_NAME
    ----------------
    db2
    
    SQL> CREATE USER convert_to_cdb_user IDENTIFIED BY Oracle_123;
    
    User created.
    
    SQL> GRANT CREATE SESSION, CREATE PLUGGABLE DATABASE TO convert_to_cdb_user;
    
    Grant succeeded.
    
    
    Open remote database in read-only mode:
    
    SQL> select instance_name from v$instance;
    
    INSTANCE_NAME
    ----------------
    db2
    
    SQL> shutdown immediate;
    
    Database closed.
    Database dismounted.
    ORACLE instance shut down.
    SQL> startup mount
    ORACLE instance started.
    
    Total System Global Area  734003200 bytes
    Fixed Size                  2928728 bytes
    Variable Size             205524904 bytes
    Database Buffers          520093696 bytes
    Redo Buffers                5455872 bytes
    Database mounted.
    
    SQL> alter database open read only;
    
    Database altered.
    
    
    Connect in our CDB container and check if you are able to connect in remote database using provided user
    
    [[email protected] ~]$ sqlplus convert_to_cdb_user/[email protected]
    
    SQL*Plus: Release 12.1.0.2.0 Production on Tue Mar 15 08:46:25 2016
    
    Copyright (c) 1982, 2014, Oracle.  All rights reserved.
    
    
    Connected to:
    Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
    Preparing Container Database (CDB)

    Now it´s time to configure our CDB. Let´s create the database link:

    SQL> show con_name
    
    CON_NAME
    ------------------------------
    CDB$ROOT
    
    SQL> CREATE DATABASE LINK clone_link
      2    CONNECT TO convert_to_cdb_user  IDENTIFIED BY Oracle_123 USING 'db2';
    
    Database link created.
    
    SQL> -- Testing
    SQL> select count(1) from [email protected]_link;
    
      COUNT(1)
    ----------
             0
    Cloning database

    Now we have both remote non-CDB database and container database ready, we just need execute the command to clone database

    SQL> show con_name
    
    CON_NAME
    ------------------------------
    CDB$ROOT
    
    SQL> CREATE PLUGGABLE DATABASE orapdb3
      2    FROM [email protected]_link
      3  FILE_NAME_CONVERT=('+DATA01/DB2/','+data02/orapdb3/');
    
    Pluggable database created.
    
    SQL> SELECT name, open_mode FROM v$pdbs WHERE name = 'ORAPDB3';
    
    NAME                           OPEN_MODE
    ------------------------------ ----------
    ORAPDB3                        MOUNTED
    

    Since this PDB was created as a clone of a non-CDB, before it can be opened we need to run the noncdb_to_pdb.sql script to clean it up.

    SQL> alter session set container=orapdb3;
    
    Session altered.
    
    SQL> show con_name
    
    CON_NAME
    ------------------------------
    ORAPDB3
    SQL> @?/rdbms/admin/noncdb_to_pdb.sql
    
    
    The PDB can now be opened:
    
    SQL> show pdbs
    
        CON_ID CON_NAME                       OPEN MODE  RESTRICTED
    ---------- ------------------------------ ---------- ----------
             5 ORAPDB3                        MIGRATE    YES 
    
    SQL> show con_name
    
    CON_NAME
    ------------------------------
    ORAPDB3
    
    SQL> shutdown immediate;
    
    Pluggable Database closed.
    
    SQL> startup
    
    Pluggable Database opened.
    
    
    SQL> show pdbs
    
        CON_ID CON_NAME                       OPEN MODE  RESTRICTED
    ---------- ------------------------------ ---------- ----------
             5 ORAPDB3                        READ WRITE NO
    
    Connect in CDB$ROOT and remove database link:
    
    SQL> alter session set container=cdb$root;
    
    Session altered.
    
    SQL> show con_name
    
    CON_NAME
    ------------------------------
    CDB$ROOT
    
    SQL> drop database link clone_link;
    
    Database link dropped.
    
    
    We can now shutdown old non-CDB database
    
    SQL> select instance_name, status from v$instance;
    
    INSTANCE_NAME    STATUS
    ---------------- ------------
    db2              OPEN
    
    SQL> select open_mode from v$database;
    
    OPEN_MODE
    --------------------
    READ ONLY
    
    
    SQL> shutdown immediate;
    Database closed.
    Database dismounted.
    ORACLE instance shut down.
    
    Finally, configure new PDB to automatically start.
    
    SQL> alter session set container=orapdb3;
    
    Session altered.
    
    SQL> alter pluggable database orapdb3 save state;
    
    Pluggable database altered.