Oracle Data Guard Setup in Oracle 23ai Migrating from Non-CDB (Primary) to CDB (Standby)

Introduction

This document explains how to configure a normal Oracle Data Guard physical standby in Oracle Database 23ai, where the primary database is a Non-CDB and the standby database is created as a CDB. This approach is commonly used during modernization or upgrade initiatives, allowing legacy non-container databases to be protected while adopting the multitenant architecture.

The steps and checks described here reflect standard DBA practices and focus on correctness, validation, and operational clarity.

Supported approach:

Oracle Data Guard does not directly support Non-CDB to CDB redo apply. Therefore, the correct and supported approach is:

  1. Convert the Non-CDB primary to a PDB using the DBMS_PDB.DESCRIBE method

  2. Plug the PDB into a CDB primary (23ai)

  3. Configure Data Guard between CDB primary and CDB standby

This document covers the complete flow.

Architecture Overview

  • Source Database : Non-CDB (Legacy)

  • Target Primary : Oracle 23ai CDB

  • Standby : Oracle 23ai CDB Physical Standby

  • Protection Mode : Maximum Performance / Availability

Step 1: Verify Non-CDB Readiness

On the source Non-CDB database:

SQL> SELECT cdb FROM v$database;

CDB

NO

This confirms the source database is running in non-container mode.

Check plug compatibility:

SQL> BEGIN
DBMS_PDB.CHECK_PLUG_COMPATIBILITY(
pdb_descr_file => ‘/u01/app/oracle/ncdb.xml’,
pdb_name => ‘LEGACY_PDB’
);
END;
/

PL/SQL procedure successfully completed.

If incompatible objects exist, Oracle reports them in PDB_PLUG_IN_VIOLATIONS.

NO

Check compatibility:

SQL> BEGIN DBMS_PDB.CHECK_PLUG_COMPATIBILITY( pdb_descr_file => ‘/u01/app/oracle/ncdb.xml’, pdb_name => ‘LEGACY_PDB’ ); END; /

Step 2: Describe the Non-CDB

SQL> EXEC DBMS_PDB.DESCRIBE(‘/u01/app/oracle/ncdb.xml’);

This generates the XML metadata required to plug the Non-CDB as a PDB.

Step 3: Create Oracle 23ai CDB (Primary)

Create a new CDB using DBCA or manual scripts:

  • Enable ARCHIVELOG

  • Enable FORCE LOGGING

  • Configure FRA

Verify:

SQL> SELECT name, cdb, open_mode FROM v$database;

Step 4: Plug Non-CDB as PDB

Create the PDB inside the 23ai CDB:

SQL> CREATE PLUGGABLE DATABASE legacy_pdb
USING ‘/u01/app/oracle/ncdb.xml’
COPY
FILE_NAME_CONVERT = (‘/u01/oradata/NCDB’,’/u01/oradata/CDB/legacy_pdb’);

Pluggable database created.

Open the PDB:

SQL> ALTER PLUGGABLE DATABASE legacy_pdb OPEN;

Pluggable database altered.

Verify PDB status:

SQL> SHOW PDBS

CON_ID CON_NAME OPEN_MODE RESTRICTED
—— ———— ———- ———-
3 LEGACY_PDB READ WRITE NO

Step 5: Convert to Application- Compatible PDB

SQL> ALTER SESSION SET CONTAINER=legacy_pdb;
SQL> @$ORACLE_HOME/rdbms/admin/noncdb_to_pdb.sql

Restart PDB after completion.

Step 6: Prepare CDB for Data Guard

On CDB primary:

SQL> ALTER DATABASE FORCE LOGGING;
SQL> ALTER SYSTEM SET LOG_ARCHIVE_CONFIG=’DG_CONFIG=(CDBPRI,CDBSTBY)’;

Step 7: Create Physical Standby CDB

Duplicate the primary CDB using RMAN active duplication:

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

Starting Duplicate Db at 12-JUN-25
Finished Duplicate Db at 12-JUN-25

Verify standby role:

SQL> SELECT database_role, open_mode FROM v$database;

DATABASE_ROLE OPEN_MODE
————— ——————–
PHYSICAL STANDBY MOUNTED

Step 8: Configure Redo Transport

SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_2=
‘SERVICE=CDBSTBY ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=CDBSTBY’;

Step 9: Start Redo Apply on Standby

Start managed recovery:

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;

Database altered.

Verify redo apply processes:

SQL> SELECT process, status FROM v$managed_standby;

PROCESS STATUS
——- ————
MRP0 APPLYING_LOG
RFS IDLE

Step 10: Validation Checks

Primary database validation:

SQL> SELECT destination, status FROM v$archive_dest_status;

DESTINATION STATUS
———– ——
LOG_ARCHIVE_DEST_2 VALID

Standby database validation:

SQL> SELECT database_role, open_mode FROM v$database;

DATABASE_ROLE OPEN_MODE
————— ——————–
PHYSICAL STANDBY MOUNTED

Check apply lag:

SQL> SELECT name, value FROM v$dataguard_stats WHERE name LIKE ‘%lag%’;

NAME VALUE
————– ———
apply lag +00 00:00:05
transport lag +00 00:00:03

Operational Notes

  • Data Guard works at CDB level, not individual PDBs

  • All PDBs inside the CDB are protected

  • PDB-level recovery is not supported

Conclusion

Migrating from a Non-CDB to a CDB while implementing Data Guard in Oracle 23ai requires a structured approach. By first converting the Non-CDB into a PDB and then configuring Data Guard between CDB primary and standby, DBAs can achieve both modernization and high availability using fully supported Oracle architecture.

Recent Posts