Oracle 12c

Oracle database 12c related posts

Configure Oracle 12c Dataguard Physical Standby

Oracle dataguard physical standby

Description:

In this post I will describe the step by step configuration of Oracle 12c Dataguard physical standby setup with dataguard broker(DGMGRL) on Oracle Linux 7

EnvironmentDB_NameDB_Unique_name
Primarycdb12ccdb12c
Standbycdb12ccdb12cdr

We will be covering the following steps:

Primary Server setup

  1. Enable archive log mode
  2. Enable Force logging
  3. Create standby redologs SRLs
  4. Check db_name and db_unique_name
  5. Set standby_file_management
  6. TNS and listener Setup
  7. Copy pfile and password to standby

Standby Server setup

  1. Modify the pfile
  2. Create necessary directories
  3. Create standby database using RMAN Duplicate

Configure Dataguard broker

  1. Enable dataguard broker
  2. Register the database with dataguard broker
  3. Add standby database to dataguard broker
  4. Enable configuration

Primary Server setup

1. Enable archive log mode

Ensure the primary database is in archivelog mode. If not enable it.

alter system set log_archive_dest_1='LOCATION=/u01/app/oracle/arch';
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;
2. Enable force logging:

Make sure Force logging is enabled on the database.

ALTER DATABASE FORCE LOGGING;
ALTER SYSTEM SWITCH LOGFILE;
3. Create standby redo logs on the primary database

Create the standby redo logs to support standby role. The recommended number of SRLs is (Number of redologs + 1). The SRLs size must be same as online redo logs size.

ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 12 ('/u01/oradata/dev12c/std_redo12.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 13 ('/u01/oradata/dev12c/std_redo13.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 14 ('/u01/oradata/dev12c/std_redo14.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 15 ('/u01/oradata/dev12c/std_redo15.log') SIZE 200M;
4. Check pfile for db_name and db_unique_name

Make sure primary database has DB_UNIQUE_NAME set. If not set it using ALTER SYSTEM SET command.

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_name                              string      dev12c
SQL> show parameter unique

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_unique_name                       string      dev12c
SQL>
5. Set STANDBY_FILE_MANAGEMENT to AUTO
ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO;
6. TNS and LISTENER setup(for both primary & standby)

Tnsnames configuration:

DEV12C =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = ol7-db.localdomain)(PORT = 1522))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = dev12c)
    )
  )

DEV12CDR =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = ol7-db-dr.localdomain)(PORT = 1522))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = dev12c)
    )
  )


LISTENER_DEV12C =
  (ADDRESS = (PROTOCOL = TCP)(HOST = ol7-db.localdomain)(PORT = 1522))
Listener.ora configuration
LISTENER12C =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = ol7-db.localdomain)(PORT = 1522))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1522))
    )
  )

SID_LIST_LISTENER12C =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = dev12c_DGMGRL)
      (ORACLE_HOME = /u01/app/oracle/product/12.2.0/dbhome_1)
      (SID_NAME = dev12c)
    )
  )
Restart the listener(On both primary & standby)
lsnrctl stop listener12c
lsnrctl start listener12c
7. Copy pfile and password file to standby server
create pfile='/tmp/initdev12c.ora' from spfile;
scp initdev12c.ora oracle@ol7-db-dr:/tmp
scp $ORACLE_HOME/dbs/orapwdev12c oracle@ol7-db-dr:/u01/app/oracle/product/12.2.0/dbhome_1/dbs

Standby Server setup

1. modify the pfile copied from primary and make change for the below parameters
*.db_name=dev12c
*.db_unique_name=dev12cdr
enable_pluggable_database=true
log_file_name_convert='dummy','dummy'
2. Create the necessary directories
mkdir -p /u01/app/oracle/admin/dev12c/adump
mkdir -p /u01/oradata/dev12c/pdbseed
mkdir -p /u01/oradata/dev12c/pdb12c
mkdir -p /u01/app/oracle/fra
mkdir -p /u01/app/oracle/arch
3. Create standby using RMAN DUPLICATE

Start the auxiliary database instance using the pfile

export ORACLE_SID=dev12c
sqlplus "/as sysdba"
startup nomount pfile='/u01/initdev12c.ora';

Connect to RMAN and issue the duplicate command,

rman target sys/idgroup@dev12c auxiliary sys/idgroup@dev12cdr
DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE DORECOVER NOFILENAMECHECK;

Configure Datagurar Broker

1. Enable dataguard broker on both primary & standby
ALTER SYSTEM SET dg_broker_start=true;
2. On primary side: register the database with dataguard broker
dgmgrl sys/idgroup@dev12c
create configuration dgconfig as primary database is dev12c connect identifier is dev12c;

o/p:
[oracle@ol7-db admin]$ dgmgrl sys/idgroup@dev12c
DGMGRL for Linux: Release 12.2.0.1.0 - Production on Sat Jul 17 12:25:24 2021

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

Welcome to DGMGRL, type "help" for information.
Connected to "dev12c"
Connected as SYSDBA.
DGMGRL>
DGMGRL> create configuration dgconfig as primary database is dev12c connect identifier is dev12c;
Configuration "dgconfig" created with primary database "dev12c"
DGMGRL>
3. On primary side: add the standby database
add database dev12cdr as connect identifier is dev12cdr maintained as physical;

o/p:
DGMGRL> add database dev12cdr as connect identifier is dev12cdr maintained as physical;
Database "dev12cdr" added
DGMGRL>
4. On Primary side: enable the configuration
enable configuration;

o/p:
DGMGRL> enable configuration;
Enabled.
DGMGRL>

Check the configuration

DGMGRL> show configuration

Configuration - dgconfig

  Protection Mode: MaxPerformance
  Members:
  dev12c   - Primary database
    dev12cdr - Physical standby database

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS   (status updated 41 seconds ago)
DGMGRL>
DGMGRL> show database dev12c

Database - dev12c

  Role:               PRIMARY
  Intended State:     TRANSPORT-ON
  Instance(s):
    dev12c

Database Status:
SUCCESS

DGMGRL>
DGMGRL> show database dev12cdr

Database - dev12cdr

  Role:               PHYSICAL STANDBY
  Intended State:     APPLY-ON
  Transport Lag:      0 seconds (computed 1 second ago)
  Apply Lag:          0 seconds (computed 1 second ago)
  Average Apply Rate: 1.00 KByte/s
  Real Time Query:    OFF
  Instance(s):
    dev12c

Database Status:
SUCCESS

DGMGRL>

Hope this helps…

ORA-16853: apply lag has exceeded specified threshold

I got the below error in one of my standby environment. Error – ORA-16853: apply lag has exceeded specified threshold

DGMGRL> show database dev12cdr

Database - dev12cdr

  Role:               PHYSICAL STANDBY
  Intended State:     APPLY-ON
  Transport Lag:      4 minutes 37 seconds (computed 32 seconds ago)
  Apply Lag:          4 minutes 37 seconds (computed 32 seconds ago)
  Average Apply Rate: (unknown)
  Real Time Query:    OFF
  Instance(s):
    dev12c

  Database Warning(s):
    ORA-16853: apply lag has exceeded specified threshold

Database Status:
WARNING

DGMGRL>

Cause: This is due the Apply Lag Threshold. Check and modify the dataguard configuration parameter ApplyLagThreshold.

Solution: Modify the ApplyLagThreshold parameter in database configuration

show database verbose dev12cdr;
edit database dev12cdr set property ApplyLagThreshold=3600;

ORA-16857: member disconnected from redo source for longer than specified threshold

In one of my dataguard environment I got the Error: ORA-16857: member disconnected from redo source for longer than specified threshold

DGMGRL> show database dev12cdr;

Database - dev12cdr

  Role:               PHYSICAL STANDBY
  Intended State:     APPLY-ON
  Transport Lag:      1 minute 39 seconds (computed 1 second ago)
  Apply Lag:          3 minutes 51 seconds (computed 1 second ago)
  Average Apply Rate: 2.00 KByte/s
  Real Time Query:    OFF
  Instance(s):
    dev12c

  Database Warning(s):
    ORA-16857: member disconnected from redo source for longer than specified threshold

Database Status:
WARNING

DGMGRL>

Solution 1:

The size of Online Redo logs (ORLs) and Standby Redo Logs(SRLs) are different on both primary and standby databases

On Standy:

SQL> select GROUP#,THREAD#,BYTES/1024/1024 from v$log;

    GROUP#    THREAD# BYTES/1024/1024
---------- ---------- ---------------
         1          1             200
         2          1             200
         3          1             200

SQL>  select GROUP#,THREAD# ,BYTES/1024/1024, status from v$standby_log;

    GROUP#    THREAD# BYTES/1024/1024 STATUS
---------- ---------- --------------- ----------
         8          1              50 UNASSIGNED
         9          1              50 UNASSIGNED
        10          1              50 UNASSIGNED
        11          1              50 UNASSIGNED

On Primary:

SQL> select GROUP#,THREAD#,BYTES/1024/1024 from v$log;

    GROUP#    THREAD# BYTES/1024/1024
---------- ---------- ---------------
         1          1             200
         3          1             200
         2          1             200

SQL>  select GROUP#,THREAD# ,BYTES/1024/1024, status from v$standby_log;

    GROUP#    THREAD# BYTES/1024/1024 STATUS
---------- ---------- --------------- ----------
         8          1              50 UNASSIGNED
         9          1              50 UNASSIGNED
        10          1              50 UNASSIGNED
        11          1              50 UNASSIGNED

Drop all standby redologs from both primary and standby and recreate with the same size.

On Primary:

--add the SRLs with the same size as ORLs
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 12 ('/u01/oradata/dev12c/std_redo12.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 13 ('/u01/oradata/dev12c/std_redo13.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 14 ('/u01/oradata/dev12c/std_redo14.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 15 ('/u01/oradata/dev12c/std_redo15.log') SIZE 200M;

--drop the old SRLs
SQL> alter database drop standby logfile group 8;
SQL> alter database drop standby logfile group 9;
SQL> alter database drop standby logfile group 10;
alter database drop standby logfile group 11;

On Standby:

--stop the managed recovery
alter database recover managed standby database cancel;

--add the SRLs with the same size as ORLs
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 12 ('/u01/oradata/dev12c/std_redo12.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 13 ('/u01/oradata/dev12c/std_redo13.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 14 ('/u01/oradata/dev12c/std_redo14.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 15 ('/u01/oradata/dev12c/std_redo15.log') SIZE 200M;

--drop the old SRLs
SQL> alter database drop standby logfile group 8;
SQL> alter database drop standby logfile group 9;
SQL> alter database drop standby logfile group 10;
alter database drop standby logfile group 11;

--Start the managed recovery
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE THROUGH ALL SWITCHOVER DISCONNECT USING CURRENT LOGFILE;

Solution 2:

Modify the value of TransportDisconnectedThreshold, if  a  delay in the redo transport is expected.

Default value is 30 Seconds

EDIT DATABASE dev12c SET PROPERTY TransportDisconnectedThreshold='150';

After making the changes check the dataguard status

DGMGRL> show database dev12cdr;

Database - dev12cdr

  Role:               PHYSICAL STANDBY
  Intended State:     APPLY-ON
  Transport Lag:      2 minutes 39 seconds (computed 16 seconds ago)
  Apply Lag:          4 minutes 51 seconds (computed 16 seconds ago)
  Average Apply Rate: 2.00 KByte/s
  Real Time Query:    OFF
  Instance(s):
    dev12c

Database Status:
SUCCESS

DGMGRL>

ORACLE error from auxiliary database: ORA-19527: physical standby redo log must be renamed

On standby side, you may encountered the Error “ORACLE error from auxiliary database: ORA-19527: physical standby redo log must be renamed” while restoring a standby database from using duplicate command

Finished recover at 17-JUL-21
ORACLE error from auxiliary database: ORA-19527: physical standby redo log must be renamed
ORA-00312: online log 1 thread 1: '/u01/oradata/dev12c/redo01.log'

RMAN-05535: warning: All redo log files were not defined properly.
ORACLE error from auxiliary database: ORA-19527: physical standby redo log must be renamed
ORA-00312: online log 2 thread 1: '/u01/oradata/dev12c/redo02.log'

RMAN-05535: warning: All redo log files were not defined properly.
ORACLE error from auxiliary database: ORA-19527: physical standby redo log must be renamed
ORA-00312: online log 3 thread 1: '/u01/oradata/dev12c/redo03.log'

RMAN-05535: warning: All redo log files were not defined properly.
ORACLE error from auxiliary database: ORA-19527: physical standby redo log must be renamed
ORA-00312: online log 8 thread 1: '/u01/oradata/dev12c/std_redo01.log'

RMAN-05535: warning: All redo log files were not defined properly.
ORACLE error from auxiliary database: ORA-19527: physical standby redo log must be renamed
ORA-00312: online log 9 thread 1: '/u01/oradata/dev12c/std_redo02.log'

RMAN-05535: warning: All redo log files were not defined properly.
ORACLE error from auxiliary database: ORA-19527: physical standby redo log must be renamed
ORA-00312: online log 10 thread 1: '/u01/oradata/dev12c/std_redo03.log'

RMAN-05535: warning: All redo log files were not defined properly.
ORACLE error from auxiliary database: ORA-19527: physical standby redo log must be renamed
ORA-00312: online log 11 thread 1: '/u01/oradata/dev12c/std_redo04.log'

RMAN-05535: warning: All redo log files were not defined properly.
Finished Duplicate Db at 17-JUL-21

Solution:

Add the below parameter in the pfile file and then re-run the duplicate database command.

log_file_name_convert='dummy','dummy'

Re-run the Duplciate database command

DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE DORECOVER NOFILENAMECHECK;

Output:

RMAN> DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE DORECOVER NOFILENAMECHECK;

Starting Duplicate Db at 17-JUL-21
using target database control file instead of recovery catalog
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=35 device type=DISK
current log archived
.
.
<output truncated>
.
.
archived log file name=/u01/app/oracle/product/12.2.0/dbhome_1/dbs/arch1_17_1066823600.dbf thread=1 sequence=17
media recovery complete, elapsed time: 00:00:00
Finished recover at 17-JUL-21
Finished Duplicate Db at 17-JUL-21

RMAN>

Check the redo logs are created:

[oracle@ol7-db-dr dev12c]$ pwd
/u01/oradata/dev12c
[oracle@ol7-db-dr dev12c]$ ls -ltrh *.log
-rw-r-----. 1 oracle oinstall 201M Jul 17 12:09 redo01.log
-rw-r-----. 1 oracle oinstall 201M Jul 17 12:09 redo02.log
-rw-r-----. 1 oracle oinstall 201M Jul 17 12:09 redo03.log
-rw-r-----. 1 oracle oinstall  51M Jul 17 12:09 std_redo01.log
-rw-r-----. 1 oracle oinstall  51M Jul 17 12:09 std_redo02.log
-rw-r-----. 1 oracle oinstall  51M Jul 17 12:09 std_redo03.log
-rw-r-----. 1 oracle oinstall  51M Jul 17 12:09 std_redo04.log
[oracle@ol7-db-dr dev12c]$

Hope this helps…

ORA-19527: physical standby redo log must be renamed

On standby side, you may encountered the Error “ORA-19527: physical standby redo log must be renamed” in the alert log.

ORA-19527: physical standby redo log must be renamed
ORA-00312: online log 10 thread 1: '/u01/oradata/dev12c/std_redo03.log'

Though this didn’t stop the data guard replication, we need to get rid of this error message. It seems to be false alarm in DR alert log.

Solution: If there is no difference in the directory structure in Primary and standby, you can get rid of this message by modifying the log_file_name_convert parameter to a dummy Value

ALTER SYSTEM SET log_file_name_convert='dummy','dummy';

After the parameter was set, the ORA message was no longer seen in the alert.log

Reference: ORA-19527: Physical Standby Redo Log Must Be Renamed…during switchover (Doc ID 2194825.1)

Enable Flashback Database on Oracle 12c

In this article we will describe the step by step instructions on how to enable flashback on Oracle 12c database

  1. Enable ARCHIVELOG mode:
SQL> select log_mode from v$database;

LOG_MODE
------------
NOARCHIVELOG

If the database is in NOARCHIVELOG mode, Enable it

alter system set log_archive_dest_1='LOCATION=/u01/app/oracle/arch';
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;

Check the Database ARCHIVELOG status

SQL> select log_mode from v$database;

LOG_MODE
------------
ARCHIVELOG

2. Set the DB_RECOVERY_FILE_DEST_SIZE and DB_RECOVERY_FILE_DEST

alter system set DB_RECOVERY_FILE_DEST_SIZE=10G;
alter system set DB_RECOVERY_FILE_DEST='/u01/app/oracle/fra';

3. Enable FLASHBACK database

ALTER DATABASE FLASHBACK ON;

4. Check the FLASHBACK database status

SQL> select flashback_on from v$database;

FLASHBACK_ON
------------------
YES

Hope this helps..

ORA-19802: cannot use DB_RECOVERY_FILE_DEST without DB_RECOVERY_FILE_DEST_SIZE

You might encounter ORA-19802 error while setting DB_RECOVERY_FILE_DEST

Error:

SQL> alter system set db_recovery_file_dest='/u01/app/oracle/fra';
alter system set db_recovery_file_dest='/u01/app/oracle/fra'
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-19802: cannot use DB_RECOVERY_FILE_DEST without DB_RECOVERY_FILE_DEST_SIZE

Solution:

First set the DB_RECOVERY_FILE_DEST_SIZE parameter, then set the DB_RECOVERY_FILE_DEST

SQL> alter system set DB_RECOVERY_FILE_DEST_SIZE=10G;

System altered.

SQL> alter system set DB_RECOVERY_FILE_DEST='/u01/app/oracle/fra';

System altered.

ORA-16179: incremental changes to “log_archive_dest_1” not allowed with SPFILE

You might encounter ORA-16179 error during updating the archive log destination.

Error Details:

SQL> alter system set log_archive_dest_1='/u01/app/oracle/arch';
alter system set log_archive_dest_1='/u01/app/oracle/arch'
*
ERROR at line 1:
ORA-32017: failure in updating SPFILE
ORA-16179: incremental changes to "log_archive_dest_1" not allowed with SPFILE

Solution:

SQL> alter system set log_archive_dest_1='LOCATION=/u01/app/oracle/arch';

System altered.

Unplug and Plugin Pluggable database (PDB)

Unplug and plugin pdb

Oracle has introduced new Multitenant Option from Oracle 12cR1 and this option allows a single container database (CDB) to host multiple pluggable databases.

One of the most powerful feature of Oracle Multitenant is Unplug and Plug In a PDB from one CDB to another CDB.

Refer here for more details on Oracle Multitenant option.

Description:

In this post I will describe how to Unplug and Plugin a PDB from one CDB to another CDB in Oracle 12c. Here I have used 2 CDBs running on the same VM. Below are the details,

Source CDB: CDB2 –> Unplug pdb_db2 from cdb2
Target CDB: CDB1 –> Plug pdb_db2 to cdb1

SQL> select d.name db_name, p.name pdb_name, p.open_Mode from v$pdbs p, v$database d;

DB_NAME   PDB_NAME        OPEN_MODE
--------- --------------- ----------
CDB2      PDB$SEED        READ ONLY
CDB2      PDB1            READ WRITE
CDB2      PDB2            READ WRITE
CDB2      PDB3            READ WRITE
CDB2      PDB_DB2_NEW     READ WRITE
CDB2      PDB_DB2         READ WRITE

SQL> select d.name db_name, p.name pdb_name, p.open_Mode from v$pdbs p, v$database d;

DB_NAME   PDB_NAME        OPEN_MODE
--------- --------------- ----------
CDB1      PDB$SEED        READ ONLY
CDB1      PDB1            READ WRITE

In the below example I will unplug pdb_db2 from CDB2 and plugin to CDB1.

Below are the steps:

Unplug the PDB from CDB
  1. Connect to the source CDB ( as sysdba)
  2. Close the PDB to unplug
  3. Unplug the PDB
  4. Drop the PDB pdb_db2 by preserving the datafiles
  5. Verify the status of the unplugged PDB

Plug In the PDB to CDB

  1. Connect to the target CDB ( as sysdba)
  2. Run DBMS_PDB.CHECK_PLUG_COMPATIBILITY Function
  3. Plug In the PDB using the metadata (xml) file
  4. Open the PDB database

Unplugging the PDB pdb_db2 from CDB cdb2

  1. Connect to the source CDB ( as sysdba)

Set the DB Environment to connect source CDB and connect to CDB$ROOT using sysdba privilege

[oracle@cdb12c ~]$ . oraenv
ORACLE_SID = [cdb2] ?
The Oracle base remains unchanged with value /u01/app/oracle
[oracle@cdb12c ~]$ sqlplus

SQL*Plus: Release 12.2.0.1.0 Production on Thu Feb 11 03:44:53 2021

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

Enter user-name: /as sysdba

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> show con_name;

CON_NAME
------------------------------
CDB$ROOT
SQL>

2. Close the PDB(pdb_db2) to unplug

Before unplugging, the pdb has to be closed.

select name, open_mode from v$pdbs;
alter pluggable database pdb_db2 close;

o/p:
SQL> select name, open_mode from v$pdbs;

NAME            OPEN_MODE
--------------- ----------
PDB$SEED        READ ONLY
PDB1            READ WRITE
PDB2            READ WRITE
PDB3            READ WRITE
PDB_DB2_NEW     READ WRITE
PDB_DB2         READ WRITE

6 rows selected.

SQL> alter pluggable database pdb_db2 close immediate;

Pluggable database altered.

3. Unplug the PDB

Unplug the closed PDB and then specify the path and name of the XML file.

alter pluggable database pdb_db2 unplug into '/u01/pdb_clone/pdb_db2.xml';
select name, open_mode from v$pdbs;

o/p:
SQL> alter pluggable database pdb_db2 unplug into '/u01/pdb_clone/pdb_db2.xml';

Pluggable database altered.

SQL> select name, open_mode from v$pdbs;

NAME            OPEN_MODE
--------------- ----------
PDB$SEED        READ ONLY
PDB1            READ WRITE
PDB2            READ WRITE
PDB3            READ WRITE
PDB_DB2_NEW     READ WRITE
PDB_DB2         MOUNTED

6 rows selected.

4. Drop the PDB pdb_db2 by preserving the datafiles

Drop the closed PDB and keep the data files.
Specify KEEP DATAFILES to retain the data files associated with the PDB after the PDB is dropped. The temp file for the PDB is deleted because it is no longer needed. This is the default.

drop pluggable database pdb_db2 keep datafiles;
select name, open_mode from v$pdbs;

o/p:

SQL> drop pluggable database pdb_db2 keep datafiles;

Pluggable database dropped.

SQL>
SQL> select name, open_mode from v$pdbs;

NAME            OPEN_MODE
--------------- ----------
PDB$SEED        READ ONLY
PDB1            READ WRITE
PDB2            READ WRITE
PDB3            READ WRITE
PDB_DB2_NEW     READ WRITE

5. Verify the status of the unplugged PDB

select name, open_mode from v$pdbs where name ='PDB_DB2';

SQL> select name, open_mode from v$pdbs where name ='PDB_DB2';

no rows selected

Successfully unplugged the PDB pdb_db2 from CDB cdb2, Now let see how to plug this PDB to CDB1.

Plug In the PDB pdb_db2 to CDB1

  1. Connect to the target CDB ( as sysdba)

Set the environment variable of target CDB and connect to CDB$ROOT as sysdba

.oraenv
sqlplus "/as sysdba"
show con_name

o/p:

[oracle@cdb12c admin]$ . oraenv
ORACLE_SID = [cdb2] ? cdb1
The Oracle base remains unchanged with value /u01/app/oracle
[oracle@cdb12c admin]$ sqlplus

SQL*Plus: Release 12.2.0.1.0 Production on Thu Feb 11 04:12:40 2021

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

Enter user-name: /as sysdba

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> show con_name

CON_NAME
------------------------------
CDB$ROOT
SQL>

2. Run DBMS_PDB.CHECK_PLUG_COMPATIBILITY Function

Before Plug In the database make sure the unplugged PDB is compatible with the new host.

SET SERVEROUTPUT ON
DECLARE
 compatible CONSTANT VARCHAR2(3) :=
  CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY(
      pdb_descr_file => '/u01/pdb_clone/pdb_db2.xml',
      pdb_name => 'pdb_db2')
  WHEN TRUE THEN 'YES'
  ELSE 'NO'
END;
BEGIN
 DBMS_OUTPUT.PUT_LINE(compatible);
END;
/

o/p:
SQL> SET SERVEROUTPUT ON
DECLARE
 compatible CONSTANT VARCHAR2(3) :=
  CASE DBMS_PDB.CHECK_PLUG_COMPATIBILITY(
      pdb_descr_file => '/u01/pdb_clone/pdb_db2.xml',
      pdb_name => 'pdb_db2')
  WHEN TRUE THEN 'YES'
  ELSE 'NO'
END;
BEGIN
 DBMS_OUTPUT.PUT_LINE(compatible);
END;
/
YES

PL/SQL procedure successfully completed.

3. Plug In the PDB using the metadata (xml) file

create pluggable database pdb_db2 using '/u01/pdb_clone/pdb_db2.xml' NOCOPY TEMPFILE REUSE;
select con_id, name, open_mode from v$pdbs;
select name from v$datafile where con_id=4;

o/p:

SQL> create pluggable database pdb_db2 using '/u01/pdb_clone/pdb_db2.xml' NOCOPY TEMPFILE REUSE;

Pluggable database created.

SQL>
SQL> select con_id, name, open_mode from v$pdbs;

    CON_ID NAME            OPEN_MODE
---------- --------------- ----------
         2 PDB$SEED        READ ONLY
         3 PDB1            READ WRITE
         4 PDB_DB2         MOUNTED

SQL> select name from v$datafile where con_id=4;

NAME
------------------------------------------------
/u01/app/oracle/oradata/cdb2/pdb_db2/CDB2/B92E25114D543C30E053D138A8C0059C/datafile/o1_mf_system_j0c54z1f_.dbf
/u01/app/oracle/oradata/cdb2/pdb_db2/CDB2/B92E25114D543C30E053D138A8C0059C/datafile/o1_mf_sysaux_j0c54z1o_.dbf
/u01/app/oracle/oradata/cdb2/pdb_db2/CDB2/B92E25114D543C30E053D138A8C0059C/datafile/o1_mf_undotbs1_j0c54z1o_.dbf
/u01/app/oracle/oradata/cdb2/pdb_db2/CDB2/B92E25114D543C30E053D138A8C0059C/datafile/o1_mf_users_j0c54z1p_.dbf

4. Open the PDB database

Open and check the status of the plugged PDB.

alter pluggable database pdb_db2 open;
conn faheem/faheem@cbd12c:1521/pdb_db2
select * from tab;

o/p:
SQL> alter pluggable database pdb_db2 open;

Pluggable database altered.

SQL>  conn faheem/faheem@cdb12c:1521/pdb_db2
Connected.

SQL> select * from test;

        ID
----------
         1

We have succesfully unplug and plug pdb_db2 from cdb2 to cdb1.

Hope this helps..

Clone a non-CDB into CDB in Oracle 12c

clone a non-cdb into cdb

Oracle has introduced new Multitenant Option from Oracle 12cR1 and this option allows a single container database (CDB) to host multiple pluggable databases.

Refer here for more details on Oracle Multitenant option.

Related articles:

Create Container Database (CDB) in Oracle 12c using DBCA
Create Container database (CDB) in silent mode
Drop a container database in silent mode
Create a pluggable database manually in Oracle 12c
Clone a pluggable database (PDB) within a CDB in Oracle 12c

Description:

In this post I will describe how to clone a non-CDB database into a CDB in Oracle 12c.

In the below example I have two databases running on the same VM, and will create a new PDB to clone the non-cdb database
db2 – Non-CDB database
cdb2 – CDB database used to clone the non-cdb.
pdb_db2 – new pdb database name which has to clone from non-cdb.

Below are the steps:

  1. Open the non-CDB database into read-only mode
  2. Create directory for new PDB and add new TNS entry to connect non-cdb
  3. Create Database link to allow connection to non-CDB database
  4. Create a new PDB database by cloning the non-cdb using dblink
  5. Execute the noncdb_to_pdb.sql script
  6. Check the newly created PDB status
  7. Open newly created PDB database
1. Open the non-CDB database into read-only mode
export ORACLE_SID=db2
sqlplus "/as sysdba"
shutdown immediate;
startup mount;
alter database open read only;

O/P:
----
[oracle@cdb12c tmp]$ . oraenv
ORACLE_SID = [cdbdev] ? db2
The Oracle base remains unchanged with value /u01/app/oracle
[oracle@cdb12c tmp]$ sqlplus

SQL*Plus: Release 12.2.0.1.0 Production on Tue Jan 19 06:46:34 2021

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

Enter user-name: /as sysdba

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>
SQL>
SQL> startup mount
ORACLE instance started.

Total System Global Area 2432696320 bytes
Fixed Size                  8623592 bytes
Variable Size             654314008 bytes
Database Buffers         1761607680 bytes
Redo Buffers                8151040 bytes
Database mounted.
SQL>
SQL> alter database open read only;

Database altered.

SQL>
SQL>
2. Create a directory to store new PDB Datafiles and add new TNS entry to connect the non-CDB database
mkdir /u01/app/oracle/oradata/cdb2/pdb_db2

--Add the TNS entry in $ORACLE_HOME/network/admin
db2 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = cdb12c)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = db2)
    )
  )
3. Create Database link to allow connection to non-CDB database
export ORACLE_SID=cdb2
sqlplus "/as sysdba"
create database link to_db2_link connect to system identified by idgroup using 'db2';

select name from v$database@to_db2_link;

O/P:
----
[oracle@cdb12c pdb_db2]$ . oraenv
ORACLE_SID = [db2] ? cdb2
The Oracle base remains unchanged with value /u01/app/oracle
[oracle@cdb12c pdb_db2]$ sqlplus
SQL*Plus: Release 12.2.0.1.0 Production on Tue Jan 19 15:45:17 2021
Copyright (c) 1982, 2016, Oracle.  All rights reserved.
Enter user-name: /as sysdba

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL>  create database link to_db2_link connect to system identified by idgroup using 'db2';

Database link created.

SQL> select name from v$database@to_db2_link;
NAME
---------
DB2
SQL>
4. Create a new PDB database by cloning the non-CDB using dblink
export ORACLE_SID=cdb2
sqlplus "/as sysdba"
create pluggable database PDB_DB2 from NON$CDB@to_db2_link create_file_dest='/u01/app/oracle/oradata/cdb2/pdb_db2';

Output:
[oracle@cdb12c ~]$ sqlplus

SQL*Plus: Release 12.2.0.1.0 Production on Tue Jan 19 15:50:26 2021

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

Enter user-name: /as sysdba

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> create pluggable database PDB_DB2 from NON$CDB@to_db2_link
  2  create_file_dest='/u01/app/oracle/oradata/cdb2/pdb_db2';

Pluggable database created.

SQL>
5. Execute the noncdb_to_pdb.sql script
export ORACLE_SID=cdb2
sqlplus "/as sysdba"
alter session set container=PDB_DB2;
@$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql

OP:
[oracle@cdb12c ~]$ sqlplus

SQL*Plus: Release 12.2.0.1.0 Production on Tue Jan 19 15:54:02 2021

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

Enter user-name: /as sysdba

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> alter session set container=PDB_DB2;

Session altered.

SQL>
SQL> @$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql
SQL> SET SERVEROUTPUT ON
SQL> SET FEEDBACK 1
SQL> SET NUMWIDTH 10
SQL> SET LINESIZE 80
.
.
<output truncated>
.
.
SQL> set verify OFF
SQL> set wrap ON
SQL> set xmloptimizationcheck OFF
SQL>
4. Check the newly created pdb status

Status of the PDBs can be checked using v$pdbs view,

select name, open_mode from v$pdbs;
show pdbs;

SQL> select name, open_mode from v$pdbs;

NAME            OPEN_MODE
--------------- ----------
PDB$SEED        READ ONLY
PDB1            READ WRITE
PDB2            READ WRITE
PDB3            READ WRITE
PDB_DB2         MOUNTED ---> Newly created pdb

6 rows selected.


SQL> show pdbs;

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 PDB1                           READ WRITE NO
         4 PDB2                           READ WRITE NO
         5 PDB3                           READ WRITE NO
         6 PDB_DB2                        MOUNTED   -->
SQL>
5. Open the PDB database in read-write mode
--Open newly created pdb:
alter pluggable database pdb_db2 open;
--connect to new pdb
alter session set container=pdb_db2;
select * from faheem.test;

Output:
SQL> alter pluggable database pdb_db2 open;

Pluggable database altered.

SQL> alter session set container=pdb_db2;

Session altered.

SQL> select * from faheem.test;

        ID
----------
         1

1 row selected.

SQL>

We have successfully clone a non-CDB database into a CDB.

Hope this helps…