To CDB or not to CDB, that’s the question

To CDB or not to CDB, that’s the question

A product manager has several parts on the job. You can do outbound PM, that is what you, the readers or public, see. But we have also an inbound task. One of the things we do is answer internal questions and advise on how to use the product. This question is coming from a colleague who is doing an upgrade at a customer and facing some strange things with the move from non-cdb towards a cdb.

On My Oracle Support there is a mos-note which is very interesting: Reusing the Source Standby Database Files When Plugging a non-CDB as a PDB into the Primary Database of a Data Guard Configuration (Doc ID 2273304.1)

Wouldn’t it be nice to test this? In short it means, as long as you share the same ASM disk groups, you do not need to copy the files and you can just “use” them in the PDB, but also … you’re not messing up your standby database. So let’s explore how this works.

The idea

The idea is simple, after the upgrade of the DB to 19.3, they want to (and I strongly agree and encourage this) convert this to PDB’s.

So it starts with a normal upgrade from the DB towards a 19.3 non-cdb and then we want to plug it into a CDB and make it multitenant.

The question is … will this


I have setup my lab accordingly. So I have created a non-cdb 19.3 database. Just next next finish, nothing fancy (you will read later why I added this sentence).

Next to that, I created an empty cdb, without PDBs.

For both databases, Data Guard was setup and is handled using the broker.

Maybe not too important, but for this blogpost it is, We use ASM on Oracle Restart. 2 Diskgroups +DATA and +RECO.
Both vm’s are setup EXACTLY the same.

My non-cdb is called dgdemo. Db unique for the primary is dgdemovm1 and for the standby dgdemovm2. You will see later on why this was not a smart choice.

The CDB is called (how can you guess it) cdgdemo with instance names cdgdemovm1 for the primary and cdgdemovm2 for the standby.

Ready? Ok, let’s go!


As everything, also this has prerequisites. In the mos-note it states

  • The source non-CDB and destination CDB must be the same version.
  • The Source non-CDB primary database and destination CDB Primary database share storage
  • The Source non-CDB standby database and destination CDB standby database share storage
  • The Source non-CDB standby database and the destination CDB standby database must use the same diskgroup, ASM aliases cannot span multiple diskgroups
  • The db_create_file_dest parameter in the CDB standby database must be set and should be set to the diskgroup name being used by the standby database

Ok, did you read it? Stop now and re-read it please. It is important.

I will borrow a sentence from the mos-note as I cannot write it better: “Using this method the data files of both the Primary and the Standby non-CDB databases will physically remain in their existing directory structure and be consumed by the destination CDB and its Standby.  The steps as documented are for ASM storage although a similar process can be used with non-ASM using softlinks. 

This is interesting, right? This means that no (big) file copies need to be done and we can reuse the data in ASM (or filesystem) with just a (I call it) a metadata change.

The procedure

Let me immediately rephrase myself. It is not a big “copy / paste” procedure, otherwise I’d just have given you a script which does everything for you.

First step, we need to know the GUID from the Database to make sure that we can check we are on the correct database.
You get that from the Current (non-cdb) primary database:

On the standby Server, the non-cdb standby database, create a SQL Script (build_crt_alias_noncdb.sql) with following content:

And then execute it on the non-cdb physical standby database. This script creates another script, that you will execute later to create the ALIASES (so if you want to remove them later, use rmalias as rm will also remove the file) for the metadata change to succeed. I agree, … this is a bit … whatever, but currently we do not support single Pdb role transitions, so bear with me for a moment.

So when you execute this, it will have comparable output like this

Then we need to teach the standby server his ASM instance, that we are going to mess around with it, not really messing around, but we will need the aliases. So log on to the standby server ASM instance and execute the generated script

At this point, the standby ASM is ready for the CDB Standby database to be able to find the non-CDB Standby database’s data files when the non-cdb primary will be plugged in into the primary CDB.

Now it is time to stop the redo apply on the non-cdb standby database. Either use sql or the broker, but in my example, I prefer the broker.

If you use Active Data Guard and you have the physical standby in read-only mode, you should now reboot it in mount mode as we need to roll it forward a little bit.

When the primary is a RAC database, shut down all the other nodes and you now should continue on one instance only.

Next step is to stop it using srvctl and then cleanly start it. Then we flush the redo to the standby site and open the database read-only. Flushing, in this case, will send the redo to the standby server, but will not apply it yet as we stopped the redo-apply earlier.

This is a very important moment. Now we need to determine the checkpoint_change number as this has to be the same on primary and standby or otherwise the rest will fail.

On the non-cdb primary:

Then recover the standby database until this number and verify all went well

So far so good. This MUST be good otherwise you might find yourself in interesting situations later on.

Now it is time to create a manifest file which we need later to plug the database into the CDB. After that, we need to shutdown the database.

Then also shutdown the non-cdb standby database

Now all is ready to plug in the non-cdb into the cdb as a pdb. Except … and this has bitten me in the past (hey , the one without mistakes … ). At this point, check your standby_file_management parameter. It should be AUTO! if it is not, change it to auto on both cdb-primary and cdb-standby.

Then on the CDB primary, plug-in the non-cdb as follows

Verify this on the standby CDB

Trust is good, but verify. In alertlog you need to find messages that new data files have been added to the media recovery

So this looks good!

On the primary CDB, we now need convert the non-cdb to a PDB. To do so, log on to the mounted container and run the noncdb_to_pbd.sql script

sorry to skip all the output, but at the end you should have your prompt back and verify if all went well after opening the PDB.

For this demo, it is not a real problem as all went fine for what we wanted to show here, but in a real production situation, this should have been carefully taken care of upfront.
I mean, create your CDB with the correct options, make sure no options are missing and all is ok, then this will not show.

Key is, that we did NOT perform a file copy, we did NOT transfer lots of data, but we kept our DR in place by plugging in the non-cdb into a fresh CDB.

As always, questions, remarks? find me on twitter @vanpupi

Leave a Reply

Your email address will not be published. Required fields are marked *

13 − 2 =

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: