Oracle 12.1.0.2 brings a great new functionality: you can create thin clones – that is, not copying the source files, just pointers – on ext4 filesystem, the current default on Red Hat Linux 6.
Requirements for example below:
– Oracle 12.1.0.2
– Data files are on ext4 filesystem (or other supporting sparse files)
– Source PDB on read only mode
It is very simple to set up:
SQL> alter system set clonedb=TRUE scope=spfile; SQL> shutdown immediate SQL> startup SQL> show parameter clonedb NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ clonedb boolean TRUE
I will create a clone of the PDB2 database.
SQL> select name,con_id,open_mode,SNAPSHOT_PARENT_CON_ID from v$pdbs; NAME CON_ID OPEN_MODE SNAPSHOT_PARENT_CON_ID ------------------------------ ---------- ---------- ---------------------- PDB$SEED 2 READ ONLY 0 PDB1 3 MOUNTED 0 PDB2 4 READ ONLY 0
For this I need first to create the target directory for the datafiles.
SQL> ! mkdir -p /u01/app/oracle/oradata/NONRAC/PDB2_CLONE1
Then I can do the clone using the ‘snapshot copy’ clause. It took 9 seconds.
SQL> create pluggable database PDB2_C1 from PDB2 snapshot copy file_name_convert=('/u01/app/oracle/oradata/NONRAC/PDB2','/u01/app/oracle/oradata/NONRAC/PDB2_CLONE1'); Pluggable database created. Elapsed: 00:00:09.35
Note that the new PDB remains in MOUNT state and without showing a connection to its parent. I find unfortunate the lack of that information.
SQL> select name,con_id,open_mode,SNAPSHOT_PARENT_CON_ID from v$pdbs; NAME CON_ID OPEN_MODE SNAPSHOT_PARENT_CON_ID ------------------------------ ---------- ---------- ---------------------- PDB$SEED 2 READ ONLY 0 PDB1 3 MOUNTED 0 PDB2 4 READ ONLY 0 PDB2_C1 5 MOUNTED 0
After we open the clone in READ WRITE mode, then we can see the relationship with the parent.
SQL> alter pluggable database PDB2_C1 open read write; Pluggable database altered. Elapsed: 00:00:02.12 SQL> select name,con_id,open_mode,SNAPSHOT_PARENT_CON_ID from v$pdbs; NAME CON_ID OPEN_MODE SNAPSHOT_PARENT_CON_ID ------------------------------ ---------- ---------- ---------------------- PDB$SEED 2 READ ONLY 0 PDB1 3 MOUNTED 0 PDB2 4 READ ONLY 0 PDB2_C1 5 READ WRITE 4
And below we verify that the clone uses 4MB instead of 800MB of the source database.
SQL> ! du -m /u01/app/oracle/oradata/NONRAC/PDB2/* 6 /u01/app/oracle/oradata/NONRAC/PDB2/PDB2_users01.dbf 586 /u01/app/oracle/oradata/NONRAC/PDB2/sysaux01.dbf 261 /u01/app/oracle/oradata/NONRAC/PDB2/system01.dbf 1 /u01/app/oracle/oradata/NONRAC/PDB2/temp01.dbf SQL> ! du -m /u01/app/oracle/oradata/NONRAC/PDB2_CLONE1/* 1 /u01/app/oracle/oradata/NONRAC/PDB2_CLONE1/PDB2_users01.dbf 1 /u01/app/oracle/oradata/NONRAC/PDB2_CLONE1/sysaux01.dbf 1 /u01/app/oracle/oradata/NONRAC/PDB2_CLONE1/system01.dbf 1 /u01/app/oracle/oradata/NONRAC/PDB2_CLONE1/temp01.dbf
We can also clone non-CDB databases with some more steps, as explained at:
https://dbamarco.wordpress.com/2015/03/09/small-change-big-difference/
The clonedb.pl script (see documentation here) can also be used, even though you might find easier to script yourself to your own environment.