Introduction
In a previous article we explored how to use the Oracle REMOTE CLONE PDB and the REFRESHABLE PDB functionalities to do a migration from Oracle Databases in Windows (on-prem or from other cloud providers) to Linux-based OCI Oracle Databases.
In that article we briefly discussed that these features can also be used when cloning a Non-CDB database into a PDB one.
Now we are going to look at the process of how to clone a Non-CDB into a PDB in more detail.
Prerequisites for CLONE
The prerequisites that apply are the same as the ones in the previous article : endianness, database options, database version -12.1.0.2 or higher for “Cold” Clone (Source DB open READ ONLY) or 12.2 or higher for Hot Clone-, character sets, open mode for the Source DB.
As we did in that article, we will be describing the HOT CLONE method since it does not interrupt the source database transactional activities during the process.
REMOTE HOT CLONE from Non-CDB to a PDB process
We are going to clone a non-CDB Oracle Database (Oracle 19.14 Standard Edition on Oracle Enterprise Linux Server 7.9) to a multitenant (CDB) Database system (Oracle 19.18 Enterprise Edition on Oracle Linux Server release 7.9). Note that the cloning can be done between Standard and Enterprise editions.
We check the Source DB system (non-CDB, Archive Log, Local Undo, Character Sets):
[oracle@calinstancedb19st ~]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on Wed Oct 18 14:22:27 2023
Version 19.14.0.0.0
Copyright (c) 1982, 2021, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production
Version 19.14.0.0.0
-- Check if Multitenant:
SQL> SELECT CDB FROM V$DATABASE;
CDB
---
NO
-- Archive Log:
SQL> ARCHIVE LOG LIST;
Database log mode Archive Mode
Automatic archival Enabled
Archive destination /u01/app/oracle/product/19c/dbhome_1/dbs/arch
Oldest online log sequence 49
Next log sequence to archive 51
Current log sequence 51
-- Local Undo
SQL> SELECT * FROM DATABASE_PROPERTIES WHERE PROPERTY_NAME='LOCAL_UNDO_ENABLED';
PROPERTY_NAME PROPERTY_VALUE DESCRIPTION
------------------ -------------- -----------------------------
LOCAL_UNDO_ENABLED TRUE true if local undo is enabled
-- Character sets:
SQL> SELECT VALUE FROM NLS_DATABASE_PARAMETERS
2 WHERE PARAMETER = 'NLS_CHARACTERSET';
VALUE
--------
AL32UTF8
SQL> SELECT VALUE FROM NLS_DATABASE_PARAMETERS
2 WHERE PARAMETER = 'NLS_NCHAR_CHARACTERSET';
VALUE
---------
AL16UTF16
SQL>
If any of the prerequisites is not met, we must change them (E.g: ALTER DATABASE ARCHIVELOG
) or consider to do a COLD CLONE instead (using ALTER DATABASE OPEN READ ONLY
).
Then we create the clone user in Source DB for the cloning process and GRANT CREATE SESSION
, CREATE PLUGGABLE DATABASE
to it.
-- Clone User.
SQL> CREATE USER CLONE_USER IDENTIFIED BY Oracle_123456;
User created.
SQL> GRANT CREATE SESSION, CREATE PLUGGABLE DATABASE TO CLONE_USER;
Grant succeeded.
SQL>
Now, we change to Target DB to check (Multitenant, Character Sets, Existing PDB’s):
[oracle@caldbcs3 ~]$ sqlplus / as sysdba
SQL*Plus: Release 19.0.0.0.0 - Production on Wed Oct 18 14:31:33 2023
Version 19.18.0.0.0
Copyright (c) 1982, 2022, Oracle. All rights reserved.
Connected to:
Oracle Database 19c EE High Perf Release 19.0.0.0.0 - Production
Version 19.18.0.0.0
-- Check if Multitenant:
SYS@CALDBCS3> SELECT CDB FROM V$DATABASE;
CDB
---
YES
-- Character sets:
SYS@CALDBCS3> SELECT VALUE FROM NLS_DATABASE_PARAMETERS
2 WHERE PARAMETER = 'NLS_CHARACTERSET';
VALUE
--------
AL32UTF8
SYS@CALDBCS3> SELECT VALUE FROM NLS_DATABASE_PARAMETERS
2 WHERE PARAMETER = 'NLS_NCHAR_CHARACTERSET';
VALUE
---------
AL16UTF16
-- PDBs:
SYS@CALDBCS3> SHOW PDBS;
CON_ID CON_NAME OPEN MODE RESTRICTED
------ ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
4 CALDBCS3_PDB1 READ WRITE NO
SYS@CALDBCS3>
Now we create the DBLink to the Source DB and connect with the clone user (don’t forget GLOBAL_NAMES
).
-- DBLink:
SYS@CALDBCS3> SHOW PARAMETER GLOBAL_NAMES;
NAME TYPE VALUE
------------ ----------- -----
global_names boolean TRUE
SYS@CALDBCS3> alter session set global_names=FALSE;
Session altered.
SYS@CALDBCS3> CREATE DATABASE LINK ORADB19ST_LINK
2 CONNECT TO CLONE_USER IDENTIFIED BY Oracle_123456
3 USING 'calinstancedb19st:1521/ORCL';
Database link created.
SYS@CALDBCS3> SELECT * FROM DUAL@ORADB19ST_LINK;
D
-
X
SYS@CALDBCS3>
We can now proceed with the CLONE PDB process. We must provide the password for the target TDE Wallet since Target DB is using TDE.
-- CREATE PDB (CLONE)
SYS@CALDBCS3> SHOW PDBS;
CON_ID CON_NAME OPEN MODE RESTRICTED
------ ------------- ---------- ----------
2 PDB$SEED READ ONLY NO
4 CALDBCS3_PDB1 READ WRITE NO
SYS@CALDBCS3> CREATE PLUGGABLE DATABASE CALDBCS3_PDB2
2 FROM ORCL@ORADB19ST_LINK
3 KEYSTORE IDENTIFIED BY ***************;
Pluggable database created.
SYS@CALDBCS3> SHOW PDBS;
CON_ID CON_NAME OPEN MODE RESTRICTED
------ ------------- ---------- ----------
2 PDB$SEED READ ONLY NO
3 CALDBCS3_PDB2 MOUNTED <-- MOUNTED
4 CALDBCS3_PDB1 READ WRITE NO
SYS@CALDBCS3>
The new PDB appears as MOUNTED.
Now is when we must convert it to a proper PDB executing the script noncdb_to_pdb.sql
. This step is done with the PDB in MOUNTED state.
-- noncdb_to_pdb.sql (in MOUNTED state)
SYS@CALDBCS3> ALTER SESSION SET CONTAINER=CALDBCS3_PDB2;
Session altered.
SYS@CALDBCS3> @$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql
SYS@CALDBCS3> SET FEEDBACK 1
SYS@CALDBCS3> SET NUMWIDTH 10
SYS@CALDBCS3> SET LINESIZE 80
SYS@CALDBCS3> SET TRIMSPOOL ON
SYS@CALDBCS3> SET TAB OFF
SYS@CALDBCS3> SET PAGESIZE 100
SYS@CALDBCS3> SET VERIFY OFF
SYS@CALDBCS3>
SYS@CALDBCS3> WHENEVER SQLERROR EXIT;
SYS@CALDBCS3>
SYS@CALDBCS3> DOC
DOC>#######################################################################
DOC>#######################################################################
DOC> The following statement will cause an "ORA-01403: no data found"
DOC> error if we're not in a PDB.
DOC> This script is intended to be run right after plugin of a PDB,
DOC> while inside the PDB.
DOC>#######################################################################
DOC>#######################################################################
DOC>#
SYS@CALDBCS3>
...<snipped>
SYS@CALDBCS3> alter session set "_enable_view_pdb"=false;
Session altered.
SYS@CALDBCS3>
SYS@CALDBCS3> -- leave the PDB in the same state it was when we started
SYS@CALDBCS3> BEGIN
2 execute immediate '&open_sql &restricted_state';
3 EXCEPTION
4 WHEN OTHERS THEN
5 BEGIN
6 IF (sqlcode <> -900) THEN
7 RAISE;
8 END IF;
9 END;
10 END;
11 /
PL/SQL procedure successfully completed.
SYS@CALDBCS3> SHOW PDBS;
CON_ID CON_NAME OPEN MODE RESTRICTED
------ ------------- ---------- ----------
2 PDB$SEED READ ONLY NO
3 CALDBCS3_PDB2 MOUNTED <-- MOUNTED
4 CALDBCS3_PDB1 READ WRITE NO
SYS@CALDBCS3>
The output is quite long (I’ve snipped it), but after a while we get the new PDB almost ready (and still in MOUNTED state).
If we try to open it now we get the «Warning: PDB altered with errors."
message and the RESTRICTED open mode because of the different patch level between Source DB and Target DB:
-- OPEN PDB:
SYS@CALDBCS3> SHOW PDBS;
CON_ID CON_NAME OPEN MODE RESTRICTED
------ ------------- ---------- ----------
2 PDB$SEED READ ONLY NO
3 CALDBCS3_PDB2 MOUNTED
4 CALDBCS3_PDB1 READ WRITE NO
SYS@CALDBCS3> ALTER PLUGGABLE DATABASE CALDBCS3_PDB2 OPEN;
Warning: PDB altered with errors.
SYS@CALDBCS3> SHOW PDBS;
CON_ID CON_NAME OPEN MODE RESTRICTED
------ ------------- ---------- ----------
2 PDB$SEED READ ONLY NO
3 CALDBCS3_PDB2 READ WRITE YES <-- RESTRICTED
4 CALDBCS3_PDB1 READ WRITE NO
SYS@CALDBCS3>
So, we must follow the usual path: check violations in PDB_PLUG_IN_VIOLATIONS and run datapatch
if required:
SYS@CALDBCS3> ALTER SESSION SET CONTAINER=CALDBCS3_PDB2;
Session altered.
SYS@CALDBCS3> SELECT status, type, cause, message
2 FROM pdb_plug_in_violations;
STATUS TYPE CAUSE
--------- --------- ---------
MESSAGE
---------------------------------------------------------
RESOLVED WARNING OPTION
Database option APS mismatch: PDB installed version NULL. CDB installed version 19.0.0.0.0.
RESOLVED WARNING OPTION
Database option DV mismatch: PDB installed version NULL. CDB installed version 19.0.0.0.0.
RESOLVED WARNING OPTION
Database option OLS mismatch: PDB installed version NULL. CDB installed version 19.0.0.0.0.
RESOLVED WARNING OPTION
Database option RAC mismatch: PDB installed version NULL. CDB installed version 19.0.0.0.0.
RESOLVED WARNING OPTION
Database option SDO mismatch: PDB installed version NULL. CDB installed version 19.0.0.0.0.
RESOLVED WARNING OPTION
Database option XOQ mismatch: PDB installed version NULL. CDB installed version 19.0.0.0.0.
RESOLVED ERROR Non-CDB to PDB
PDB plugged in is a non-CDB, requires noncdb_to_pdb.sql be run.
PENDING ERROR SQL Patch
Interim patch 34786990/25032666 (OJVM RELEASE UPDATE: 19.18.0.0.230117 (34786990)): Installed in the CDB but not in the PDB
PENDING ERROR SQL Patch
Interim patch 33561310/24538862 (OJVM RELEASE UPDATE: 19.14.0.0.220118 (33561310)): Not installed in the CDB but installed in the PDB
PENDING ERROR SQL Patch
'19.18.0.0.0 Release_Update 2301270055' is installed in the CDB but '19.14.0.0.0 Release_Update 2112251221' is installed in the PDB
PENDING WARNING is encrypted tablespace?
Tablespace SYSTEM is not encrypted. Oracle Cloud mandates all tablespaces should be encrypted.
PENDING WARNING is encrypted tablespace?
Tablespace SYSAUX is not encrypted. Oracle Cloud mandates all tablespaces should be encrypted.
PENDING WARNING is encrypted tablespace?
Tablespace USERS is not encrypted. Oracle Cloud mandates all tablespaces should be encrypted.
13 rows selected.
SYS@CALDBCS3> select cause, type, action
2 from pdb_plug_in_violations;
CAUSE
---------------------------------------------
TYPE
---------------------------------------------
ACTION
---------------------------------------------
OPTION
WARNING
Fix the database option in the PDB or the CDB
OPTION
WARNING
Fix the database option in the PDB or the CDB
OPTION
WARNING
Fix the database option in the PDB or the CDB
OPTION
WARNING
Fix the database option in the PDB or the CDB
OPTION
WARNING
Fix the database option in the PDB or the CDB
OPTION
WARNING
Fix the database option in the PDB or the CDB
Non-CDB to PDB
ERROR
Run noncdb_to_pdb.sql.
SQL Patch
ERROR
Call datapatch to install in the PDB or the CDB
SQL Patch
ERROR
Call datapatch to install in the PDB or the CDB
SQL Patch
ERROR
Call datapatch to install in the PDB or the CDB
is encrypted tablespace?
WARNING
Encrypt the tablespace.
is encrypted tablespace?
WARNING
Encrypt the tablespace.
is encrypted tablespace?
WARNING
Encrypt the tablespace.
13 rows selected.
SYS@CALDBCS3>
SYS@CALDBCS3> EXIT
Disconnected from Oracle Database 19c EE High Perf Release 19.0.0.0.0 - Production
Version 19.18.0.0.0
[oracle@caldbcs3 ~]$ cd $ORACLE_HOME/OPatch
[oracle@caldbcs3 OPatch]$ ./datapatch -verbose
SQL Patching tool version 19.18.0.0.0 Production on Wed Oct 18 15:18:25 2023
Copyright (c) 2012, 2023, Oracle. All rights reserved.
Log file for this invocation: /u01/app/oracle/cfgtoollogs/sqlpatch/sqlpatch_77286_2023_10_18_15_18_25/sqlpatch_invocation.log
Connecting to database...OK
Gathering database info...done
Note: Datapatch will only apply or rollback SQL fixes for PDBs
that are in an open state, no patches will be applied to closed PDBs.
Please refer to Note: Datapatch: Database 12c Post Patch SQL Automation
(Doc ID 1585822.1)
Bootstrapping registry and package to current versions...done
Determining current state...done
Current state of interim SQL patches:
Interim patch 33561310 (OJVM RELEASE UPDATE: 19.14.0.0.220118 (33561310)):
Binary registry: Not installed
PDB CALDBCS1_PDB1: Not installed
PDB CALDBCS3_PDB2: Applied successfully on 03-OCT-22 11.56.18.315748 AM
PDB CDB$ROOT: Not installed
PDB PDB$SEED: Not installed
Interim patch 33808367 (OJVM RELEASE UPDATE: 19.15.0.0.220419 (33808367)):
Binary registry: Not installed
PDB CALDBCS1_PDB1: Rolled back successfully on 25-JUL-23 10.30.05.591534 AM
PDB CALDBCS3_PDB2: Not installed
PDB CDB$ROOT: Rolled back successfully on 25-JUL-23 10.29.56.052091 AM
PDB PDB$SEED: Rolled back successfully on 25-JUL-23 10.30.00.836619 AM
Interim patch 34786990 (OJVM RELEASE UPDATE: 19.18.0.0.230117 (34786990)):
Binary registry: Installed
PDB CALDBCS1_PDB1: Applied successfully on 25-JUL-23 10.30.10.320358 AM
PDB CALDBCS3_PDB2: Not installed
PDB CDB$ROOT: Applied successfully on 25-JUL-23 10.30.00.815902 AM
PDB PDB$SEED: Applied successfully on 25-JUL-23 10.30.05.575750 AM
Current state of release update SQL patches:
Binary registry:
19.18.0.0.0 Release_Update 230127005551: Installed
PDB CALDBCS3_PDB1:
Applied 19.18.0.0.0 Release_Update 230127005551 successfully on 25-JUL-23 10.30.10.316032 AM
PDB CALDBCS3_PDB2:
Applied 19.14.0.0.0 Release_Update 211225122123 successfully on 03-OCT-22 11.56.18.309998 AM
PDB CDB$ROOT:
Applied 19.18.0.0.0 Release_Update 230127005551 successfully on 25-JUL-23 10.30.00.810350 AM
PDB PDB$SEED:
Applied 19.18.0.0.0 Release_Update 230127005551 successfully on 25-JUL-23 10.30.05.570170 AM
Adding patches to installation queue and performing prereq checks...done
Installation queue:
For the following PDBs: CDB$ROOT PDB$SEED CALDBCS1_PDB1
No interim patches need to be rolled back
No release update patches need to be installed
No interim patches need to be applied
For the following PDBs: CALDBCS3_PDB2
The following interim patches will be rolled back:
33561310 (OJVM RELEASE UPDATE: 19.14.0.0.220118 (33561310))
Patch 34765931 (DATABASE RELEASE UPDATE : 19.18.0.0.230117 (REL-JAN230131) (34765931)):
Apply from 19.14.0.0.0 Release_Update 211225122123 to 19.18.0.0.0 Release_Update 230127005551
The following interim patches will be applied:
34786990 (OJVM RELEASE UPDATE: 19.18.0.0.230117 (34786990))
WARNING: Following components are NOT in a valid state.
This could cause patching failure. If it does, consider
running utlrp.sql to bring components to VALID state.
Then, re-run datapatch.
CALDBCS3_PDB2 : CATPROC [INVALID], SDO [INVALID]
Installing patches...
Patch installation complete. Total patches installed: 3
Validating logfiles...done
Patch 33561310 rollback (pdb CALDBCS3_PDB2): SUCCESS
logfile: /u01/app/oracle/cfgtoollogs/sqlpatch/33561310/24538862/33561310_rollback_CALDBCS1_CALDBCS3_PDB2_2023Oct18_15_18_54.log (no errors)
Patch 34765931 apply (pdb CALDBCS3_PDB2): SUCCESS
logfile: /u01/app/oracle/cfgtoollogs/sqlpatch/34765931/25098466/34765931_apply_CALDBCS1_CALDBCS3_PDB2_2023Oct18_15_19_01.log (no errors)
Patch 34786990 apply (pdb CALDBCS3_PDB2): SUCCESS
logfile: /u01/app/oracle/cfgtoollogs/sqlpatch/34786990/25032666/34786990_apply_CALDBCS1_CALDBCS3_PDB2_2023Oct18_15_19_01.log (no errors)
SQL Patching tool complete on Wed Oct 18 15:21:22 2023
[oracle@caldbcs3 OPatch]$
If required, we recompile the objects running the sql script utlrp.sql
SYS@CALDBCS3> ALTER SESSION SET CONTAINER=CALDBCS3_PDB2;
Session altered.
SYS@CALDBCS3> @$ORACLE_HOME/rdbms/admin/utlrp.sql
Session altered.
TIMESTAMP
----------------------------------------------------------------------------------------------------
COMP_TIMESTAMP UTLRP_BGN 2023-10-18 15:22:58
DOC> The following PL/SQL block invokes UTL_RECOMP to recompile invalid
DOC> objects in the database. Recompilation time is proportional to the
DOC> number of invalid objects in the database, so this command may take
DOC> a long time to execute on a database with a large number of invalid
DOC> objects.
DOC>
DOC> Use the following queries to track recompilation progress:
DOC>
DOC> 1. Query returning the number of invalid objects remaining. This
DOC> number should decrease with time.
DOC> SELECT COUNT(*) FROM obj$ WHERE status IN (4, 5, 6);
DOC>
DOC> 2. Query returning the number of objects compiled so far. This number
DOC> should increase with time.
DOC> SELECT COUNT(*) FROM UTL_RECOMP_COMPILED;
DOC>
DOC> This script automatically chooses serial or parallel recompilation
DOC> based on the number of CPUs available (parameter cpu_count) multiplied
DOC> by the number of threads per CPU (parameter parallel_threads_per_cpu).
DOC> On RAC, this number is added across all RAC nodes.
DOC>
DOC> UTL_RECOMP uses DBMS_SCHEDULER to create jobs for parallel
DOC> recompilation. Jobs are created without instance affinity so that they
DOC> can migrate across RAC nodes. Use the following queries to verify
DOC> whether UTL_RECOMP jobs are being created and run correctly:
DOC>
DOC> 1. Query showing jobs created by UTL_RECOMP
DOC> SELECT job_name FROM dba_scheduler_jobs
DOC> WHERE job_name like 'UTL_RECOMP_SLAVE_%';
DOC>
DOC> 2. Query showing UTL_RECOMP jobs that are running
DOC> SELECT job_name FROM dba_scheduler_running_jobs
DOC> WHERE job_name like 'UTL_RECOMP_SLAVE_%';
DOC>#
PL/SQL procedure successfully completed.
TIMESTAMP
----------------------------------------------------------------------------------------------------
COMP_TIMESTAMP UTLRP_END 2023-10-18 15:22:58
DOC> The following query reports the number of invalid objects.
DOC>
DOC> If the number is higher than expected, please examine the error
DOC> messages reported with each object (using SHOW ERRORS) to see if they
DOC> point to system misconfiguration or resource constraints that must be
DOC> fixed before attempting to recompile these objects.
DOC>#
OBJECTS WITH ERRORS
-------------------
0
DOC> The following query reports the number of exceptions caught during
DOC> recompilation. If this number is non-zero, please query the error
DOC> messages in the table UTL_RECOMP_ERRORS to see if any of these errors
DOC> are due to misconfiguration or resource constraints that must be
DOC> fixed before objects can compile successfully.
DOC> Note: Typical compilation errors (due to coding errors) are not
DOC> logged into this table: they go into DBA_ERRORS instead.
DOC>#
ERRORS DURING RECOMPILATION
---------------------------
0
Function created.
PL/SQL procedure successfully completed.
Function dropped.
PL/SQL procedure successfully completed.
SYS@CALDBCS3>
Finally, we check, CLOSE and OPEN the new PDB and SAVE the STATE:
-- Check, CLOSE & OPEN:
SYS@CALDBCS3> ALTER SESSION SET CONTAINER=CDB$ROOT;
Session altered.
SYS@CALDBCS3> ALTER PLUGGABLE DATABASE CALDBCS3_PDB2 CLOSE IMMEDIATE;
Pluggable database altered.
SYS@CALDBCS3> ALTER PLUGGABLE DATABASE CALDBCS3_PDB2 OPEN;
Pluggable database altered.
SYS@CALDBCS3> SHOW PDBS;
CON_ID CON_NAME OPEN MODE RESTRICTED
------ ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 CALDBCS3_PDB2 READ WRITE NO
4 CALDBCS3_PDB1 READ WRITE NO
SYS@CALDBCS3>
-- SAVE STATE:
SYS@CALDBCS3> ALTER PLUGGABLE DATABASE CALDBCS3_PDB2 SAVE STATE;
Pluggable database altered.
SYS@CALDBCS3>
At this point we have the Non-CDB Source DB cloned into a full operational PDB (CALDBCS3_PDB2) in the Target CDB.
Cheers.
Carlos.