This post demonstrates how to clone the remote pluggable database from one CDB to another CDB using db link.
Here, we are cloning the pluggable database, PRODPDB1 from the root container database, PROD to DEV in the root container database, DEV.
Environment:
==========
Source CDB and PDB: PROD and PRODPDB1
Target CDB and PDB: DEV and DEVPDB2
Source and Target DB Version: 19.27
OS Version: Oracle Linux 9.4
1. Create a clone user in source pluggable database PRODPDB1 of CDB PROD.
This user is used for db link creation from target container database, DEV.
SQL> alter session set container=PRODPDB1;
Session altered.
SQL> create user cloneuser identified by cloneuser;
User created.
2. Grant create session and create pluggable database privileges to cloneuser of PRODPDB1 of CDB PROD.
SQL> show con_name
CON_NAME
——————————
PRODPDB1
SQL> grant create session, create pluggable database to cloneuser;
Grant succeeded.
SQL> select * from dba_sys_privs where grantee = ‘CLONEUSER’;
GRANTEE PRIVILEGE ADM COM INH
——— —————————————- — — —
CLONEUSER CREATE PLUGGABLE DATABASE NO NO NO
CLONEUSER CREATE SESSION NO NO NO
3. Create a test table and insert data to validate the data integrity after cloning PRODPDB1 from PROD to DEV.
SQL> show con_name
CON_NAME
——————————
PRODPDB1
SQL> create table PDBCLONETEST (c1 number);
Table created.
SQL> insert into PDBCLONETEST values(1);
1 row created.
SQL> commit;
Commit complete.
SQL> select * from PDBCLONETEST;
C1
———-
1
4. Find the data file locations of pluggable database PRODPDB1 of CDB PROD.
The datafile location path needs to be included in the file_name_convert parameter in the cloning script.
SQL> alter session set container=PRODPDB1;
Session altered.
SQL> select name from v$datafile;
NAME
——————————————————————————–
/u01/app/oracle/oradata/PROD/prodpdb1/system01.dbf
/u01/app/oracle/oradata/PROD/prodpdb1/sysaux01.dbf
/u01/app/oracle/oradata/PROD/prodpdb1/undotbs01.dbf
/u01/app/oracle/oradata/PROD/prodpdb1/users01.dbf
5. Close the PRODPDB1 in PROD.
SQL> select name,CDB from v$database;
NAME CDB
——— —
PROD YES
SQL> alter pluggable database PRODPDB1 close;
Pluggable database altered.
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
———- —————————— ———- ———-
2 PDB$SEED READ ONLY NO
3 PRODPDB1 MOUNTED
6. Open the PRODPDB1 at PROD in read only mode.
PRODPDB1 should be in READ ONLY mode for cloning
SQL> alter pluggable database PRODPDB1 open read only;
Pluggable database altered.
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
———- —————————— ———- ———-
2 PDB$SEED READ ONLY NO
3 PRODPDB1 READ ONLY NO
7. Login to Target Container Database, DEV.
SQL> show con_name
CON_NAME
——————————
CDB$ROOT
SQL> select name,CDB from v$database;
NAME CDB
——— —
DEV YES
8. Add the tnsentry of PRODPDB1 in tnsnames.ora of target server (DEV).
PRODPDB1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.166)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = prodpdb1)
)
)
[oracle@prod admin]$ tnsping PRODPDB1
TNS Ping Utility for Linux: Version 19.0.0.0.0 – Production on 21-AUG-2026 13:14:27
Copyright (c) 1997, 2025, Oracle. All rights reserved.
Used parameter files:
/u01/app/oracle/product/19.30/db/network/admin/sqlnet.ora
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.56.166)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = prodpdb1)))
OK (0 msec)
9. Create the database link in target database(DEV) to clone the PRODPDB1 from PROD to DEV database.
SQL> select name,cdb from v$database;
NAME CDB
———- —
DEV YES
SQL> create database link clone_prodpdb1 connect to cloneuser identified by cloneuser using ‘prodpdb1’;
Database link created.
Check the connectvity from DEB database to pluggable database PRODPDB1 of PROD CDB.
SQL> select * from dual@clone_prodpdb1;
D
–
X
[oracle@prod ~]$ sqlplus cloneuser/cloneuser@prodpdb1
SQL*Plus: Release 19.0.0.0.0 – Production on Fri Aug 21 15:40:52 2026
Version 19.27.0.0.0
Copyright (c) 1982, 2024, Oracle. All rights reserved.
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 – Production
Version 19.27.0.0.0
SQL> show con_name
CON_NAME
——————————
PRODPDB1
10. Run CREATE PLUGGABLE DATABASE command for cloning PRODPDB1. The new clone pluggable database DEVPDB2 will becreated in the DEV.
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
———- —————————— ———- ———-
2 PDB$SEED READ ONLY NO
3 DEVPDB1 READ WRITE NO
SQL> create pluggable database devpdb2 from prodpdb1@clone_prodpdb1 file_name_convert=(‘/u01/app/oracle/oradata/PROD/prodpdb1/’,’/u01/app/oracle/oradata/DEV/devpdb2′);
Pluggable database created.
SQL> show pdbs
CON_ID CON_NAME OPEN MODE RESTRICTED
———- —————————— ———- ———-
2 PDB$SEED READ ONLY NO
3 DEVPDB1 READ WRITE NO
4 DEVPDB2 MOUNTED
SQL> alter pluggable database DEVPDB2 open;
Pluggable database altered.
11. Check the data integrity. Connect to newly cloned DEVPDB2.
SQL> alter session set container=DEVPDB2;
Session altered.
SQL> show con_name
CON_NAME
——————————
DEVPDB2
SQL> select * from PDBCLONETEST;
C1
———-
1
Disclaimer:
Please note the above information is only for educational purpose and practised in personal test database only. Always test in test database before implementing in production database. The pre-requisites and ways of implementing may vary from one environment to another. Hence, not providing guarantee that it will work in your environment.