CloneDB in Oracle 12.1.0.2

I personally really like CloneDB, a way to thin-clone an Oracle database over NFS. This can be quite interesting, and I wanted to update my blog for 12.1.0.2.3 (April PSU). Tim Hall has a good example for 11.2.0.2 and later with further references.

My setup is as follows:

  • server3 (Oracle Linux 7.1) uses Oracle Restart and has database CDB1 registered. I would like to use this as the source for the clone
  • The backup I will take of CDB1 resides in /u01/oraback/CDB1
  • /u01/oraback is NFS-exported on server3 to server4 (Oracle Linux 7.1)
  • This directory is mounted on server4 as /u01/oraback
  • Oracle 12.1.0.2.3 (April 2015 PSU) is used throughout
  • The Oracle accounts on server3 and server4 have been created using the preinstall RPM, and have the same user and group IDs. You will find this important, and your Oracle installation standards document should enforce common user and group IDs not only for RAC where this is mandatory

Step 1: backing up CDB1

In the first step I am taking a full cold backup of CDB1. Data files are in ASM, and there is 1 PDB defined in the CDB. Here is the script I used for the backup:

[oracle@server3 ~]$ rman target /

Recovery Manager: Release 12.1.0.2.0 - Production on Tue Aug 4 11:15:11 2015

Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.

connected to target database: CDB1 (DBID=853309103, not open)

RMAN> run {
2> allocate channel c1 device type disk format '/u01/oraback/CDB1/%U';
3> allocate channel c2 device type disk format '/u01/oraback/CDB1/%U';
4> set nocfau;
5> backup as copy database;
6> }

allocated channel: c1
channel c1: SID=15 device type=DISK

allocated channel: c2
channel c2: SID=252 device type=DISK

executing command: SET NOCFAU

Starting backup at 04-AUG-15
channel c1: starting datafile copy
input datafile file number=00001 name=+DATA/CDB1/DATAFILE/system.273.879591527
...
Finished backup at 04-AUG-15
released channel: c1
released channel: c2

CloneDB requires me to provide the init.ora file as well, which I also place on the NFS mount (“create pfile=’/u01/oraback/CDB1/initCDB1.orig’ from spfile” does the trick)

That should be enough for now, I can resume work on server4.

Setup of server4

The first step is to ensure that dNFS is set up. Instead of repeating myself here I’ll simply link to a previous post where I explained how I did this for 12c. The actual line in /etc/fstab is this:

server3:/u01/oraback/   /u01/oraback    nfs     rw,bg,hard,nointr,tcp,vers=3,timeo=600,rsize=32768,wsize=32768 1 2

Check MOS and your NFS appliance vendor’s support site for your specific settings.

The oranfstab’s contents is shown here for reference:

[oracle@server4 lib]$ cat $ORACLE_HOME/dbs/oranfstab
server: server1
local: 192.168.100.13
path:  192.168.100.12
export: /u01/oraback mount: /u01/oraback

Prepare for cloning

The clonedb script requires a few environment variables to be set, as in this example:

export MASTER_COPY_DIR=/u01/oraback/CDB1
export CLONE_FILE_CREATE_DEST=/u01/oradata/CLONEDB
export CLONEDB_NAME=CLONEDB

The MASTER_COPY_DIR indicates where the backup resides, the CLONE_FILE_CREATE_DEST marks the directory where the CLONEDB data files are going to be located, and finally the CLONEDB_NAME is the database name.

With that in place, directories created and permissions set properly, it’s time to call the script, and here’s the first surprise:

[oracle@server4 ~]$ perl $ORACLE_HOME/rdbms/install/clonedb.pl
Missing braces on \o{} at /u01/app/oracle/product/12.1.0.2/dbhome_1/rdbms/install/clonedb.pl line 245, near "$lne' , '$clonedbdir"

I tried with $ORACLE_HOME/perl/bin/perl and the Oracle-Linux 7.1 version of perl and both showed the same behaviour (perl provided by the RDBMS home is v5.14.1, the default is v5.16.3). I corrected the script in line 245 and was able to produce the required scripts:

[oracle@server4 ~]$ $ORACLE_HOME/perl/bin/perl $ORACLE_HOME/rdbms/install/clonedb.pl \
> /u01/oraback/CDB1/initCDB1.orig /tmp/script1.sql /tmp/script2.sql

[oracle@server4 ~]$ cat /tmp/script1.sql

SET ECHO ON
SET FEEDBACK 1
SET NUMWIDTH 10
SET LINESIZE 80
SET TRIMSPOOL ON
SET TAB OFF
SET PAGESIZE 100

STARTUP NOMOUNT PFILE=/u01/oradata/CLONEDB/initCLONEDB.ora
CREATE CONTROLFILE REUSE SET DATABASE CLONEDB RESETLOGS
    MAXLOGFILES 32
    MAXLOGMEMBERS 2
    MAXINSTANCES 1
    MAXLOGHISTORY 908
LOGFILE
  GROUP 1 '/u01/oradata/CLONEDB/CLONEDB_log1.log' SIZE 100M BLOCKSIZE 512,
  GROUP 2 '/u01/oradata/CLONEDB/CLONEDB_log2.log' SIZE 100M BLOCKSIZE 512
DATAFILE
'/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-3_0mqdp1mb',
'/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-7_0oqdp1n5',
'/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-9_0nqdp1n5',
'/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-1_0lqdp1mb',
'/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-5_0rqdp1o4',
'/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-8_0qqdp1nl',
'/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-UNDOTBS1_FNO-4_0pqdp1nk',
'/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-USERS_FNO-10_0sqdp1o4',
'/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-USERS_FNO-6_0tqdp1oc'
CHARACTER SET WE8DEC;

[oracle@server4 ~]$ cat /tmp/script2.sql
declare
begin
dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-3_0mqdp1mb' , '/u01/oradata/CLONEDB//ora_data_CLONEDB0.dbf');
dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-7_0oqdp1n5' , '/u01/oradata/CLONEDB//ora_data_CLONEDB1.dbf');
dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-9_0nqdp1n5' , '/u01/oradata/CLONEDB//ora_data_CLONEDB2.dbf');
dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-1_0lqdp1mb' , '/u01/oradata/CLONEDB//ora_data_CLONEDB3.dbf');
dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-5_0rqdp1o4' , '/u01/oradata/CLONEDB//ora_data_CLONEDB4.dbf');
dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-8_0qqdp1nl' , '/u01/oradata/CLONEDB//ora_data_CLONEDB5.dbf');
dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-UNDOTBS1_FNO-4_0pqdp1nk' , '/u01/oradata/CLONEDB//ora_data_CLONEDB6.dbf');
dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-USERS_FNO-10_0sqdp1o4' , '/u01/oradata/CLONEDB//ora_data_CLONEDB7.dbf');
dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-USERS_FNO-6_0tqdp1oc' , '/u01/oradata/CLONEDB//ora_data_CLONEDB8.dbf');
end;
/
show errors;
alter database open resetlogs;
drop tablespace TEMP;
create temporary tablespace TEMP;[oracle@server4 ~]$

[oracle@server4 tmp]$ cat /u01/oradata/CLONEDB/initCLONEDB.ora
CDB1.__data_transfer_cache_size=0
CDB1.__db_cache_size=478150656
CDB1.__java_pool_size=4194304
CDB1.__large_pool_size=125829120
CDB1.__oracle_base='/u01/app/oracle'#ORACLE_BASE set from environment
CDB1.__pga_aggregate_target=268435456
CDB1.__sga_target=805306368
CDB1.__shared_io_pool_size=0
CDB1.__shared_pool_size=188743680
CDB1.__streams_pool_size=0
*.audit_file_dest='/u01/app/oracle/admin/CDB1/adump'
*.audit_trail='db'
*.compatible='12.1.0.2.0'
control_files=/u01/oradata/CLONEDB/CLONEDB_ctl.dbf
*.db_block_size=8192
*.db_create_file_dest='+DATA'
*.db_domain=''
db_name=CLONEDB
*.db_recovery_file_dest='+RECO'
*.db_recovery_file_dest_size=4560m

*.dispatchers='(PROTOCOL=TCP) (SERVICE=CDB1XDB)'
*.enable_pluggable_database=true
*.open_cursors=300
*.pga_aggregate_target=256m
*.processes=300
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=768m
*.undo_tablespace='UNDOTBS1'
db_create_file_dest=/u01/oradata/CLONEDB/
log_archive_dest=/u01/oradata/CLONEDB/
clonedb=TRUE

The scripts in that form won’t work- bear with me a second.

Fixing the scripts

First of all the init.ora script, it needs mending. The final initCLONEDB.ora, located in $CLONE_FILE_CREATE_DEST file looks like this (mandatory directories have to be created):

*.audit_file_dest='/u01/app/oracle/admin/CLONEDB/adump'
*.audit_trail='db'
*.compatible='12.1.0.2.0'
*.control_files=/u01/oradata/CLONEDB/CLONEDB_ctl.dbf
*.db_block_size=8192
*.db_domain=''
*.db_name=CLONEDB
*.db_recovery_file_dest='/u01/fra'
*.db_recovery_file_dest_size=4560m
*.dispatchers='(PROTOCOL=TCP) (SERVICE=CLONEDBXDB)'
*.enable_pluggable_database=true
*.open_cursors=300
*.pga_aggregate_target=256m
*.processes=300
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=768m
*.undo_tablespace='UNDOTBS1'
*.db_create_file_dest=/u01/oradata/CLONEDB/
*.log_archive_dest=/u01/oradata/CLONEDB/
*.clonedb=TRUE

I took out the ASM related parameters and made sure the FRA was usable. I also tidied everything up a little bit. Take a backup of this file, it will be overwritten next time you run clonedb.pl

Next check script1.sql for problems. I initially forgot to remove the reference to the init.ora I placed in /u01/oraback/CDB1 (I thought it was a good idea. It’s not):

SQL> @/tmp/script1
SQL> SET FEEDBACK 1
SQL> SET NUMWIDTH 10
SQL> SET LINESIZE 80
SQL> SET TRIMSPOOL ON
SQL> SET TAB OFF
SQL> SET PAGESIZE 100
SQL>
SQL> STARTUP NOMOUNT PFILE=/u01/oradata/CLONEDB/initCLONEDB.ora
ORACLE instance started.

Total System Global Area  805306368 bytes
Fixed Size                  2929552 bytes
Variable Size             318770288 bytes
Database Buffers          478150656 bytes
Redo Buffers                5455872 bytes
SQL> CREATE CONTROLFILE REUSE SET DATABASE CLONEDB RESETLOGS
  2      MAXLOGFILES 32
  3      MAXLOGMEMBERS 2
  4      MAXINSTANCES 1
  5      MAXLOGHISTORY 908
  6  LOGFILE
  7    GROUP 1 '/u01/oradata/CLONEDB/CLONEDB_log1.log' SIZE 100M BLOCKSIZE 512,
  8    GROUP 2 '/u01/oradata/CLONEDB/CLONEDB_log2.log' SIZE 100M BLOCKSIZE 512
  9  DATAFILE
 10  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-3_04qdogkp',
 11  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-7_06qdogmu',
 12  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-9_05qdogmq',
 13  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-1_03qdogkp',
 14  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-5_09qdogpr',
 15  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-8_08qdogon',
 16  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-UNDOTBS1_FNO-4_07qdogom',
 17  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-USERS_FNO-10_0aqdogpt',
 18  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-USERS_FNO-6_0bqdogqn',
 19  '/u01/oraback/CDB1/initCDB1.orig'
 20  CHARACTER SET WE8DEC;
CREATE CONTROLFILE REUSE SET DATABASE CLONEDB RESETLOGS
*
ERROR at line 1:
ORA-01503: CREATE CONTROLFILE failed
ORA-01565: error in identifying file '/u01/oraback/CDB1/initCDB1.orig'
ORA-17503: ksfdopn:7 Failed to open file /u01/oraback/CDB1/initCDB1.orig
ORA-27047: unable to read the header block of file
Additional information: 7
Additional information: 210592808
Additional information: 140184619486368

Took me 5 minutes to work out that there isn’t a problem with the pfile for starting the database. There is a problem with the reference to the pfile in line 19…

In a second attempt I was luckier.

[oracle@server4 CLONEDB]$ sqlplus / as sysdba

SQL*Plus: Release 12.1.0.2.0 Production on Tue Aug 4 16:09:50 2015

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

Connected to an idle instance.

SQL> @/tmp/script1
SQL> SET FEEDBACK 1
SQL> SET NUMWIDTH 10
SQL> SET LINESIZE 80
SQL> SET TRIMSPOOL ON
SQL> SET TAB OFF
SQL> SET PAGESIZE 100
SQL>
SQL> STARTUP NOMOUNT PFILE=/u01/oradata/CLONEDB/initCLONEDB.ora
ORACLE instance started.

Total System Global Area  805306368 bytes
Fixed Size                  2929552 bytes
Variable Size             318770288 bytes
Database Buffers          478150656 bytes
Redo Buffers                5455872 bytes
SQL> CREATE CONTROLFILE REUSE SET DATABASE CLONEDB RESETLOGS
  2      MAXLOGFILES 32
  3      MAXLOGMEMBERS 2
  4      MAXINSTANCES 1
  5      MAXLOGHISTORY 908
  6  LOGFILE
  7    GROUP 1 '/u01/oradata/CLONEDB/CLONEDB_log1.log' SIZE 100M BLOCKSIZE 512,
  8    GROUP 2 '/u01/oradata/CLONEDB/CLONEDB_log2.log' SIZE 100M BLOCKSIZE 512
  9  DATAFILE
 10  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-3_0mqdp1mb',
 11  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-7_0oqdp1n5',
 12  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-9_0nqdp1n5',
 13  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-1_0lqdp1mb',
 14  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-5_0rqdp1o4',
 15  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-8_0qqdp1nl',
 16  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-UNDOTBS1_FNO-4_0pqdp1nk',
 17  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-USERS_FNO-10_0sqdp1o4',
 18  '/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-USERS_FNO-6_0tqdp1oc'
 19  CHARACTER SET WE8DEC;

Control file created.

Elapsed: 00:00:02.22

Success! Now I need to continue with script2:

SQL> @/tmp/script2
SQL> declare
  2  begin
  3  dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-3_0mqdp1mb' , '/u01/oradata/CLONEDB//ora_data_CLONEDB0.dbf');
  4  dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-7_0oqdp1n5' , '/u01/oradata/CLONEDB//ora_data_CLONEDB1.dbf');
  5  dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSAUX_FNO-9_0nqdp1n5' , '/u01/oradata/CLONEDB//ora_data_CLONEDB2.dbf');
  6  dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-1_0lqdp1mb' , '/u01/oradata/CLONEDB//ora_data_CLONEDB3.dbf');
  7  dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-5_0rqdp1o4' , '/u01/oradata/CLONEDB//ora_data_CLONEDB4.dbf');
  8  dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-SYSTEM_FNO-8_0qqdp1nl' , '/u01/oradata/CLONEDB//ora_data_CLONEDB5.dbf');
  9  dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-UNDOTBS1_FNO-4_0pqdp1nk' , '/u01/oradata/CLONEDB//ora_data_CLONEDB6.dbf');
 10  dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-USERS_FNO-10_0sqdp1o4' , '/u01/oradata/CLONEDB//ora_data_CLONEDB7.dbf');
 11  dbms_dnfs.clonedb_renamefile('/u01/oraback/CDB1/data_D-CDB1_I-853309103_TS-USERS_FNO-6_0tqdp1oc' , '/u01/oradata/CLONEDB//ora_data_CLONEDB8.dbf');
 12  end;
 13  /

PL/SQL procedure successfully completed.

Elapsed: 00:00:04.05
SQL> show errors;
No errors.
SQL> alter database open resetlogs;

Database altered.

Elapsed: 00:00:22.60
SQL> drop tablespace TEMP;
drop tablespace TEMP
*
ERROR at line 1:
ORA-12906: cannot drop default temporary tablespace

Elapsed: 00:00:00.01
SQL> create temporary tablespace TEMP;
create temporary tablespace TEMP
*
ERROR at line 1:
ORA-01543: tablespace 'TEMP' already exists

Elapsed: 00:00:00.02

Not quite success but close. I added a temp file to the TEMP tablespace and was ready. A quick test revealed that I could open the PDB, too:

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PDB1                           MOUNTED
SQL> alter pluggable database PDB1 open;

Pluggable database altered.

Elapsed: 00:00:01.46
SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PDB1                           READ WRITE NO
SQL>

Sparse Files

The real beauty lies in the fact that I have space efficient snapshots:

SQL> select name from v$datafile;

NAME
--------------------------------------------------------------------------------
/u01/oradata/CLONEDB/ora_data_CLONEDB3.dbf
/u01/oradata/CLONEDB/ora_data_CLONEDB0.dbf
/u01/oradata/CLONEDB/ora_data_CLONEDB6.dbf
/u01/oradata/CLONEDB/ora_data_CLONEDB4.dbf
/u01/oradata/CLONEDB/ora_data_CLONEDB8.dbf
/u01/oradata/CLONEDB/ora_data_CLONEDB1.dbf
/u01/oradata/CLONEDB/ora_data_CLONEDB5.dbf
/u01/oradata/CLONEDB/ora_data_CLONEDB2.dbf
/u01/oradata/CLONEDB/ora_data_CLONEDB7.dbf

9 rows selected.

Elapsed: 00:00:00.01
SQL> !ls -lsh /u01/oradata/CLONEDB/
total 211M
   0 drwxr-x---. 4 oracle asmadmin   37 Aug  4 16:14 CLONEDB
8.9M -rw-r-----. 1 oracle asmadmin 8.9M Aug  4 16:16 CLONEDB_ctl.dbf
101M -rw-r-----. 1 oracle asmadmin 101M Aug  4 16:16 CLONEDB_log1.log
101M -rw-r-----. 1 oracle asmadmin 101M Aug  4 16:10 CLONEDB_log2.log
4.0K -rw-r--r--. 1 oracle oinstall  613 Aug  4 16:09 initCLONEDB.ora
4.0K -rw-r--r--. 1 oracle oinstall  613 Aug  4 16:00 initCLONEDB.ora.orig
460K -rw-r-----. 1 oracle asmadmin 761M Aug  4 16:15 ora_data_CLONEDB0.dbf
 64K -rw-r-----. 1 oracle asmadmin 491M Aug  4 16:10 ora_data_CLONEDB1.dbf
 64K -rw-r-----. 1 oracle asmadmin 521M Aug  4 16:15 ora_data_CLONEDB2.dbf
420K -rw-r-----. 1 oracle asmadmin 791M Aug  4 16:15 ora_data_CLONEDB3.dbf
 64K -rw-r-----. 1 oracle asmadmin 251M Aug  4 16:10 ora_data_CLONEDB4.dbf
 64K -rw-r-----. 1 oracle asmadmin 261M Aug  4 16:15 ora_data_CLONEDB5.dbf
540K -rw-r-----. 1 oracle asmadmin 361M Aug  4 16:15 ora_data_CLONEDB6.dbf
 64K -rw-r-----. 1 oracle asmadmin 201M Aug  4 16:15 ora_data_CLONEDB7.dbf
 64K -rw-r-----. 1 oracle asmadmin 5.1M Aug  4 16:10 ora_data_CLONEDB8.dbf

The first column in the output is the actual size on disk, for example 64k for ora_data_CLONEDB4.dbf. A “regular” ls output will show the file as 251M, reflected in the above output as well. It’s the original file size.

Advertisement