A while back I blogged about using ACFS to provide a copy-on-write (CoW) file system for quick cloning PDBs. While ACFS is a great platform to enable quick PDB cloning it does have a few drawbacks, namely RAC. Running ASM/ACFS in a non RAC, aka Oracle Restart PDB snapshot cloning isn’t possible due to not being able to mount the ACFS snapshots automatically. So the question is how to do snapshot PDB cloning in a single instance environment.
Back in 11.2 Oracle introduced a NFS client embedded in the database kernel called Direct NFS (dNFS). A bit later the feature was added where dNFS could leverage RMAN image copies to quick clone databases. So in 12c does snap cloning a PDB using dNFS require RMAN image copies and NFS? Luckily no. Starting with 12.1.0.2 it is possible to use dNFS and setting an init parameter to snap clone PDBs using a regular file system.
For this tutorial using Oracle Linux 6.6 with ext4 and DB 12.1.0.2 PSU 2. First up is setting clonedb to true which requires and instance restart. Beware that with clonedb set to true additional SGA will be required to tracking which blocks have changed in the clone PDBs.
SQL> show parameter clone NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ clonedb boolean TRUE
Next a parent PDB has been created with and the Swingbench schema loaded. Note the files are being stored on a regular file system.
SQL> select con_id,guid from v$pdbs where name = 'SWING_SRC'; CON_ID GUID ---------- -------------------------------- 7 22123FC0ACAD2166E0532902A8C0AC2D SQL> select name from v$datafile where con_id=7; NAME ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ /u01/app/oracle/oradata/C008/22123FC0ACAD2166E0532902A8C0AC2D/datafile/o1_mf_system_c1ws3ljf_.dbf /u01/app/oracle/oradata/C008/22123FC0ACAD2166E0532902A8C0AC2D/datafile/o1_mf_sysaux_c1ws3lk1_.dbf /u01/app/oracle/oradata/C008/22123FC0ACAD2166E0532902A8C0AC2D/datafile/o1_mf_soe_c1wstz68_.dbf
$du -sh * 3.2G 22123FC0ACAD2166E0532902A8C0AC2D $df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_consol-lv_root 55G 42G 12G 79% / tmpfs 3.8G 629M 3.2G 17% /dev/shm /dev/vda1 477M 93M 356M 21% /boot
$ df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_consol-lv_root 55G 42G 12G 79% / tmpfs 3.8G 629M 3.2G 17% /dev/shm /dev/vda1 477M 93M 356M 21% /boot
The PDB is around 3.2GB in size and there is 12GB of free diskspace on the mount point. If we were to do a full clone we would quickly run out of space after 3 clones. So next lets clone the PDB using a snap clone clause. Since we are using clonedb and dNFS the parent PDB must remain in a read only mode for as long as any cloned PDBs remain. With the parent PDB in read only mode we can snap clone a new PDB.
sql>create pluggable database swing_clone1 from swing_src snapshot copy;
Checking the filesystem we still show 12G of free diskspace.
$ df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_consol-lv_root 55G 42G 12G 79% / tmpfs 3.8G 629M 3.2G 17% /dev/shm /dev/vda1 477M 93M 356M 21% /boot
In the alert log the following entries are shown.
**************************************************************** Pluggable Database SWING_CLONE1 with pdb id - 8 is created as UNUSABLE. If any errors are encountered before the pdb is marked as NEW, then the pdb must be dropped **************************************************************** Database Characterset for SWING_CLONE1 is WE8MSWIN1252 Deleting old file#43 from file$ Deleting old file#44 from file$ Deleting old file#45 from file$ Adding new file#46 to file$(old file#43) Adding new file#47 to file$(old file#44) Adding new file#48 to file$(old file#45) Successfully created internal service swing_clone1 at open ALTER SYSTEM: Flushing buffer cache inst=0 container=8 local
After that we can open the PDB as a normal PDB and run the order entry Swingbench load.
./charbench -c oewizard_clone2.xml Author : Dominic Giles Version : 2.5.0.971 Results will be written to results.xml. Hit Return to Terminate Run... Time Users TPM TPS 2:22:44 PM 5 39 10
After running the load additional disk space is used to store the changed blocks in the cloned PDB as the df command now shows slightly less free space, 11 GB instead of 12.
$ df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_consol-lv_root 55G 42G 11G 80% / tmpfs 3.8G 631M 3.2G 17% /dev/shm /dev/vda1 477M 167M 281M 38% /boot
Next we can verify the data files for the cloned PDB.
SQL> select guid,con_id from v$pdbs where name='SWING_CLONE1'; GUID CON_ID -------------------------------- ---------- 2215413A865F5166E0532902A8C03179 8 SQL> select name from v$datafile where con_id=8; NAME -------------------------------------------------------------------------------- /u01/app/oracle/oradata/C008/2215413A865F5166E0532902A8C03179/datafile/o1_mf_sys tem_c1x5pzy8_.dbf /u01/app/oracle/oradata/C008/2215413A865F5166E0532902A8C03179/datafile/o1_mf_sys aux_c1x5pzyq_.dbf /u01/app/oracle/oradata/C008/2215413A865F5166E0532902A8C03179/datafile/o1_mf_soe _c1x5pzz3_.dbf
As a final test we can get the amount of diskspace the PDB is currently being used. Eventually if all the blocks are changed in the PDB the clone PDB will be the same size of the parent so its a good idea to limit the amount of changes in the clone before refreshing.
du -sh 2215413A865F5166E0532902A8C03179 435M 2215413A865F5166E0532902A8C03179
With clonedb and dNFS its important to know which PDB is the parent since it can’t be dropped or open read/write until the child PDBs are dropped. For this reason there is a column in the v$pdbs called SNAPSHOT_PARENT_CON_ID. The snapped PDB has a con_id of 8 so its pretty easy to find out the parent with the following query.
<pre>
SQL> select SNAPSHOT_PARENT_CON_ID from v$pdbs where con_id=8;
SNAPSHOT_PARENT_CON_ID
———————-
7
</pre>
With this latest enhancement to clonedb and dNFS its possible to snapclone PDBs without the file system being capable of snap cloning itself.