Introduction

I have provided help for some people from GUOB community a few times with questions about “how to clone a PDB in CDB with Data Guard” or situations like “my standby stop to sync after a PDB clone at primary”. In this blog post I’m gonna to show an example in how I usually do this kind of PDB clone in CDB running in Data Guard configurations.

First thing to know is Oracle will not automatically create the new datafiles in the Standby when you clone a PDB in the Primary side, the only thing that Data Guard take care is about the PDB registration in the Standby controlfile. This occurs because Data Guard only send redo data from Primary to Standby, and when we are cloning a PDB, which usually occurs behind of scenes is a RMAN restore that do not generates redo to create the new datafiles. The only redo generated for this operation is the “PDB creation” itself, the information that is registered in the controlfile.

So when we clone a PDB in the Primary, we need to clone it in the Standby as well. Fortunately we can leverage the RESTORE FROM SERVICE feature in RMAN on Standby side. This is my preferred option and is that one I will demonstrate in this blog post.

Please note these steps were very tested in 19c databases, I didn’t have chance to test it in new releases like 26ai, but it is expected to work in the same way.

Case Scenario

To demonstrate how this works, I’m using an example of cloning a non-CDB database as a PDB in an existing CDB. This scenario is similar to the local PDB clone, but we need to use a DBLINK created in the Target CDB pointing to the source non-CDB database.

The next steps is divided in 3 sections:

  • Section A – The commands we need to execute in the source non-CDB
  • Section B – The commands we need to execute in the target Primary CDB
  • Section C – The commands we need to execute in the target Standby CDB

To better understand this step by step, please keep in mind those details:

Source non-CDB Hostnamelab03
Source non-CDB Database nameDB03A
Target Primary CDB Hostnamelab01
Target Standby CD Hostnamelab02
Target Primary CDB Database unique nameCDBDG_A
Target Standby CDB Database unique nameCDBDG_B
Target new Clone PDB NameDB03A_CLONE

Step by Step

Section A) Source non-CDB

1) Create the clone user in the source non-CDB with the required privileges to create pluggable databases (this is required in order to clone the database over DBLINK):

create user c##clone_user identified by oracle;
grant create session, sysoper, create pluggable database to c##clone_user;

Section B) Target CDB Primary

2) Create the DBLINK in the target CDB pointing to the source non-CDB:

drop public database link LK_TO_DB03A;
create public database link LK_TO_DB03A 
 connect to c##clone_user identified by oracle 
 using '//lab03:1521/DB03A';

Please note I’m using EZCONNECT for the connection string, but you can use TNS alias as well.

3) Create the PDB clone

create pluggable database DB03A_CLONE
from non$cdb@LK_TO_DB03A
parallel 8;

I’m using PARALLEL 8 here. This is optional, but I always use this when that is possible.

4) Check the PDB status after the clone is completed:

set lines 300
col pdb_name for a20
col status for a20
col refresh_mode for a20
col refresh_interval for 999
select con_id, pdb_name, status, refresh_mode, refresh_interval 
from dba_pdbs 
where pdb_name='DB03A_CLONE';

Also check for any PDB invalidation:

set pagesize 500
set linesize 300
col cause for a30
col name for a20
col message for a80 word_wrapped
col status format a10
select name,cause,type,message,status 
from PDB_PLUG_IN_VIOLATIONS
where status <> 'RESOLVED'
order by name, type, cause;

That is expected the new PDB is in RESTRICTED mode due the pending task to convert it to PDB using the noncdb_to_pdb.sql script (next step)

5) Complete the conversion from non-CDB to PDB:

alter session set container = DB03A_CLONE;
@?/rdbms/admin/noncdb_to_pdb.sql

6) Restart the PDB without restrictions or violations

alter pluggable database close;
alter pluggable database open;
show pdbs;

If the PDB still in RESTRICTED mode, so you should evaluate what is the cause using the PDB_PLUG_IN_VIOLATIONS view. For example, a common issue is a patch mismatch between the CDB root and the new PDB, where the solution is just to run the Datapatch.

Section C) Target CDB Standby

7) Check the status for the new PDB datafiles in the Standby:

alter session set container=DB03A_CLONE;

set lines 100
col name format a20
select name, recovery_status from v$pdbs;

set lines 120           
set pages 9999
col name format a65
select name, status from v$datafile;

8) Execute an Active Restore for this PDB from Primary to Standby using RMAN

Connect in the RMAN:

rman
connect target sys/<sysPassword>@CDBDG_B

Execute a script like this, please change the PDB name, the disk group and connection string according:

run{
 allocate channel disk1 device type disk;
 allocate channel disk2 device type disk;
 allocate channel disk3 device type disk;
 allocate channel disk4 device type disk;
 allocate channel disk5 device type disk;
 set newname for pluggable database DB03A_CLONE to '+DATA';
 restore pluggable database DB03A_CLONE from service 'lab01:1521/CDBDG_A' section size 512m;
}

What is important to note here:

  • The TNS used as ‘target’ is the current Standby
  • The TNS used as ‘from service’ is the current Primary
  • set newname” it is important here to leverage the RMAN capability of generating OMF names for restored datafiles
  • section size” it is important if the PDB has big files, but I normally use this option even for small files. If your datafiles are really big, like 16-32 TB, consider to use larger sections like 128 – 256 GB.
  • The number of channel should be allocated as you usually would allocate to an active duplicate from PROD.
  • If the Primary database is RAC, use the SCAN instead of hostname to balance the load in the Primary cluster.

9) Stop MRP. In this example I’m doing this manually using SQLPLUS, but we can use dgmgrl for Data Guard with Broker configuration:

ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

10) Switch the Standby datafiles to their copies (this actually rename the datafiles in the standby controlfile).

This is a RMAN command:

switch pluggable database DB03A_CLONE to copy;

11) Restart the physical standby in mount mode if it is running in Active Data Guard mode.

sqlplus / as sysdba
select status from v$instance;

-- ONLY if the current status is OPEN
shutdown immediate;
startup mount;

If the Standby is a RAC database, you should stop it using srvctl stop database command, since all instances needs to be restarted in MOUNT mode.

12) Enable recovery for the new PDB:

alter session set container=DB03A_CLONE;
alter pluggable database enable recovery;

13) Enable the MRP again to sync the Standby applying the archived logs:

alter session set container=CDB$ROOT;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;

The steps 14-17 are optional, but I recommend to do it and confirm the new datafiles get ONLINE status in V$DATAFILE view.

14) Wait until Standby is sync with the Primary (apply lag = 0)

set linesize 300
col name format a25
col value format a25
col unit format a30
col time_computed format a20
select NAME, VALUE, UNIT, DATUM_TIME, TIME_COMPUTED 
FROM V$DATAGUARD_STATS;

15) Stop the MRP and open the standby and all the PDBs to synchronize the Standby controlfile status:

ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
alter database open;
alter pluggable database all open;

16) Check datafile status

set pages 50
set lines 400
col name format a100
select con_id, file#, status, enabled, name 
from v$datafile 
order by 1,2;

17) Close the database and restart the MRP again

alter database close;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;

Nice to know about alert log messages

Case 1:

a) the standby alert log will show something like this when CREATE PDB is executed in Primary database.

Recovery created pluggable database DB03A_CLONE
DB03A_CLONE(6):Tablespace-SYSTEM during PDB create skipped since source is in              r/w mode or this is a refresh clone
DB03A_CLONE(6):File #37 added to control file as 'UNNAMED00037'. Originally created as:
DB03A_CLONE(6):'+DATA/CDBDG_A/2E065E6A74AD26A9E0630E01A8C03B9D/DATAFILE/system.377.1192959657'
DB03A_CLONE(6):because the pluggable database was created with nostandby
DB03A_CLONE(6):or the tablespace belonging to the pluggable database is

This is expected behavior until we restore the PDB with RMAN in the Standby.

Case 2:

The standby can log this in the alert log, just open the standby in READ-ONLY and close again.

WARNING: the control file may have incorrect data structure for some PDBs.
Please open database and all pluggable databases read-only to synchronize the control file with the database dictionary.
max_pdb is 7

Conclusion

In this blog post I covered all the steps to get a PDB properly cloned in a CDB with Data Guard configuration. As a final tip for it, if you Standby is a RAC database, I recommend you first shutdown all the instances using the SRVCTL, and following the blog steps only using SQLPLUS and RMAN. After you complete these steps, shutdown the local instance and start the database with SRVCTL again.

Leave a Reply

Discover more from Blog do Dibiei

Subscribe now to keep reading and get access to the full archive.

Continue reading