Overview
This article documents a complete Oracle Database 19c Standard Edition 2 patch cycle from baseline validation through final SQL registry confirmation. The database was patched from 19.31.0.0.0 to 19.32.0.0.260721 using the July 2026 release update bundle.
The value of this walkthrough is not just the successful outcome, but the operational details, timing, troubleshooting observations, and the superset/subset patch behavior that often confuses teams in real patching scenarios.
Environment Baseline
Database: Production DB Instance
Role: PRIMARY
Open Mode: READ WRITE
Database Version: 19.31.0.0.0
Edition: Standard Edition 2
OPatch Version (at session start): 12.2.0.1.52
Database Home: /oracle/app/product/db_home/19c/instance
Grid Home: /oracle/app/product/grid/19c_home
OPatch had been upgraded to 12.2.0.1.52 prior to beginning the patching sequence.
Section 1: Pre-Patching Validation
Database Status Check
SQL> select name, open_mode, database_role from v\$database;
NAME OPEN_MODE DATABASE_ROLE
--------- ----------- ----------------
PRODDB READ WRITE PRIMARY
Observation: Database is healthy and accessible at start.
Existing Patches
The database carried three active patches from the April/July 2026 cycle:
38906621 OJVM RELEASE UPDATE: 19.31.0.0.260421
39039430 OCW RELEASE UPDATE 19.31.0.0.0
39034528 Database Release Update: 19.31.0.0.260421
Pre-Existing Invalid Objects
The following query revealed 10 invalid objects, all under the DEVELOPMENT schema with modification dates ranging from 2021–2025:
SQL> select object_name, object_type, owner, created
from dba_objects
where status = 'INVALID'
order by owner, object_name;
OBJECT_NAME OBJECT_TYPE OWNER CREATED
------------------- ------------- ------------ ----------
<object list> <type> DEVELOPMENT 2021–2025
Importance of this baseline: These invalid objects predate the patch session. Documenting them prevents incorrectly attributing them to patching activity. At post-patching validation, we will confirm they remain unchanged.
Section 2: Crontab Protection
Before any Grid or database activity, the existing Oracle crontab was reviewed and protected.
The crontab contained:
- RMAN backups
- Archive backups
- Health checks
- FRA space checks
- Log cleanup routines
- CPU alerting
- TechBoost startup
Crontab Protection Command:
/usr/bin/crontab -l | /bin/sed 's/^/##JULY_2026##&/g' | /usr/bin/crontab
This prefixes every crontab entry with ##JULY_2026##, effectively disabling all scheduled jobs while preserving them for rollback. This is a critical operational detail often overlooked in patching procedures. The surrounding infrastructure — backups, health checks, monitoring — must be accounted for, not just the Oracle binaries.
Section 3: Database Shutdown
The database was cleanly shut down before any Grid Home maintenance:
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
TNS processes were verified afterward to confirm a clean state.
Section 4: CRS/HAS Lifecycle Management
Initial CRS Status Check
$ ./crsctl check crs
All major CRS components reported online.
Stopping HAS
$ ./crsctl stop has
CRS-4133: Oracle High Availability Services has been stopped.
Subsequent check:
$ ./crsctl check crs
CRS-4639: Could not contact Oracle High Availability Services
Restarting HAS
$ ./crsctl start has
CRS-4638: Oracle High Availability Services is online
Initial state after restart (first check):
CRS-4638: Oracle High Availability Services is online
CRS-4535: Cannot communicate with Cluster Ready Services
CRS-4530: Communications failure contacting Cluster Synchronization Services daemon
CRS-4534: Cannot communicate with Event Manager
Key observation: An immediate crsctl check crs after crsctl start has should NOT be interpreted as a failure. CRS components require time to establish quorum and synchronize.
Final state (repeated checks):
CRS-4638: Oracle High Availability Services is online
CRS-4537: Cluster Ready Services is online
CRS-4529: Cluster Synchronization Services is online
CRS-4533: Event Manager is online
Teaching point: This is a real troubleshooting scenario. Patience during CRS startup is required. A few seconds of “Cannot communicate” messages are normal before full synchronization.
Section 5: Grid Infrastructure Patching — Node 1
Patch Bundle
/backup/install/JULY2026/39618711/39467003
OPatchAuto Execution
\$GRID_HOME/OPatch/opatchauto apply \
/path/to/patch/bundle/39618711/39467003 \
-oh \$GRID_HOME
Session Start: 20:17:54
Session Flow:
- Prerequisite checks → PASSED
- Patch validation → PASSED
- CRS brought down
- Binary patch applied
- rootadd_rdbms.sh executed
- CRS restarted
Patches Applied
39472050
39503034
39526364
Patches Skipped
39107825
39107855
Reason: Not required for this Grid Home. OPatchAuto intelligently determines applicability per Grid Home.
Session End: 20:39:13
Duration: 21 minutes, 13 seconds
Section 6: Grid Infrastructure Patching — Node 2
OPatchAuto Execution (Node 2)
Same Grid Home, same patch bundle, Node 2:
\$GRID_HOME/OPatch/opatchauto apply \
/path/to/patch/bundle/39618711/39467003 \
-oh \$GRID_HOME
Session ID: CHM5
Session Start: 20:53:18
Session Flow:
- Prerequisite checks → PASSED
- Patch validation checks → PASSED
- CRS brought down
- Binary patch applied
- rootadd_rdbms.sh executed
- CRS restarted
Patches Applied (Node 2)
39472050
39503034
39526364
Patches Skipped (Node 2)
39107825
39107855
Reason: Same as Node 1 — not required for this Grid Home configuration.
Session End: 21:18:43
Duration: 25 minutes, 15 seconds
Section 7: Database Home Patching
OPatchAuto Against Database Home
\$ORACLE_HOME/OPatch/opatchauto apply \
/path/to/patch/bundle/39618711/39467003 \
-oh \$ORACLE_HOME
Prerequisite Checks
Patch applicability verified successfully
Patch validation checks successfully completed
Patch Application Log
Prepatch operation completed successfully
Binary patch applied successfully
rootadd_rdbms.sh successfully executed
Postpatch operation completed successfully
Patches Skipped
The following were skipped because they are not applicable to the database target type:
39503034
39107825
39107855
Reason: This patch is not applicable to this specified target type - "rac_database"
Important teaching point: A patch bundle often contains patches for multiple target types (Grid, database, RAC, single-instance, etc.). OPatchAuto filters and applies only those applicable to the target. A skipped patch is not a failure condition; it is correct filtering behavior.
Section 8: Manual OJVM Patching — The Superset/Subset Moment
This is the most valuable part of the patching narrative.
Applying OJVM Patch 39222882
opatch apply -id 39222882
Confirmation:
Patch 39222882 successfully applied.
Sub-set patch [38906621] has become inactive
due to the application of a super-set patch [39222882].
Understanding Superset/Subset Behavior
Previous OJVM patch:
38906621 OJVM 19.31.0.0.260421
New OJVM patch:
39222882 OJVM 19.32.0.0.260721
Patch 39222882 is a superset of 38906621. When the superset is applied, OPatch automatically marks the old subset patch as inactive. The old patch is still in the patch inventory, but is no longer in effect.
This is critical to understand: you will not see an explicit opatch rollback 38906621 command. Instead, the superset patch absorbs the functionality, and the subset becomes inactive. The SQL layer (datapatch) later rolls back the subset formally, but the binary layer handles it through superset supersession.
Section 9: Database Startup After OJVM Binary Patch
After applying 39222882, the database was started:
SQL> startup;
Database mounted.
Database opened.
SQL*Plus version verification:
Version 19.32.0.0.0
The database came up cleanly on the new binary.
Section 10: datapatch — SQL Layer Patch Application
The SQL layer patching is where the logical consistency is established:
cd \$ORACLE_HOME/OPatch
./datapatch -verbose
datapatch Analysis
- Old OJVM patch: 38906621
- New OJVM patch: 39222882
- New RU: 39472050
Installation Queue
Based on the above, datapatch constructed the following queue:
Rollback:
38906621
Apply:
39472050
39222882
Execution Results
Patch 38906621 rollback: SUCCESS
Patch 39472050 apply: SUCCESS
Patch 39222882 apply: SUCCESS
No errors in the corresponding SQL patch logs.
Teaching point: This is the orchestration that many DBAs find confusing. The binary layer and the SQL layer operate in sequence:
- Binary layer (OPatchAuto): Applies 39222882, marks 38906621 as inactive
- SQL layer (datapatch): Detects this change, formally rolls back 38906621 from the data dictionary, then applies 39472050 and 39222882 at the SQL level
The two layers must synchronize. datapatch handles this automatically, but understanding the sequence prevents misinterpretation of the logs.
Section 11: Final Patch Levels
opatch lspatches Output
39222882;OJVM RELEASE UPDATE: 19.32.0.0.260721
39526364;OCW RELEASE UPDATE 19.32.0.0.0
39472050;Database Release Update: 19.32.0.0.260721
State Transition Summary
| Component | Before | After |
|---|---|---|
| Database RU | 19.31.0.0.260421 | 19.32.0.0.260721 |
| OJVM | 19.31.0.0.260421 | 19.32.0.0.260721 |
| OCW | 19.31.0.0.0 | 19.32.0.0.0 |
Section 12: SQL Patch Registry Verification
Final DBA_REGISTRY_SQLPATCH output:
38906621 ROLLBACK SUCCESS 31-AUG-26 09:02:48 PM
39222882 APPLY SUCCESS 31-AUG-26 09:02:59 PM
39472050 APPLY SUCCESS 31-AUG-26 09:03:55 PM
This chronological sequence provides irrefutable proof:
- Old OJVM patch rolled back at 09:02:48 PM
- New OJVM patch applied 11 seconds later at 09:02:59 PM
- Database RU applied at 09:03:55 PM
No conflicts. Clean transition.
Section 13: Final Component Validation
DBA_REGISTRY Check
SQL> select comp_name, status
from dba_registry
order by comp_name;
COMP_NAME STATUS
---------------------- -------
CATALOG VALID
CATPROC VALID
JAVAVM VALID
XML VALID
CATJAVA VALID
CONTEXT VALID
XDB VALID
ORDIM VALID
APEX VALID
All critical components report VALID. Optional components show OPTION OFF where applicable.
Pre-Existing Objects Revisited
The 10 invalid objects identified in pre-patching validation remained unchanged — still invalid, still dated 2021–2025, still under the DEVELOPMENT schema. No new invalid objects were introduced by patching.
Section 14: Lessons from Real Execution
Not everything is shown in the logs. During the session, there was an operator mistake:
After exiting SQL*Plus, the following commands were inadvertently entered at the bash prompt instead of within SQL*Plus:
Set lines 230
col ...
select ...
Result:
bash: Set: command not found
col: bad usage
bash: syntax error near unexpected token
This is not an Oracle patching failure. It was simply commands executed in the wrong shell context. The log was corrected, commands were re-entered in SQL*Plus, and execution continued without issue.
Why include this: This makes the article realistic. Patching sessions involve multiple shells, multiple environments, and context switching. Showing the actual mistake and recovery is more valuable than hiding it. It serves as a quiet reminder to teams that operational discipline — knowing which shell you’re in, which home you’ve sourced, which user you’re running as — is as important as the patch commands themselves.
Section 15: Conclusion
The patching session was completed successfully from baseline validation through final registry confirmation. Total elapsed time across all phases was approximately 46 minutes (20:17 to 21:18, accounting for Node 2 completion).
Key takeaways:
- Baseline matters: Document pre-existing conditions (invalid objects, patch levels, cron jobs) to avoid misattribution later.
- Infrastructure protection: Patching isn’t just about binaries. Protect cron jobs, backups, and monitoring to prevent unintended outages during the maintenance window.
- CRS behavior is asynchronous: After
crsctl start has, components come online gradually. Immediatecrsctl check crsshowing “Cannot communicate” is normal and not actionable. - Patch applicability is intelligent: OPatchAuto skips patches that don’t apply to the target type. This is not a failure.
- Superset/subset is binary-layer behavior: When a superset patch is applied, the subset becomes inactive at the binary layer. The SQL layer (datapatch) handles the formal rollback.
- datapatch orchestrates across layers: The SQL layer patch tool detects binary changes and constructs the correct rollback/apply queue automatically. Trust the tool.
- Real execution has missteps: Shell context errors, timing observations, and troubleshooting moments are part of the work. Documenting them makes the guidance actionable for other teams.
The database is now on 19.32.0.0.260721 with all components validated.
Leave a comment