Oracle Database 19c July 2026 Release Update Patching: Real-World Walkthrough

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:

  1. Prerequisite checks → PASSED
  2. Patch validation → PASSED
  3. CRS brought down
  4. Binary patch applied
  5. rootadd_rdbms.sh executed
  6. 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:

  1. Prerequisite checks → PASSED
  2. Patch validation checks → PASSED
  3. CRS brought down
  4. Binary patch applied
  5. rootadd_rdbms.sh executed
  6. 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:

  1. Binary layer (OPatchAuto): Applies 39222882, marks 38906621 as inactive
  2. 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

ComponentBeforeAfter
Database RU19.31.0.0.26042119.32.0.0.260721
OJVM19.31.0.0.26042119.32.0.0.260721
OCW19.31.0.0.019.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:

  1. Old OJVM patch rolled back at 09:02:48 PM
  2. New OJVM patch applied 11 seconds later at 09:02:59 PM
  3. 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:

  1. Baseline matters: Document pre-existing conditions (invalid objects, patch levels, cron jobs) to avoid misattribution later.
  2. Infrastructure protection: Patching isn’t just about binaries. Protect cron jobs, backups, and monitoring to prevent unintended outages during the maintenance window.
  3. CRS behavior is asynchronous: After crsctl start has, components come online gradually. Immediate crsctl check crs showing “Cannot communicate” is normal and not actionable.
  4. Patch applicability is intelligent: OPatchAuto skips patches that don’t apply to the target type. This is not a failure.
  5. 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.
  6. datapatch orchestrates across layers: The SQL layer patch tool detects binary changes and constructs the correct rollback/apply queue automatically. Trust the tool.
  7. 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.


Discover more from Syed Anwar Ahmed – Oracle DBA Blog

Subscribe to get the latest posts sent to your email.

Comments

Leave a comment

Discover more from Syed Anwar Ahmed – Oracle DBA Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading