TIL: Migrate a PDB from backup including datafile movement

Sven Illert -

Today I learned an improvement for the way to migrate a non-container 12c database from a backup to a new container based database infrastructure in version 19 with all the glory of Oracle managed files (OMF). Of course that’s pretty simple anyways, but sometimes reading the documentation more intensely helps improving the methods you use on a daily basis. So let’s just for completeness describe the way to create a pluggable database as a clone from a database backup of a non-cdb. At first, we need to create a dummy instance and duplicate the database.

Create the dummy database:

% export ORACLE_HOME=/u01/app/oracle/product/19.19/dbhome_1
% export ORACLE_SID=DUP
% cat $ORACLE_HOME/dbs/initDUP.ora
*.audit_file_dest='/tmp'
*.db_name='DUP'
*.compatible='12.0.0.0.0'
*.sga_target=4G
*.pga_aggregate_target=512M
*.db_create_file_dest=+DATA
*.db_create_online_log_dest_1=+DATA
*.db_recovery_file_dest=+RECO
*.db_recovery_file_dest_size=50G
% sql / as sysdba
SQL> create spfile from pfile;
SQL> startup nomount

Duplicate from backup without opening the database (which is needed, since duplicating directly to the new home):

% rman auxiliary /
RMAN> run {
2> allocate auxiliary channel aux1 device type disk;
3> allocate auxiliary channel aux2 device type disk;
4> allocate auxiliary channel aux3 device type disk;
5> allocate auxiliary channel aux4 device type disk;
8> duplicate database to DUP backup location '/u70/SOURCE' noopen;
9> }

Now open the database with resetlogs into upgrade mode and start the database upgrade:

% sql / as sysdba
SQL> alter database open resetlogs upgrade;
% dbupgrade

After some time we have a closed database which is migrated to 19c which we need to start in read only mode to create the pdb description file:

% sql / as sysdba
SQL> startup open read only;
SQL> EXEC DBMS_PDB.DESCRIBE(pdb_descr_file => '/tmp/SOURCE.xml');
SQL> shutdown immediate;

Now we are ready to plug the non-cdb into the container and in one step also move the datafiles into the directory structure of the CDB. The magic here is to use MOVE FILE_NAME_CONVERT = NONE, which is not that obvious when you glance at the syntax in the documentation. Also we convert the dictionary to that of a pdb and create an application service for access of the freshly created database, which you should always do. Never ever use the default service of a (pluggable) database anymore.

OK, let’s do it:

% export ORACLE_SID=CDB
% sql / as sysdba
SQL> CREATE PLUGGABLE DATABASE SOURCE USING '/tmp/SOURCE.xml' MOVE FILE_NAME_CONVERT = NONE;
SQL> alter session set container=SOURCE;
SQL> @$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql
% srvctl add service -db $ORACLE_UNQNAME -pdb SOURCE -service SVC_SOURCE -role primary
% srvctl start service -db $ORACLE_UNQNAME -service SVC_SOURCE

And you know what? For Enterprise Edition databases this is not too much of an problem, since you can easily move any data files online to another destination. But this method also works for Standard Edition databases, where this is normaly not that easy and is only supported when the database is not open. I’d also recommend to use the same volume or ASM diskgroup for the intermediate database where the files of your destination pdb should be placed. Since this would not move any datafiles but only rename the files where they are.