In this article, we are going to demonstrate the steps to apply the Oracle April 2026 Critical Patch Update (CPU) on a Single Instance Oracle 19c Container Database (CDB). Here we will apply combo patch 39062931 which contains 39034528 (Database Apr 2026 Release Update 19.31.0.0.260421) and 38906621 (OJVM Component Release Update 19.31.0.0.260421). We also cover an important real-world scenario where a previously applied overlay patch 34672698 (ORA-00800 fix) conflicted with the Apr 2026 RU — confirming that the fix is now natively included in the RU itself.
Environment Details
| Parameter | Value |
|---|---|
| Database Type | Single Instance Oracle 19c CDB |
| OS | Oracle Linux x86-64 |
| Starting Version | 19.30.0.0.0 (Jan 2026 RU) |
| Target Version | 19.31.0.0.0 (Apr 2026 RU) |
| Combo Patch | 39062931 |
| DB RU Patch | 39034528 |
| OJVM RU Patch | 38906621 |
| Overlay Patch (conflict) | 34672698 (ORA-00800 fix — rolled back, natively included in 19.31) |
| OPatch Version | 12.2.0.1.51 |
| ORACLE_HOME | /u03/app/oracle/product/19.0.0.0/db_1 |
Section 1: Pre-Patch Checks
1.1 Verify current database version
sqlplus / as sysdba
SQL> select version_full from v$instance;
VERSION_FULL
-----------------
19.30.0.0.0
1.2 Check existing SQL patch history (dba_registry_sqlpatch)
SQL> set lines 200
SQL> col description format a50
SQL> col status format a10
SQL> col action_time format a30
SQL> select patch_id, action, status, action_time, description
2 from dba_registry_sqlpatch
3 order by action_time;
| PATCH_ID | ACTION | STATUS | ACTION_TIME | DESCRIPTION |
|---|---|---|---|---|
| 29517242 | APPLY | SUCCESS | 2022-10-18 02:14:37 | Database Release Update 19.17 |
| 38632161 | APPLY | SUCCESS | 2026-01-21 04:45:06 | Database Release Update 19.30.0.0.260120 |
| 38523609 | APPLY | SUCCESS | 2026-01-21 04:49:43 | OJVM Release Update 19.30.0.0.260120 |
1.3 Check component registry (dba_registry)
SQL> col comp_name format a45
SQL> select comp_id, comp_name, version, status from dba_registry order by comp_id;
| COMP_ID | COMP_NAME | VERSION | STATUS |
|---|---|---|---|
| APS | OLAP Analytic Workspace | 19.0.0.0.0 | VALID |
| CATALOG | Oracle Database Catalog Views | 19.0.0.0.0 | VALID |
| CATJAVA | Oracle Database Java Packages | 19.0.0.0.0 | VALID |
| CATPROC | Oracle Database Packages and Types | 19.0.0.0.0 | VALID |
| CONTEXT | Oracle Text | 19.0.0.0.0 | VALID |
| DV | Oracle Database Vault | 19.0.0.0.0 | VALID |
| JAVAVM | JServer JAVA Virtual Machine | 19.0.0.0.0 | VALID |
| OLS | Oracle Label Security | 19.0.0.0.0 | VALID |
| ORDIM | Oracle Multimedia | 19.0.0.0.0 | VALID |
| OWM | Oracle Workspace Manager | 19.0.0.0.0 | VALID |
| SDO | Spatial | 19.0.0.0.0 | VALID |
| XDB | Oracle XML Database | 19.0.0.0.0 | VALID |
| XML | Oracle XDK | 19.0.0.0.0 | VALID |
| XOQ | Oracle OLAP API | 19.0.0.0.0 | VALID |
1.4 Check invalid objects (baseline)
SQL> select count(*) from dba_objects where status = 'INVALID';
COUNT(*)
----------
8
1.5 Check current OPatch inventory
$ORACLE_HOME/OPatch/opatch lspatches
| Patch ID | Description |
|---|---|
| 34672698 | ORA-00800 SOFT EXTERNAL ERROR, ARGUMENTS [SET PRIORITY FAILED], [VKTM], DISM(16) |
| 38523609 | OJVM RELEASE UPDATE: 19.30.0.0.260120 |
| 38632161 | Database Release Update: 19.30.0.0.260120 |
| 29585399 | OCW RELEASE UPDATE 19.3.0.0.0 |
Section 2: Upgrade OPatch
Before applying any patch, always upgrade OPatch to the latest version. Download the latest OPatch (p6880880) from MOS and apply.
# As oracle user
cd $ORACLE_HOME
mv OPatch OPatch_backup_$(date +%Y%m%d)
unzip /<patch_staging_dir>/p6880880_190000_Linux-x86-64.zip -d $ORACLE_HOME
# Verify new version
$ORACLE_HOME/OPatch/opatch version
# Expected: OPatch Version: 12.2.0.1.51
Section 3: Stage the Patches
# Create staging directory
mkdir -p /<patch_staging_dir>/APR_2026
# Unzip combo patch (contains both DB RU and OJVM RU)
cd /<patch_staging_dir>/APR_2026
unzip p39062931_190000_Linux-x86-64.zip
# Verify extraction
ls -la
# Should show: 38906621/ 39034528/
Section 4: Conflict Check
# Check DB RU for conflicts
cd /<patch_staging_dir>/APR_2026/39034528
$ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -ph ./
# Check OJVM RU for conflicts
cd /<patch_staging_dir>/APR_2026/38906621
$ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -ph ./
Section 5: System Space Check
# Check available space before patching
$ORACLE_HOME/OPatch/opatch prereq CheckSystemSpace -ph /<patch_staging_dir>/APR_2026/39034528
$ORACLE_HOME/OPatch/opatch prereq CheckSystemSpace -ph /<patch_staging_dir>/APR_2026/38906621
# Also verify OS-level space
df -h $ORACLE_HOME
df -h /tmp
Section 6: Take Oracle Home TAR Backup
# As oracle user — use relative path approach to avoid absolute path issues
cd $(dirname $ORACLE_HOME)
nohup tar -czf /<backup_dir>/ORACLE_HOME_backup_$(date +%Y%m%d).tar.gz \
$(basename $ORACLE_HOME) > /tmp/oh_tar_backup.log 2>&1 &
echo "Backup PID: $!"
tail -f /tmp/oh_tar_backup.log
$(dirname $ORACLE_HOME) and $(basename $ORACLE_HOME) avoids embedding absolute paths in the tar archive, making restoration cleaner. The nohup & pattern allows the backup to run in background without being killed if the session disconnects.
Section 7: RMAN Backup (Verify)
# Verify a recent RMAN backup exists before proceeding
rman target /
RMAN> list backup summary;
RMAN> exit;
Section 8: Shutdown Database and Listener
sqlplus / as sysdba
SQL> shutdown immediate;
SQL> exit;
lsnrctl stop LISTENER
Section 9: Roll Back Overlay Patch 34672698
Because patch 34672698 conflicts with the Apr 2026 RU (its fix is now natively included), we must roll it back first.
export PATH=$ORACLE_HOME/OPatch:$PATH
cd $ORACLE_HOME/OPatch
opatch rollback -id 34672698
# Verify rollback
opatch lspatches
# 34672698 should no longer appear
Section 10: Apply DB RU 39034528
cd /<patch_staging_dir>/APR_2026/39034528
# Apply (interactive)
$ORACLE_HOME/OPatch/opatch apply
# OR apply silently (for automation/scripts)
$ORACLE_HOME/OPatch/opatch apply -silent
opatch apply) itself automatically changes oradism ownership from root:oinstall to oracle:oinstall with permissions 755. Always check after applying the DB RU before attempting any manual root steps:
ls -la $ORACLE_HOME/bin/oradism
If oradism is already showing oracle:755 post-apply, the manual chown/chmod steps are not required. Only apply root permission changes if oradism remains root-owned after the patch apply.
Section 11: Apply OJVM RU 38906621
cd /<patch_staging_dir>/APR_2026/38906621
$ORACLE_HOME/OPatch/opatch apply
11.1 Verify OPatch inventory after apply
$ORACLE_HOME/OPatch/opatch lspatches
| Patch ID | Description |
|---|---|
| 38906621 | OJVM RELEASE UPDATE: 19.31.0.0.260421 |
| 39034528 | Database Release Update: 19.31.0.0.260421 |
| 29585399 | OCW RELEASE UPDATE 19.3.0.0.0 |
Note: Patch 34672698 no longer appears — successfully rolled back. Patch 34672698’s fix is now natively bundled into the 19.31 RU.
Section 12: Start Database and Listener
sqlplus / as sysdba
SQL> startup;
SQL> alter pluggable database all open;
SQL> show pdbs;
SQL> exit;
lsnrctl start LISTENER
lsnrctl status LISTENER
Section 13: Run Datapatch
Datapatch applies the SQL-level changes for the new patches into the CDB and all open PDBs. This step is mandatory — OPatch alone does not apply SQL changes.
cd $ORACLE_HOME/OPatch
# Run datapatch and capture output to log
./datapatch -verbose | tee /tmp/datapatch_19_31.log
tee in a pipeline means the shell reports the exit code of tee, not datapatch. If you need to capture datapatch’s actual exit code for scripted validation, use: ./datapatch -verbose > /tmp/datapatch_19_31.log 2>&1; echo "Exit code: $?"
Section 14: Post-Patch Validation
14.1 Verify dba_registry_sqlpatch (post-patch)
SQL> select patch_id, action, status, action_time, description
2 from dba_registry_sqlpatch
3 order by action_time;
| PATCH_ID | ACTION | STATUS | ACTION_TIME | DESCRIPTION |
|---|---|---|---|---|
| 34672698 | ROLLBACK | SUCCESS | 17-MAY-26 09.12.43 AM | ORA-00800 fix (overlay) |
| 38523609 | ROLLBACK | SUCCESS | 17-MAY-26 09.15.02 AM | OJVM Release Update 19.30 |
| 39034528 | APPLY | SUCCESS | 17-MAY-26 09.21.18 AM | Database Release Update 19.31.0.0.260421 |
| 38906621 | APPLY | SUCCESS | 17-MAY-26 09.25.47 AM | OJVM Release Update 19.31.0.0.260421 |
14.2 Verify dba_registry (post-patch)
SQL> select comp_id, comp_name, version, status from dba_registry order by comp_id;
| COMP_ID | COMP_NAME | VERSION | STATUS |
|---|---|---|---|
| APS | OLAP Analytic Workspace | 19.0.0.0.0 | VALID |
| CATALOG | Oracle Database Catalog Views | 19.0.0.0.0 | VALID |
| CATJAVA | Oracle Database Java Packages | 19.0.0.0.0 | VALID |
| CATPROC | Oracle Database Packages and Types | 19.0.0.0.0 | VALID |
| CONTEXT | Oracle Text | 19.0.0.0.0 | VALID |
| DV | Oracle Database Vault | 19.0.0.0.0 | VALID |
| JAVAVM | JServer JAVA Virtual Machine | 19.0.0.0.0 | VALID |
| OLS | Oracle Label Security | 19.0.0.0.0 | VALID |
| ORDIM | Oracle Multimedia | 19.0.0.0.0 | VALID |
| OWM | Oracle Workspace Manager | 19.0.0.0.0 | VALID |
| SDO | Spatial | 19.0.0.0.0 | VALID |
| XDB | Oracle XML Database | 19.0.0.0.0 | VALID |
| XML | Oracle XDK | 19.0.0.0.0 | VALID |
| XOQ | Oracle OLAP API | 19.0.0.0.0 | VALID |
14.3 Verify version
SQL> select version_full from v$instance;
VERSION_FULL
-----------------
19.31.0.0.0
14.4 Check invalid objects (post-patch)
SQL> select count(*) from dba_objects where status = 'INVALID';
COUNT(*)
----------
8
Invalid count unchanged from baseline — no new invalids introduced by patching.
14.5 Run utlrp.sql (conditional)
utlrp.sql is conditional — only required if you see new invalid objects that were not in the baseline count, or if Oracle-supplied objects remain INVALID after 24 hours. It is not mandatory after every patch apply.
-- Only run if new invalids are found
sqlplus / as sysdba
SQL> @?/rdbms/admin/utlrp.sql
14.6 CDB-aware validation (cdb_registry_sqlpatch)
-- Run from CDB$ROOT to validate across all containers
SQL> col con_id format 99
SQL> col patch_id format 9999999999
SQL> col status format a10
SQL> col action format a10
SQL> select con_id, patch_id, action, status, description
2 from cdb_registry_sqlpatch
3 order by con_id, action_time;
cdb_registry_sqlpatch shows the patch apply status for each container (CDB$ROOT and all PDBs). Use this view to confirm datapatch applied successfully in all PDBs, not just the root container. All rows should show SUCCESS.
Section 15: Rollback Procedure (If Required)
If the patch causes critical issues post-apply, roll back in reverse order: OJVM first, then DB RU. This requires full database downtime.
15.1 Shutdown the database and listener
sqlplus / as sysdba
SQL> shutdown immediate;
SQL> exit;
lsnrctl stop LISTENER
15.2 Roll back the OJVM patch first
export PATH=$ORACLE_HOME/OPatch:$PATH
opatch rollback -id 38906621
OPatch succeeded.
15.3 Roll back the DB RU
opatch rollback -id 39034528
OPatch succeeded.
15.4 Verify Jan 2026 RU is restored
opatch lspatches
-- Expect to see 38632161 and 38523609 back as active
15.5 Start database, open PDBs, run datapatch
sqlplus / as sysdba
SQL> startup;
SQL> alter pluggable database all open;
SQL> show pdbs;
SQL> exit;
cd $ORACLE_HOME/OPatch
./datapatch -verbose
Section 16: Common Failures and Troubleshooting
ZOP-47: Conflict with existing overlay patch
Symptom: opatch prereq CheckConflictAgainstOHWithDetail reports a conflict between an installed overlay patch and the new RU.
Cause: The overlay patch fix has been natively absorbed into the new RU.
Resolution: Roll back the overlay patch using opatch rollback -id <patch_id>, then proceed with the RU apply. Confirm with Oracle Support SR if unsure whether the conflict is a ZOP-47 (self-resolving) or a genuine incompatibility.
ZOP-40: Patch already installed
Symptom: OPatch reports the patch is already present in the inventory.
Cause: Patch was applied in a previous cycle or the inventory is stale.
Resolution: Verify with opatch lspatches. If genuinely already installed, no action needed. If inventory is stale, run opatch lsinventory -detail to diagnose.
Datapatch skipped PDB
Symptom: Datapatch log shows one or more PDBs were skipped.
Cause: PDB was not open during datapatch execution.
Resolution: Open the skipped PDB (alter pluggable database <pdb_name> open;) and re-run datapatch. Confirm via cdb_registry_sqlpatch that all containers show SUCCESS.
OPatch heap space error
Symptom: OPatch fails with a Java heap space error during apply.
Cause: Default JVM heap is insufficient for large patch sets.
Resolution: Set JAVA_TOOL_OPTIONS="-Xmx512m" before running opatch. This is environment-specific and not universally required — only apply if the error is observed.
OPatch inventory lock
Symptom: OPatch fails reporting the inventory is locked by another process.
Cause: A previous OPatch run did not exit cleanly, leaving a lock file.
Resolution: Check for and remove the lock file: $ORACLE_HOME/.patch_storage/<lock_file>. Confirm no other OPatch process is running before removing.
Key MOS References
| Document | Description |
|---|---|
| Doc ID CPU58 | Critical Patch Update (CPU) Apr 2026 for Oracle Database Products — patch availability, known issues, delayed RU tracking |
| Doc ID KB106822 | Primary Note for Database Quarterly Release Updates — recommended reading before any RU apply |
| Doc ID KB869205 | Oracle Database 19c Apr 2026 RU Known Issues |
| Doc ID KB137197 | OJVM Conditional Rolling Install Details |
| Doc ID 244241.1 | OPatch Support for RAC Rolling Patches |
| Doc ID 293369.1 | OPatch Documentation List |
Disclaimer: All server names, hostnames, database names, and environment-specific paths in this post have been anonymized. Steps and outputs are based on real production experience adapted for general use. Always test in a non-production environment before applying patches to production systems.
If you found this useful, connect with me on LinkedIn or explore more Oracle DBA scripts on my GitHub. More patching walkthroughs at syedanwarahmedoracle.blog.
Share Your Experience
Have you applied Oracle 19c CPU patches and hit a similar overlay patch conflict? Or found that a fix you applied months ago is now natively bundled into the next RU? Your real-world experiences help fellow DBAs tackle the same challenges. Drop a comment below — questions, observations, and feedback are always welcome.