In this blog post I will show you how to upgrade a 18.104.22.168 PDB to 19c when it is running in a VM DB System. I have a PDB called SALES and it is running Standard Edition 2 (yes, this procedure works for Standard Edition 2 as well). In a previous blog post I went over the restrictions that apply to VM DB System and having those in mind I can create a high-level plan for the upgrade:
- Check plug-in compatibility in the new release CDB
- Use AutoUpgrade to analyze the PDB
- Create a refreshable PDB on the new system
- Downtime starts
- Use AutoUpgrade to execute pre-upgrade fixups
- Refresh the new PDB
- Upgrade the new PDB
- Test and wrap-up
The refreshable PDB feature was introduced with in Oracle Database release 12.2 so you can’t use this procedure for lower versions. Your source database must be at least on release 12.2. If not, you must clone the entire database in traditional manner, which will be discussed in a later blog post.
Check plug-in compatibility of the PDB in the new release CDB
I will start by checking whether my PDB can be plugged into the new release CDB. You should describe the PDB to generate a manifest file:
EXEC DBMS_PDB.DESCRIBE('/home/oracle/sales.xml', 'SALES');
Transfer the XML file to the target system and check plug-in compatibility. Instead of transferring the file between the two systems you can also use the File Storage Service to create a shared file system that can be accessed via a NFS client.
BEGIN IF DBMS_PDB.CHECK_PLUG_COMPATIBILITY('/home/oracle/sales.xml', 'SALES') THEN DBMS_OUTPUT.PUT_LINE('SUCCESS'); ELSE DBMS_OUTPUT.PUT_LINE('ERROR'); END IF; END; /
Look at the result:
SELECT type, message, action FROM pdb_plug_in_violations WHERE name='SALES' and status='PENDING';
As expected, I do see some plug-in violations:
Obviously, there is a difference in database release and patch level. The database upgrade will take care of those issues. Also, you get a warning about
COMPATIBLE being different. This is expected and the
COMPATIBLE setting will be automatically changed once we plug the PDB into the new release CDB. The underscore parameters are added automatically when you create a VM DB System in OCI and they are there for a good reason.
RECYCLEBIN is on in my new release CDB – I can live with that, and finally I have unencrypted tablespaces. For this test it is not critical, but it should never be so in a real database.
Remember, for a plug-in operation to complete (i.e. you can open the PDB in READ WRITE mode and RESTRICTED=NO) there must not be any errors. Warnings are accepted but should be ideally be fixed as well.
Use AutoUpgrade to analyze the PDB
I need to create a config file for AutoUpgrade, and I will give it a better name:
cd java -jar $ORACLE_HOME/rdbms/admin/autoupgrade.jar -create_sample_file config mv sample_config.cfg upg19_sales.cfg
Edit the config file. See here for description of the parameters. Note that we can’t specify a
target_home because it is not present, instead you must specify the
target_version. Also, I specify that only one of the PDBs should be analyzed using
pdbs parameter. AutoUpgrade will always check CDB$ROOT and PDB$SEED regardless of
pdbs setting. This is by design. I ended up with this config file:
global.autoupg_log_dir=/home/oracle/upg_logs upg1.dbname=CDB1 upg1.start_time=NOW upg1.source_home=/u01/app/oracle/product/22.214.171.124/dbhome_1 upg1.sid=CDB1 upg1.log_dir=/home/oracle/upg_logs upg1.target_version=19 upg1.pdbs=SALES
Now, analyze the database:
java -jar $ORACLE_HOME/rdbms/admin/autoupgrade.jar -config ~/upg19_sales.cfg -mode analyze
Check the analyze result. You can disregard the checks from containers CDB$ROOT, PDB$SEED and all other PDBs than SALES. Also, only look at the issues where STAGE=PRECHECKS and fixup_available=NO:
In OCI I receive a warning from the check TDE_IN_USE. It is expected and you don’t have to do anything. The newly provisioned target system is properly configured. Also, OCI itself has a habit of setting a lot of underscore parameters. Just let them be.
Create a refreshable PDB on the new system
While I wait for downtime to start, I will create a refreshable PDB. I need to copy the PDB to the target system and to avoid doing that during downtime, I will use the refreshable PDB feature. When I refresh it, it will only need to apply the recent-most changes from the source PDB which is much faster than a full clone, obviously. I need a common user in the source CDB that can be used by the database link over which the cloning will take place:
CREATE USER c##clone_user IDENTIFIED BY FOObar11## CONTAINER=ALL; GRANT CREATE SESSION, CREATE PLUGGABLE DATABASE TO c##clone_user CONTAINER=ALL;
In the target CDB, create a database link that points to the source CDB:
CREATE DATABASE LINK clone_link CONNECT TO c##clone_user IDENTIFIED BY FOObar11## USING '10.0.1.45/ CDB1_fra1jf.sub02121342350.daniel.oraclevcn.com';
Check that it works
SELECT count(*) FROM all_objects@clone_link;
If you get ORA-02085 execute
ALTER SESSION SET GLOBAL_NAMES=FALSE;
Let’s create the refreshable PDB. I will set it to
REFRESH MODE MANUAL but you could also configure it to refresh automatically at regular intervals, e.g. every 10 minutes, using
REFRESH MODE EVERY 10 MINUTES clause. The keystore password is needed for security reasons. It is the same password as you specified for SYS when you created the system (parameter
CREATE PLUGGABLE DATABASE SALES FROM SALES@CLONE_LINK PARALLEL 4 REFRESH MODE MANUAL KEYSTORE IDENTIFIED BY "...";
If you get this error:
CREATE PLUGGABLE DATABASE SALES FROM SALES@CLONE_LINK * ERROR at line 1: ORA-19505: failed to identify file "+DATA/CDB1_FRA1JF/A4EBB0BCBC427D8FE0532D01000A9AEC/DATAFILE/users.275.1039631039" ORA-15173: entry 'CDB1_FRA1JF' does not exist in directory '/'
You are missing patch 29469563. Now – sit back and relax and wait for down time to start. You can periodically refresh the PDB to further minimize the final refresh time:
ALTER PLUGGABLE DATABASE SALES REFRESH;
Now it is time to kick users off. Drain the database of connections – or actually just drain the PDB – and prevent users from accessing the database.
Use AutoUpgrade to execute pre-upgrade fixups
Now we can run the preupgrade fixups to prepare the database for upgrade. I will re-use the config file I created earlier, but change the processing mode to fixups:
java -jar $ORACLE_HOME/rdbms/admin/autoupgrade.jar -config ~/upg19_sales.cfg -mode fixups
You should re-check the analyze log file to ensure that no new issues are reported. Note how the path has changed because of a new AutoUpgrade jobid. It increments by one on each run:
Refresh the new PDB
I suggest that you create a tracking table. This way you can ensure that you have all the latest changes in the new PDB:
ALTER SESSION SET CONTAINER=SALES; CREATE USER UPG_TRACKING IDENTIFIED BY FOObar11##; ALTER USER UPG_TRACKING QUOTA UNLIMITED ON USERS; CREATE TABLE UPG_TRACKING.SUCCESS (C1 NUMBER); INSERT INTO UPG_TRACKING.SUCCESS VALUES (42); COMMIT;
Shut down the PDB to ensure no one logs on accidentally:
ALTER PLUGGABLE DATABASE SALES CLOSE IMMEDIATE;
And do the final refresh:
ALTER PLUGGABLE DATABASE SALES REFRESH;
Upgrade the new PDB
Now we are done at the source system. We have made the final refresh and all my data are transferred to the new PDB; it is time to convert the refreshable PDB into a regular PDB and open it in upgrade mode:
ALTER PLUGGABLE DATABASE SALES REFRESH MODE NONE; ALTER PLUGGABLE DATABASE SALES OPEN UPGRADE;
I will double check that all my changes are in my new PDB:
ALTER SESSION SET CONTAINER=SALES; SELECT * FROM UPG_TRACKING.SUCCESS;
Right now, you can’t use AutoUpgrade for unplug/plug upgrades when source and target CDB are not on the same host, so we will do it the old fashion way (which is nice as it refreshes your skills). I have four CPUs in my system and I only need to upgrade this PDB so let’s ensure that all CPUs are allocated to the upgrade – that’s the option
mkdir -p ~/upg_logs/SALES dbupgrade -c SALES -l ~/upg_logs/SALES -N 4
But it also reminds you how nice AutoUpgrade is. It does so many things automatically. I will only do the essential things. For a real-life upgrade you should consult the upgrade guide to get the full procedure.
Open PDB and set it to auto-start:
ALTER PLUGGABLE DATABASE SALES OPEN; ALTER PLUGGABLE DATABASE SALES SAVE STATE;
ALTER SESSION SET CONTAINER=SALES; @$ORACLE_HOME/rdbms/admin/utlrp
Check the upgrade with post-upgrade status tool
Check the state of the Oracle Data Dictionary. If you get an error from the
SET command, you are probably using SQLPlus. You should try out SQLcl. It is so much nicer.
SET SQLFORMAT ANSICONSOLE LINES 300 SELECT COMP_ID, COMP_NAME, VERSION, STATUS FROM DBA_REGISTRY ORDER BY MODIFIED;
Because we ran the analyze on the source system, there is no post-upgrade fixups available, and I didn’t use AutoUpgrade for the actual upgrade (which would have figured it out automatically). You need to look in the pre-upgrade analyze log file on the source system. Again, I will only need to look at the issues from SALES PDB:
You could also look in the HTML files that is placed in the same directory, if you need something more readable and a better description of the issues. Otherwise, have a look at the My Oracle Support document “Database Preupgrade tool check list. (Doc ID 2380601.1)”. Even though is says that there is a fixup available you must do it manually. In my case it was:
- Dictionary stats
- Fixed object stats
- Time zone file upgrade
So, let’s do it:
EXEC DBMS_STATS.GATHER_DICTIONARY_STATS; EXEC DBMS_STATS.GATHER_FIXED_OBJECT_STATS;
And finally upgrade the time zone file:
SET SERVEROUTPUT ON @$ORACLE_HOME/rdbms/admin/utltz_upg_check.sql @$ORACLE_HOME/rdbms/admin/utltz_upg_apply.sql
Clean up the tracking user and database link:
DROP USER UPG_TRACKING CASCADE; ALTER SESSION SET CONTAINER=CDB$ROOT; DROP DATABASE LINK clone_link;
Since we have moved the database to a new host, you must update your connect strings and tnsadmin files to point to the new server and service name.
Test and wrap-up
Now it is also time to let in the application testers, start a level 0 backup and what else is on your runbook. Finally, I can now delete the source VM DB System:
oci db system terminate --db-system-id "..."
That should be it. Should something happen during the upgrade it is really easy to make a fallback. Just re-open the source PDB and you are back in business. Speaking of fallback one thing that you must keep in mind is that once you plug in your PDB to a higher release CDB the
COMPATIBLE parameter is automatically raised – no questions asked. And that does prevent you from making a database downgrade, if it should be necessary. If you need to go back to the previous release you must use Data Pump and do a regular export/import.