Introduction
Oracle patching is essential for maintaining database security, performance, and stability. However, not every patch deployment goes as planned. In some environments, newly applied Release Updates (RUs) may introduce compatibility issues, performance degradation, or operational risks that require immediate rollback.
In this guide, we walk through a real-world rollback of Oracle 19.31 Release Update (Patch 39034528) back to Oracle 19.28 (Patch 37960098) using OPatch and Datapatch.
This article is designed for Oracle DBAs, system administrators, and infrastructure teams who need a safe, validated rollback process while minimizing downtime and ensuring database consistency.
Why Roll Back Oracle 19.31?
Rolling back an Oracle Release Update may be necessary for several reasons:
- Application incompatibility after patching
- Unexpected database performance issues
- Failed post-patch validations
- Security or compliance conflicts
- Business continuity concerns
- Need to stabilize production environments quickly
In this scenario, Oracle 19.31 binaries were successfully installed, but operational requirements demanded reverting to Oracle 19.28.
Step 1: Verify Existing Patch Inventory
Before rollback, confirm the currently installed patches:
./opatch lspatches
39034528;Database Release Update : 19.31.0.0.260421 (39034528)
29585399;OCW RELEASE UPDATE 19.3.0.0.0 (29585399)
OPatch succeeded.
Output showed:
- 39034528 – Oracle Database Release Update 19.31
- 29585399 – OCW Release Update
This confirms that the Oracle Home is running 19.31 binaries and is ready for rollback.
Step 2: Perform OPatch Rollback
Rollback begins by shutting down all Oracle instances using the Oracle Home and executing:
./opatch rollback -id39034528
Oracle Interim Patch Installer version 12.2.0.1.51
Copyright (c) 2026, Oracle Corporation. All rights reserved.
Oracle Home : /u01/app/oracle/product/19.0.0
Central Inventory : /u01/app/oraInventory
from : /u01/app/oracle/product/19.0.0/oraInst.loc
OPatch version : 12.2.0.1.51
OUI version : 12.2.0.7.0
Log file location : /u01/app/oracle/product/19.0.0/cfgtoollogs/opatch/opatch2026-05-06_09-21-03AM_1.log
Patches will be rolled back in the following order:
39034528
The following patch(es) will be rolled back: 39034528
Please shutdown Oracle instances running out of this ORACLE_HOME on the local system.
(Oracle Home = '/u01/app/oracle/product/19.0.0')
Is the local system ready for patching? [y|n]
y
User Responded with: Y
Rolling back patch 39034528...
RollbackSession rolling back interim patch '39034528' from OH '/u01/app/oracle/product/19.0.0'
Patching component oracle.rdbms.util, 19.0.0.0.0...
Patching component oracle.rdbms.rsf, 19.0.0.0.0...
Patching component oracle.rdbms, 19.0.0.0.0...
Patching component oracle.assistants.acf, 19.0.0.0.0...
Patching component oracle.assistants.deconfig, 19.0.0.0.0...
Patching component oracle.assistants.server, 19.0.0.0.0...
Patching component oracle.blaslapack, 19.0.0.0.0...
Patching component oracle.buildtools.rsf, 19.0.0.0.0...
Patching component oracle.wwg.plsql, 19.0.0.0.0...
Patching component oracle.ctx, 19.0.0.0.0...
Patching component oracle.dbdev, 19.0.0.0.0...
Patching component oracle.dbjava.ic, 19.0.0.0.0...
Patching component oracle.dbjava.jdbc, 19.0.0.0.0...
Patching component oracle.dbjava.ucp, 19.0.0.0.0...
Patching component oracle.duma, 19.0.0.0.0...
Patching component oracle.javavm.client, 19.0.0.0.0...
Patching component oracle.ldap.client, 19.0.0.0.0...
Patching component oracle.ldap.owm, 19.0.0.0.0...
Patching component oracle.ldap.rsf, 19.0.0.0.0...
Patching component oracle.ldap.security.osdt, 19.0.0.0.0...
Patching component oracle.marvel, 19.0.0.0.0...
Patching component oracle.network.rsf, 19.0.0.0.0...
Patching component oracle.nlsrtl.rsf, 19.0.0.0.0...
Patching component oracle.nlsrtl.rsf.core, 19.0.0.0.0...
Patching component oracle.nlsrtl.rsf.ic, 19.0.0.0.0...
Patching component oracle.odbc.ic, 19.0.0.0.0...
Patching component oracle.ons, 19.0.0.0.0...
Patching component oracle.ons.ic, 19.0.0.0.0...
Patching component oracle.oracore.rsf, 19.0.0.0.0...
Patching component oracle.perlint, 5.28.1.0.0...
Patching component oracle.precomp.common.core, 19.0.0.0.0...
Patching component oracle.precomp.rsf, 19.0.0.0.0...
Patching component oracle.rdbms.crs, 19.0.0.0.0...
Patching component oracle.rdbms.dbscripts, 19.0.0.0.0...
Patching component oracle.rdbms.deconfig, 19.0.0.0.0...
Patching component oracle.rdbms.install.common, 19.0.0.0.0...
Patching component oracle.rdbms.oci, 19.0.0.0.0...
Patching component oracle.rdbms.rsf.ic, 19.0.0.0.0...
Patching component oracle.rdbms.scheduler, 19.0.0.0.0...
Patching component oracle.rhp.db, 19.0.0.0.0...
Patching component oracle.rsf, 19.0.0.0.0...
Patching component oracle.sdo, 19.0.0.0.0...
Patching component oracle.sdo.locator.jrf, 19.0.0.0.0...
Patching component oracle.sqlj.sqljruntime, 19.0.0.0.0...
Patching component oracle.sqlplus, 19.0.0.0.0...
Patching component oracle.sqlplus.ic, 19.0.0.0.0...
Patching component oracle.tfa.db, 19.0.0.0.0...
Patching component oracle.wwg.plsql, 19.0.0.0.0...
Patching component oracle.xdk.rsf, 19.0.0.0.0...
Patching component oracle.rdbms.hs_common, 19.0.0.0.0...
Patching component oracle.javavm.server, 19.0.0.0.0...
Patching component oracle.rdbms.install.plugins, 19.0.0.0.0...
Patching component oracle.rdbms.locator, 19.0.0.0.0...
Patching component oracle.oraolap.api, 19.0.0.0.0...
Patching component oracle.rdbms.hsodbc, 19.0.0.0.0...
Patching component oracle.network.client, 19.0.0.0.0...
Patching component oracle.rdbms.drdaas, 19.0.0.0.0...
Patching component oracle.rdbms.dm, 19.0.0.0.0...
Patching component oracle.rdbms.rman, 19.0.0.0.0...
Patching component oracle.rdbms.rat, 19.0.0.0.0...
Patching component oracle.ovm, 19.0.0.0.0...
Patching component oracle.odbc, 19.0.0.0.0...
Patching component oracle.xdk.server, 19.0.0.0.0...
Patching component oracle.oraolap.dbscripts, 19.0.0.0.0...
Patching component oracle.xdk.xquery, 19.0.0.0.0...
Patching component oracle.network.listener, 19.0.0.0.0...
Patching component oracle.dbtoolslistener, 19.0.0.0.0...
Patching component oracle.ldap.rsf.ic, 19.0.0.0.0...
Patching component oracle.xdk.parser.java, 19.0.0.0.0...
Patching component oracle.sdo.locator, 19.0.0.0.0...
Patching component oracle.ctx.rsf, 19.0.0.0.0...
Patching component oracle.ldap.ssl, 19.0.0.0.0...
Patching component oracle.oraolap, 19.0.0.0.0...
Patching component oracle.mgw.common, 19.0.0.0.0...
Patching component oracle.install.deinstalltool, 19.0.0.0.0...
Patching component oracle.rdbms.dv, 19.0.0.0.0...
Patching component oracle.xdk, 19.0.0.0.0...
Patching component oracle.nlsrtl.rsf.lbuilder, 19.0.0.0.0...
Patching component oracle.ctx.atg, 19.0.0.0.0...
Patching component oracle.network.aso, 19.0.0.0.0...
Patching component oracle.rdbms.lbac, 19.0.0.0.0...
Patching component oracle.precomp.lang, 19.0.0.0.0...
Patching component oracle.precomp.common, 19.0.0.0.0...
Patching component oracle.jdk, 1.8.0.201.0...
RollbackSession removing interim patch '39034528' from inventory
Inactive sub-set patch [37960098] has become active due to the rolling back of a super-set patch [39034528].
Please refer to Doc ID 2161861.1 for any possible further required actions.
Log file location: /u01/app/oracle/product/19.0.0/cfgtoollogs/opatch/opatch2026-05-06_09-21-03AM_1.log
OPatch succeeded.
Key Rollback Actions:
- Oracle Home validation
- Inventory updates
- Removal of patch 39034528
- Reactivation of previous patch 37960098
- Binary restoration to 19.28 level
Important Note:
During rollback, Oracle reported:
Inactive sub-set patch [37960098] has become active due to rolling back of super-set patch [39034528]
This indicates Oracle successfully restored the prior RU.
Step 3: Validate Patch Inventory Post-Rollback
After rollback:
./opatch lspatches
37960098;Database Release Update : 19.28.0.0.250715 (37960098)
29585399;OCW RELEASE UPDATE 19.3.0.0.0 (29585399)
Confirmed:
- 37960098 – Oracle Database Release Update 19.28
- 29585399 – OCW remains intact
At this point, Oracle binaries are downgraded, but SQL patch registry still requires synchronization.
Step 4: Run Datapatch Sanity Checks
Before SQL rollback:
./datapatch -sanity_checks
Findings:
./datapatch -sanity_checks
SQL Patching sanity checks version 19.28.0.0.0 on Wed 06 May 2026 10:32:17 AM +0530
Copyright (c) 2021, 2026, Oracle. All rights reserved.
Log file for this invocation: /u01/app/oracle/cfgtoollogs/sqlpatch/sanity_checks_20260506_103217_18649/sanity_checks_20260506_103217_18649.log
Running checks
JSON report generated in /u01/app/oracle/cfgtoollogs/sqlpatch/sanity_checks_20260506_103217_18649/sqlpatch_sanity_checks_summary.json file
Checks completed. Printing report:
Check: Database component status - OK
Check: PDB Violations - OK
Check: Invalid System Objects - OK
Check: Tablespace Status - OK
Check: Backup jobs - OK
Check: Temp file exists - OK
Check: Temp file online - OK
Check: Data Pump running - OK
Check: Container status - WARNING
Datapatch will only run in containers with READ WRITE, MIGRATE (upgrade) or READ ONLY mode.
Specified containers are not READ WRITE, MIGRATE or READ ONLY mode. When not opened, containers will not be a part of patching.
Open containers if they should take part of patching activities. Refer to the section "Modifying a PDB with the ALTER PLUGGABLE DATABASE Statement" in the Multitenant Administrator's Guide for details.
CDB$ROOT:
| HOST_NAME | NAME | OPEN_MODE |
|--------------+------+-----------|
| prod.mit.com | PDB | MOUNTED |
|--------------+------+-----------|
Check: Oracle Database Keystore - OK
Check: Dictionary statistics gathering - WARNING
Patching the database without recent data dictionary statistics gathered may lead to performance issues.
Data dictionary statistics are older than 7 days.
Run the following queries to start gathering the dictionary statistics:
EXEC DBMS_STATS.GATHER_DICTIONARY_STATS;
EXEC DBMS_SYSTEM.GATHER_FIXED_OBJECTS_STATS;
Refer to MOS 457926.1 for more details.
PDB$SEED:
| LATEST | OPERATION | STATUS |
|-----------------+-------------------------+-----------|
| 14-OCT-25 11:46 | gather_dictionary_stats | COMPLETED |
|-----------------+-------------------------+-----------|
Check: Scheduled Jobs - OK
Check: GoldenGate triggers - OK
Check: Logminer DDL triggers - OK
Check: Check sys public grants - OK
Check: Statistics gathering running - OK
Check: Optim dictionary upgrade parameter - OK
Check: Symlinks on oracle home path - OK
Check: Central Inventory - OK
Check: Java Virtual Machine Enable - OK
Check: Oracle Database Vault Enabled - OK
Check: Queryable Inventory database directories - OK
Check: Queryable Inventory locks - OK
Check: Queryable Inventory package - OK
Check: Queryable Inventory external table - OK
Check: Imperva processes - OK
Check: Guardium processes - OK
Check: Locale - OK
Refer to MOS Note 2975965.1 and debug log
/u01/app/oracle/cfgtoollogs/sqlpatch/sanity_checks_20260506_103217_18649/sanity_checks_debug_20260506_103217_18649.log
SQL Patching sanity checks completed on Wed 06 May 2026 10:32:21 AM +0530
Healthy Checks:
- Database component status OK
- PDB violations OK
- Invalid objects OK
- Tablespace status OK
- Backup jobs OK
- Temp files valid
- Java VM enabled
- Inventory integrity confirmed
Warnings:
1. Mounted PDB
One pluggable database remained in MOUNTED mode and would be skipped during patching.
Recommendation: Open all required PDBs before datapatch if SQL rollback must apply there.
2. Outdated Dictionary Statistics
Oracle warned dictionary stats were older than 7 days.
Recommended commands:
EXEC DBMS_STATS.GATHER_DICTIONARY_STATS;
EXEC DBMS_SYSTEM.GATHER_FIXED_OBJECTS_STATS;
This is important for maintaining optimizer performance after patch transitions.
Step 5: Execute Datapatch Rollback
Run:
./datapatch -verbose
Datapatch Actions:
- Connected successfully to database
- Detected SQL registry mismatch
- Rolled back SQL changes from 19.31 to 19.28
- Updated:
- CDB$ROOT
- PDB$SEED
- Skipped mounted PDBs
Results:
- CDB$ROOT rollback: SUCCESS
- PDB$SEED rollback: SUCCESS
- No errors reported
This ensures Oracle dictionary metadata aligns with the downgraded binary version.
Critical Lessons Learned
1. Binary Rollback Alone Is Not Enough
Many administrators stop after OPatch rollback, but SQL patch registry must also be reverted using Datapatch.
2. Always Check PDB Status
Closed or mounted PDBs will not receive SQL rollback.
3. Gather Fresh Dictionary Statistics
Ignoring optimizer statistics may create performance regressions.
4. Validate Inventory Thoroughly
Always confirm:
opatch lspatchesdatapatch -sanity_checksdatapatch -verbose
5. Keep Full Backup Before Rollback
Rollback should always be supported by:
- RMAN backups
- Filesystem snapshots
- Recovery plans
Best Practices for Oracle RU Rollbacks
Pre-Rollback Checklist:
- Confirm patch inventory
- Backup Oracle Home
- Backup database
- Notify stakeholders
- Validate cluster dependencies
- Stop all Oracle services
Post-Rollback Checklist:
- Validate binary version
- Run datapatch rollback
- Open all PDBs
- Gather dictionary stats
- Recompile invalid objects
- Review alert logs
- Conduct application testing
Common Risks During Rollback
| Risk | Impact | Mitigation |
|---|---|---|
| Skipped PDBs | SQL inconsistency | Open PDBs before datapatch |
| Missing backups | Recovery failure | Full backup strategy |
| Inventory corruption | Patch instability | Validate with OPatch |
| Outdated stats | Performance issues | Gather dictionary stats |
| Service downtime | Business disruption | Maintenance window planning |
Final Thoughts
Oracle patch rollback is a sensitive but essential skill for enterprise DBAs. This Oracle 19.31 to 19.28 rollback demonstrates a structured recovery path that preserves database stability while ensuring SQL and binary consistency.
By following a disciplined rollback process using OPatch and Datapatch, organizations can quickly recover from patching complications while minimizing operational risk.
For production systems, rollback should always be treated as part of broader disaster recovery and change management strategies.
A well-tested rollback plan is just as important as the patch itself.




