Showing posts with label 19c. Show all posts
Showing posts with label 19c. Show all posts

May 1, 2026

Shell Script to Automate Oracle 19c TDE Wallet & sqlnet.ora Backups

 

Recently, one of my junior colleague had a requirement to clone a production database. While doing so he faced the following error while opening the database

ORA-28374: typed master key not found in wallet
ORA-00704: bootstrap process failure

 

The Production database had TDE enabled  so it was obvious oracle will look for the wallet before opening the database.

Now this is a situation where no tricks or workaround would work unless the correct wallet(ewallet.p12 ) is provided.

Thankfully , we have been following a practice to keep our wallet backup as part of backup strategy. This is very critical in case TDE is enabled and should be adopted by DBA’s .

Sharing the shell script we are using  for taking wallet backup . This script also takes backup of sqlnet.ora which is also important.

#!/bin/bash

# ==============================================================================

# Script Name: wallet_backup.sh

# Description: Backs up Oracle TDE wallet files AND sqlnet.ora with retention.

# Run as:      oracle user

# ==============================================================================

 

# Load Oracle environment variables (CRITICAL FOR CRON JOBS)

. ~/.bash_profile

 

# --- Configuration Variables ---

# The active wallet location

WALLET_DIR="/opt/oracle/dcs/commonstore/wallets/prddb_dsmc19c/tde"

 

# Location of sqlnet.ora (Uses the standard ORACLE_HOME network path)

SQLNET_FILE="$ORACLE_HOME/network/admin/sqlnet.ora"

 

# The destination for the backups

BACKUP_DEST="/u01/backup/wallet_bkp"

 

# How many days to keep old backups

RETENTION_DAYS=30

 

# Generate a timestamp for the filenames (Format: YYYYMMDD_HHMMSS)

TIMESTAMP=$(date +"%Y%m%d_%H%M%S")

LOG_FILE="${BACKUP_DEST}/wallet_backup_${TIMESTAMP}.log"

 

# --- Pre-flight Checks ---

# Ensure destination directory exists

mkdir -p "$BACKUP_DEST"

 

echo "==================================================" | tee -a "$LOG_FILE"

echo " Starting TDE Wallet & Config Backup at $(date)" | tee -a "$LOG_FILE"

echo " Destination: $BACKUP_DEST" | tee -a "$LOG_FILE"

echo "==================================================" | tee -a "$LOG_FILE"

 

# --- Backup Execution ---

echo "Copying files..." | tee -a "$LOG_FILE"

 

# 1. Backup ewallet.p12

if [ -f "${WALLET_DIR}/ewallet.p12" ]; then

    cp -p "${WALLET_DIR}/ewallet.p12" "${BACKUP_DEST}/ewallet_${TIMESTAMP}.p12"

    echo " -> SUCCESS: ewallet.p12 backed up." | tee -a "$LOG_FILE"

else

    echo " -> WARNING: ewallet.p12 NOT FOUND in $WALLET_DIR." | tee -a "$LOG_FILE"

fi

 

# 2. Backup cwallet.sso

if [ -f "${WALLET_DIR}/cwallet.sso" ]; then

    cp -p "${WALLET_DIR}/cwallet.sso" "${BACKUP_DEST}/cwallet_${TIMESTAMP}.sso"

    echo " -> SUCCESS: cwallet.sso backed up." | tee -a "$LOG_FILE"

else

    echo " -> WARNING: cwallet.sso NOT FOUND in $WALLET_DIR." | tee -a "$LOG_FILE"

fi

 

# 3. Backup sqlnet.ora

if [ -f "$SQLNET_FILE" ]; then

    cp -p "$SQLNET_FILE" "${BACKUP_DEST}/sqlnet_${TIMESTAMP}.ora"

    echo " -> SUCCESS: sqlnet.ora backed up." | tee -a "$LOG_FILE"

else

    echo " -> WARNING: sqlnet.ora NOT FOUND at $SQLNET_FILE." | tee -a "$LOG_FILE"

fi

 

# --- Housekeeping (Retention Policy) ---

echo "Cleaning up backups older than $RETENTION_DAYS days..." | tee -a "$LOG_FILE"

 

find "$BACKUP_DEST" -name "ewallet_*.p12" -type f -mtime +$RETENTION_DAYS -exec rm -f {} \;

find "$BACKUP_DEST" -name "cwallet_*.sso" -type f -mtime +$RETENTION_DAYS -exec rm -f {} \;

find "$BACKUP_DEST" -name "sqlnet_*.ora" -type f -mtime +$RETENTION_DAYS -exec rm -f {} \;

find "$BACKUP_DEST" -name "wallet_backup_*.log" -type f -mtime +$RETENTION_DAYS -exec rm -f {} \;

 

echo "Cleanup complete." | tee -a "$LOG_FILE"

echo "Backup process finished at $(date)" | tee -a "$LOG_FILE"

echo "==================================================" | tee -a "$LOG_FILE"

 

 

Automate the script via cronjob

[oracle@prddb ~]$ crontab -e

0 1 * * * /u01/backup/scripts/wallet_backup.sh

 

 

 

April 15, 2026

How to Patch Oracle 19c to Release 19.30 on Windows – A Complete Step-by-Step Blog

 

As soon as  Oracle released quarterly patch for Jan 2026 , I had to patch one of my Oracle 19c databases from 19.25 to 19.30. Since this is something we DBAs do almost on every quarter, I decided to write down the exact steps I followed. The procedures are the same for all 19c versions.

Note: On production systems, always apply on test/dev first. Never patch production directly without testing!

Prerequisites

  • Oracle 19c database installed on Windows x86-64
  • Access to Oracle Support (MOS account)
  • OS user with ORACLE_HOME and ORACLE_BASE permissions
  • At least 12 GB free disk space in oracle_home directory
  • WinSCP or similar tool to transfer files to the server
  • Scheduled maintenance window (database downtime required)

 

Step 1: Download the Patch and OPatch Utility

Log in to Oracle Support and download the following:

  • Patch file: 38597735 → p38597735_190000_MSWIN-x86-64.zip
  • OPatch utility: 6880880 → p6880880_190000_MSWIN -x86-64.zip

Steps to download: Select Patches & Updates → enter patch number → select platform Windows x86-64 → download both files and review the README.

 

Step 2: Check and Update OPatch

On the server, check your current OPatch version:

cd %ORACLE_HOME%/OPatch

opatch version

 

 

You need version 12.2.0.1.48 or higher. If it's older, update it:

cd %ORACLE_HOME%

ren OPatch OPatch_backup1

robocopy p6880880_190000_MSWIN -x86-64.zip   %ORACLE_HOME%

cd %ORACLE_HOME%

unzip p6880880_190000_MSWIN -x86-64.zip

 

 

Step 3: Run Pre-checks

Before applying the patch, check for conflicts with existing patches:

C:\Users\Administrator>cd C:\software\oracle_patch_19.30\38597735

 

C:\software\oracle_patch_19.30\38597735>D:\oracle\product\19.3.0\dbhome_1\OPatch\opatch prereq CheckConflictAgainstOHWithDetail -ph ./

Oracle Interim Patch Installer version 12.2.0.1.49

Copyright (c) 2026, Oracle Corporation.  All rights reserved.

 

PREREQ session

 

Oracle Home       : D:\oracle\product\19.3.0\dbhome_1

Central Inventory : C:\Program Files\Oracle\Inventory

   from           :

OPatch version    : 12.2.0.1.49

OUI version       : 12.2.0.7.0

Log file location : D:\oracle\product\19.3.0\dbhome_1\cfgtoollogs\opatch\opatch2026-04-14_19-40-37PM_1.log

 

Invoking prereq "checkconflictagainstohwithdetail"

 

Prereq "checkConflictAgainstOHWithDetail" passed.

 

OPatch succeeded.

 

As we see "OPatch succeeded", we are good to go. If there are conflicts, resolve them before proceeding.

Step 4: Stop the Database and Listener

sqlplus / as sysdba

 

SQL> shutdown immediate

SQL> exit

 

lsnrctl stop

 

 

Verify all services are completely down before moving to the next step.

Step 5: Clean Up Inactive Patches (Optional but Recommended)

This frees up Oracle Home space before applying the new patch:

cd %ORACLE_HOME%/OPatch

./opatch util listOrderedInactivePatches

./opatch util deleteInactivePatches

 

 

Step 6: Check Available Disk Space

Do not proceed if space is insufficient in oracle home

Step 7: Apply the Patch

C:\software\oracle_patch_19.30\38597735>D:\oracle\product\19.3.0\dbhome_1\OPatch\opatch apply

Oracle Interim Patch Installer version 12.2.0.1.49

Copyright (c) 2026, Oracle Corporation.  All rights reserved.

 

 

Oracle Home       : D:\oracle\product\19.3.0\dbhome_1

Central Inventory : C:\Program Files\Oracle\Inventory

   from           :

OPatch version    : 12.2.0.1.49

OUI version       : 12.2.0.7.0

Log file location : D:\oracle\product\19.3.0\dbhome_1\cfgtoollogs\opatch\opatch2026-04-14_19-41-27PM_1.log

 

Verifying environment and performing prerequisite checks...

 

--------------------------------------------------------------------------------

Start OOP by Prereq process.

Launch OOP...

 

Oracle Interim Patch Installer version 12.2.0.1.49

Copyright (c) 2026, Oracle Corporation.  All rights reserved.

 

 

Oracle Home       : D:\oracle\product\19.3.0\dbhome_1

Central Inventory : C:\Program Files\Oracle\Inventory

   from           :

OPatch version    : 12.2.0.1.49

OUI version       : 12.2.0.7.0

Log file location : D:\oracle\product\19.3.0\dbhome_1\cfgtoollogs\opatch\opatch2026-04-14_19-44-33PM_1.log

 

Verifying environment and performing prerequisite checks...

OPatch continues with these patches:   38597735

 

Do you want to proceed? [y|n]

y

User Responded with: Y

All checks passed.

 

Please shutdown Oracle instances running out of this ORACLE_HOME on the local system.

(Oracle Home = 'D:\oracle\product\19.3.0\dbhome_1')

 

 

Is the local system ready for patching? [y|n]

y

User Responded with: Y

Backing up files...

Applying interim patch '38597735' to OH 'D:\oracle\product\19.3.0\dbhome_1'

ApplySession: Optional component(s) [ oracle.tomcat.crs, 19.0.0.0.0 ] , [ oracle.has.cfs, 19.0.0.0.0 ] , [ oracle.rdbms.tg4msql, 19.0.0.0.0 ] , [ oracle.rdbms.ic, 19.0.0.0.0 ] , [ oracle.rdbms.tg4ifmx, 19.0.0.0.0 ] , [ oracle.network.cman, 19.0.0.0.0 ] , [ oracle.has.deconfig, 19.0.0.0.0 ] , [ oracle.network.gsm, 19.0.0.0.0 ] , [ oracle.assistants.asm, 19.0.0.0.0 ] , [ oracle.wlm.dbwlm, 19.0.0.0.0 ] , [ oracle.rhp.crs, 19.0.0.0.0 ] , [ oracle.has.cvu, 19.0.0.0.0 ] , [ oracle.tfa, 19.0.0.0.0 ] , [ oracle.rdbms.tg4sybs, 19.0.0.0.0 ] , [ oracle.usm, 19.0.0.0.0 ] , [ oracle.ons.daemon, 19.0.0.0.0 ] , [ oracle.rdbms.tg4tera, 19.0.0.0.0 ] , [ oracle.options.olap, 19.0.0.0.0 ] , [ oracle.assistants.usm, 19.0.0.0.0 ] , [ oracle.rdbms.tg4db2, 19.0.0.0.0 ] , [ oracle.options.olap.awm, 19.0.0.0.0 ] , [ oracle.has.crs, 19.0.0.0.0 ]  not present in the Oracle Home or a higher version is found.

 

Patching component oracle.has.common.cvu, 19.0.0.0.0...

 

Patching component oracle.has.rsf, 19.0.0.0.0...

 

Patching component oracle.assistants.server, 19.0.0.0.0...

 

Patching component oracle.ons, 19.0.0.0.0...

 

Patching component oracle.rdbms.plsql, 19.0.0.0.0...

 

Patching component oracle.rdbms.util, 19.0.0.0.0...

 

Patching component oracle.sqlplus.ic, 19.0.0.0.0...

 

Patching component oracle.sdo.locator.jrf, 19.0.0.0.0...

 

Patching component oracle.perlint, 5.28.1.0.0...

 

Patching component oracle.swd.oui.core.min, 12.2.0.7.0...

 

Patching component oracle.sqlplus, 19.0.0.0.0...

 

Patching component oracle.dbjava.jdbc, 19.0.0.0.0...

 

Patching component oracle.network.listener, 19.0.0.0.0...

 

Patching component oracle.odbc.ic, 19.0.0.0.0...

 

Patching component oracle.rdbms.rman, 19.0.0.0.0...

 

Patching component oracle.dbjava.ucp, 19.0.0.0.0...

 

Patching component oracle.perlint.modules, 5.28.1.0.0...

 

Patching component oracle.precomp.common.core, 19.0.0.0.0...

 

Patching component oracle.oracore.rsf, 19.0.0.0.0...

 

Patching component oracle.ntoledb.odp_net_2, 19.0.0.0.0...

 

Patching component oracle.has.db, 19.0.0.0.0...

 

Patching component oracle.ntoramts, 19.0.0.0.0...

 

Patching component oracle.marvel, 19.0.0.0.0...

 

Patching component oracle.xdk.parser.java, 19.0.0.0.0...

 

Patching component oracle.network.client, 19.0.0.0.0...

 

Patching component oracle.blaslapack, 19.0.0.0.0...

 

Patching component oracle.tfa.db, 19.0.0.0.0...

 

Patching component oracle.ctx, 19.0.0.0.0...

 

Patching component oracle.rdbms.hsodbc, 19.0.0.0.0...

 

Patching component oracle.ldap.rsf, 19.0.0.0.0...

 

Patching component oracle.assistants.deconfig, 19.0.0.0.0...

 

Patching component oracle.sqlj.sqljruntime, 19.0.0.0.0...

 

Patching component oracle.ldap.owm, 19.0.0.0.0...

 

Patching component oracle.duma, 19.0.0.0.0...

 

Patching component oracle.precomp.lang, 19.0.0.0.0...

 

Patching component oracle.ntoledb, 19.0.0.0.0...

 

Patching component oracle.rdbms.rsf, 19.0.0.0.0...

 

Patching component oracle.rdbms.install.common, 19.0.0.0.0...

 

Patching component oracle.ldap.security.osdt, 19.0.0.0.0...

 

Patching component oracle.sdo, 19.0.0.0.0...

 

Patching component oracle.rdbms.rsf.ic, 19.0.0.0.0...

 

Patching component oracle.wwg.plsql, 19.0.0.0.0...

 

Patching component oracle.rdbms.lbac, 19.0.0.0.0...

 

Patching component oracle.oraolap, 19.0.0.0.0...

 

Patching component oracle.precomp.rsf, 19.0.0.0.0...

 

Patching component oracle.ntoledbolap, 19.0.0.0.0...

 

Patching component oracle.assistants.acf, 19.0.0.0.0...

 

Patching component oracle.rhp.common, 19.0.0.0.0...

 

Patching component oracle.javavm.server, 19.0.0.0.0...

 

Patching component oracle.precomp.common, 19.0.0.0.0...

 

Patching component oracle.network.rsf, 19.0.0.0.0...

 

Patching component oracle.ovm, 19.0.0.0.0...

 

Patching component oracle.install.deinstalltool, 19.0.0.0.0...

 

Patching component oracle.rdbms.oci, 19.0.0.0.0...

 

Patching component oracle.rsf, 19.0.0.0.0...

 

Patching component oracle.clrintg.ode_net_2, 19.0.0.0.0...

 

Patching component oracle.nlsrtl.rsf, 19.0.0.0.0...

 

Patching component oracle.xdk.server, 19.0.0.0.0...

 

Patching component oracle.rdbms.install.plugins, 19.0.0.0.0...

 

Patching component oracle.ctx.atg, 19.0.0.0.0...

 

Patching component oracle.javavm.client, 19.0.0.0.0...

 

Patching component oracle.oraolap.dbscripts, 19.0.0.0.0...

 

Patching component oracle.rdbms.deconfig, 19.0.0.0.0...

 

Patching component oracle.dbjava.ic, 19.0.0.0.0...

 

Patching component oracle.rdbms.dv, 19.0.0.0.0...

 

Patching component oracle.aspnet_2, 19.0.0.0.0...

 

Patching component oracle.ldap.client, 19.0.0.0.0...

 

Patching component oracle.usm.deconfig, 19.0.0.0.0...

 

Patching component oracle.dbdev, 19.0.0.0.0...

 

Patching component oracle.ons.ic, 19.0.0.0.0...

 

Patching component oracle.mgw.common, 19.0.0.0.0...

 

Patching component oracle.oracler.server, 19.0.0.0.0...

 

Patching component oracle.has.common, 19.0.0.0.0...

 

Patching component oracle.xdk.rsf, 19.0.0.0.0...

 

Patching component oracle.xdk, 19.0.0.0.0...

 

Patching component oracle.rdbms.dbscripts, 19.0.0.0.0...

 

Patching component oracle.rdbms.olap, 19.0.0.0.0...

 

Patching component oracle.rdbms, 19.0.0.0.0...

 

Patching component oracle.sdo.locator, 19.0.0.0.0...

 

Patching component oracle.rdbms.scheduler, 19.0.0.0.0...

 

Patching component oracle.xdk.xquery, 19.0.0.0.0...

 

Patching component oracle.nlsrtl.rsf.lbuilder, 19.0.0.0.0...

 

Patching component oracle.jdk, 1.8.0.201.0...

Patch 38597735 successfully applied.

Sub-set patch [36878821] has become inactive due to the application of a super-set patch [38597735].

Please refer to Doc ID 2161861.1 for any possible further required actions.

Log file location: D:\oracle\product\19.3.0\dbhome_1\cfgtoollogs\opatch\opatch2026-04-14_19-44-33PM_1.log

 

OPatch succeeded.

 

Watch the output carefully. You should see success messages for each component. The full process typically takes 20–30 minutes.

Sample successful output as above.

 

Step 8: Start the Database and Run DataPatch

Start the database first:

sqlplus / as sysdba

 

SQL> startup

 

 

 

Then run DataPatch to register the patch inside the database dictionary:

cd %ORACLE_HOME%/OPatch

datapatch -verbose

 

 

This step is mandatory — without it the patch is applied at the binary level but not registered in the database.

 

Step 9: Verify the Patch

April 6, 2026

How to Change MAX_STRING_SIZE in a PDB (Oracle 19c Step-by-Step Guide)

 

Changing MAX_STRING_SIZE in a PDB (What Worked for Me)

I recently had to deal with a requirement where the application team wanted to store larger strings in the database. The usual 4000-byte limit wasn’t enough, so the only option was to switch MAX_STRING_SIZE to EXTENDED.

At first I thought it would be a quick change… but in a PDB setup, it’s not that straightforward. I actually had to redo a part of it because I missed the seed step

So sharing the exact steps that worked for me.

 

Step 1: Check Current Setting

First thing I checked was:

SQL> show parameter string_size

 

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------

max_string_size string STANDARD

 

It was STANDARD, which is expected in most environments.

 

Step 2: Close and Open PDB in Upgrade Mode

Then I closed the PDB:

SQL> ALTER PLUGGABLE DATABASE PROD CLOSE;

and opened it in upgrade mode:

SQL> ALTER PLUGGABLE DATABASE PROD OPEN UPGRADE;

 

Step 3: Change MAX_STRING_SIZE

Now set the parameter:

SQL>ALTER SYSTEM SET MAX_STRING_SIZE=EXTENDED SCOPE=spfile;

This doesn’t take effect immediately, so a restart is needed.


Step 4: Restart Database in Upgrade Mode

So I restarted the CDB:

SQL> shu immediate;
SQL> startup upgrade;


Step 5: Run utl32k.sql

After startup, I ran:

SQL>@?/rdbms/admin/utl32k.sql

This is one of those steps you really shouldn’t skip.


Step 6: Close PDB and Handle PDB$SEED

Next, I closed the PDB:

SQL> ALTER PLUGGABLE DATABASE PROD CLOSE IMMEDIATE;

Then handled the seed database (this is where I messed up the first time):

SQL> ALTER PLUGGABLE DATABASE PDB$SEED OPEN UPGRADE;

SQL> ALTER SESSION SET CONTAINER = PDB$SEED;


SQL> ALTER PLUGGABLE DATABASE  CLOSE IMMEDIATE;


SQL> ALTER PLUGGABLE DATABASE OPEN READ ONLY;


SQL> ALTER PLUGGABLE DATABASE SAVE STATE;

If you skip this, new PDBs may not inherit the setting properly.


Step 7: Run Script Again in Target PDB

Finally, I switched back to my PDB:

SQL> ALTER SESSION SET CONTAINER=PROD;


SQL> @?/rdbms/admin/utl32k.sql

 

Final Thoughts

A few things I’d keep in mind:

  • Do this during a maintenance window
  • Take a backup before starting
  • Don’t ignore the seed step
  • This change is not easily reversible

Once done, you can go beyond the 4000-byte limit — up to 32767 for VARCHAR2, which is what we needed.

 

March 31, 2026

How to Delete Old (Inactive) Patches in Oracle 19c Using OPatch

How I Clean Up Old (Inactive) Patches in Oracle Using OPatch

Problem: After multiple Oracle RU patch cycles, old inactive patches accumulate in Oracle Home, causing clutter and confusion during troubleshooting.
Environment: Oracle 19c on Windows (same steps apply to Linux)
Solution: Use OPatch utility commands to safely list and delete inactive patches while retaining the minimum recommended count.

If you have been consistently installing RUs on your Oracle Database, one of the things that will occur to you after some time is your Oracle Home being crammed with outdated patches.

They're not active anymore, but they're still lingering. I ran into the same situation recently while checking one of our 19c environments. There were multiple old RUs lying around, and I thought it's a good time to clean things up a bit.

Here's how I usually handle deleting inactive patches using OPatch.

Prerequisites

  • Oracle 19c installed (Windows or Linux)
  • OPatch version 12.2.0.1.37 or higher
  • Access to OS user with ORACLE_HOME permissions
  • Preferably a scheduled maintenance window

Step 1: Check Your OPatch Version

Before doing anything, I always make sure OPatch is up to date. Some of these utilities won't work properly on older versions.

cd D:\oracle\product\19.3.0\dbhome_1\OPatch
opatch version

Make sure it's 12.2.0.1.37 or higher. In my case, it was 12.2.0.1.45 — good to go.

Step 2: Check What's Actually Inactive

Next step is to see what patches are inactive. This command is quite handy:

D:\oracle\product\19.3.0\dbhome_1\OPatch>opatch util listorderedinactivepatches

Sample output:

Oracle Interim Patch Installer version 12.2.0.1.45
Copyright (c) 2025, Oracle Corporation. All rights reserved.

Oracle Home       : D:\oracle\product\19.3.0\dbhome_1
OPatch version    : 12.2.0.1.45

Invoking utility "listorderedinactivepatches"

***** There are 2 inactive RU patches in chain 1
-Inactive RU/BP 35046439: 19.19.0.0.230418, installed on: Fri Jul 28 10:22:30 GST 2023
-Inactive RU/BP 36521936: 19.24.0.0.240716, installed on: Thu Oct 24 11:31:40 GST 2024
-Active   RU/BP 37486199: 19.26.0.0.250121, installed on: Sat May 17 10:22:50 GST 2025

OPatch succeeded.

So clearly:

  • 2 old patches are inactive
  • 1 is the current active RU

Pretty typical scenario after a couple of patch cycles.

Step 3: Important — Don't Delete Everything

Oracle recommends keeping at least 2 inactive patches in the Oracle Home. If something goes wrong and you need to rollback or investigate, having older patches helps. So don't just go and delete everything blindly.

Step 4: Clean Up the Old Ones

To remove inactive patches, use:

D:\oracle\product\19.3.0\dbhome_1\OPatch>opatch util deleteinactivepatches

Sample output:

Invoking utility "deleteinactivepatches"

***** There are 2 inactive RU patches in chain 1

***** 1 inactive patches will be deleted
-To be deleted  : 35046439 (19.19.0.0.230418)
-To be retained : 36521936 (19.24.0.0.240716)
-Active RU/BP   : 37486199 (19.26.0.0.250121)

Do you want to proceed? [y|n]

Notice something interesting — even though there were 2 inactive patches, OPatch decided to delete only 1. That's because it automatically ensures the minimum required patches are retained.

Confirm with:

y

Result:

Deleted RU/BP patch: 35046439

OPatch succeeded.

Things I Always Keep in Mind

  • Prefer doing this during a maintenance window
  • On critical systems, take a quick backup of Oracle Home first
  • Always check logs if something looks off:
%ORACLE_HOME%\cfgtoollogs\opatch

Summary — What we did:
  • Verified OPatch version is 12.2.0.1.37 or higher
  • Listed inactive patches using listorderedinactivepatches
  • Safely deleted oldest patch using deleteinactivepatches
  • OPatch automatically retained the minimum required inactive patches

Final Thoughts

This is one of those small maintenance activities that's easy to ignore, but it helps keep your environment clean. Inactive patches don't harm directly, but over time they add clutter and confusion — especially when you're troubleshooting or auditing patch levels.

Related posts:

March 3, 2026

How to Patch Oracle 19c to Release 19.29 – A Complete Step-by-Step Blog

How to Patch Oracle 19c to Release 19.29 – A Complete Step-by-Step Guide

Problem: Oracle 19c database needs to be patched to the latest Release Update (19.29) to stay secure and aligned with Oracle's quarterly patch cycle.
Environment: Oracle 19c on Linux x86-64 (same process applies to all 19c versions)
Solution: Download patch 38291812 from Oracle Support, update OPatch, apply the patch, and run datapatch to register it in the database.

I recently had to patch one of my Oracle 19c databases from 19.28 to 19.29. Since this is something we DBAs do every few months, I decided to write down the exact steps I followed. The procedures are the same for all 19c versions.

Note: On production systems, always apply on test/dev first. Never patch production directly without testing!

Prerequisites

  • Oracle 19c database installed on Linux x86-64
  • Access to Oracle Support (MOS account)
  • OS user with ORACLE_HOME and ORACLE_BASE permissions
  • At least 12 GB free disk space in /home
  • WinSCP or similar tool to transfer files to the server
  • Scheduled maintenance window (database downtime required)

Step 1: Download the Patch and OPatch Utility

Log in to Oracle Support and download the following:

  • Patch file: 38291812p38291812_190000_Linux-x86-64.zip
  • OPatch utility: 6880880p6880880_190000_Linux-x86-64.zip

Steps to download: Select Patches & Updates → enter patch number → select platform Linux x86-64 → download both files and review the README.

Step 2: Check and Update OPatch

On the server, check your current OPatch version:

cd $ORACLE_HOME/OPatch
./opatch version

You need version 12.2.0.1.48 or higher. If it's older, update it:

mv OPatch OPatch_backup1
cp p6880880_190000_Linux-x86-64.zip $ORACLE_HOME
cd $ORACLE_HOME
unzip p6880880_190000_Linux-x86-64.zip

Update your .bash_profile so OPatch is available globally:

vi /home/oracle/.bash_profile

Add this line:

PATH=$ORACLE_HOME/OPatch:$PATH

Save and reload:

:wq
. ~/.bash_profile

Step 3: Prepare the Patch Directory

mkdir /home/oracle/patch
chmod -R 777 /home/oracle/patch

Transfer both ZIP files (Patch + OPatch) to /home/oracle/patch using WinSCP or SCP.

Step 4: Unzip the Patch

cd /home/oracle/patch
unzip p38291812_190000_Linux-x86-64.zip
cd 38291812

Step 5: Run Pre-checks

Before applying the patch, check for conflicts with existing patches:

./opatch prereq CheckConflictAgainstOHWithDetail -ph ./

If you see "OPatch succeeded" — you're good to go. If there are conflicts, resolve them before proceeding.

Step 6: Stop the Database and Listener

sqlplus / as sysdba
SQL> shutdown immediate
SQL> exit
lsnrctl stop

Verify all services are completely down before moving to the next step.

Step 7: Clean Up Inactive Patches (Optional but Recommended)

This frees up Oracle Home space before applying the new patch:

cd $ORACLE_HOME/OPatch
./opatch util listOrderedInactivePatches
./opatch util deleteInactivePatches

Step 8: Check Available Disk Space

You'll need at least 12 GB free in /home:

df -h

Do not proceed if space is insufficient — the patch will fail midway.

Step 9: Apply the Patch

cd /home/oracle/patch/38291812
./opatch apply

Watch the output carefully. You should see success messages for each component. The full process typically takes 10–20 minutes.

Sample successful output at the end:

Patching component oracle.rdbms, 19.0.0.0.0...
Verifying the update...
Patch 38291812 successfully applied.
OPatch succeeded.

Step 10: Start the Database and Run DataPatch

Start the database first:

sqlplus / as sysdba
SQL> startup

Then run DataPatch to register the patch inside the database dictionary:

cd $ORACLE_HOME/OPatch
./datapatch -verbose

This step is mandatory — without it the patch is applied at the binary level but not registered in the database.

Step 11: Verify the Patch

SQL> select * from v$version;
SQL> select patch_id, patch_uid, version, action, status, description
     from dba_registry_sqlpatch
     order by action_time;

You should see 19.29.0.0.0 listed in the output with status SUCCESS.


Summary — What we did:
  • Downloaded patch 38291812 and updated OPatch to 12.2.0.1.48+
  • Ran pre-checks to confirm no patch conflicts
  • Shut down database and listener cleanly
  • Applied the patch using opatch apply
  • Ran datapatch -verbose to register the patch in the database
  • Verified patch version shows 19.29.0.0.0 in dba_registry_sqlpatch

Final Tips

  • In Data Guard setups — always patch the standby first, then the primary
  • Never patch production directly — test on a non-prod clone first
  • Always read the patch README before applying — it may have special instructions
  • Keep the OPatch backup (OPatch_backup1) until you've verified the patch successfully

Related posts:

May 17, 2025

Datapatch Failed After applying Oracle 19c PSU Apr 2025? How Disabling WMSYS Triggers Saved the Day

 

Recently we faced one issue while applying DB PSU Apr 2025 patch on oracle database 19c.

The error was like below.

 

$ ./datapatch -verbose

/u01/oracle/cfgtoollogs/sqlpatch/37642901/27123174/37642901_apply_NONPROD_2025May17_03_54_30.log (errors)

  -> Error at line 27817: script rdbms/admin/owmcvws.plb

      - ORA-04088: error during execution of trigger 'WMSYS.NO_VM_DDL'

      - ORA-00604: error occurred at recursive SQL level 2

      - ORA-04061: existing state of  has been invalidated

      - ORA-04061: existing state of package body "WMSYS.LT_CTX_PKG" has been

      - invalidated

      - ORA-04065: not executed, altered or dropped package body "WMSYS.LT_CTX_PKG"

      - ORA-06508: PL/SQL: could not find program unit being called: "WMSYS.LT_CTX_PKG"

      - ORA-06512: at "WMSYS.LTADM", line 9800

      - ORA-04061: existing state of package body "WMSYS.LT_CTX_PKG" has been

      - invalidated

      - ORA-04065: not executed, altered or dropped package body "WMSYS.LT_CTX_PKG"

      - ORA-06508: PL/SQL: could not find program unit being called: "WMSYS.LT_CTX_PKG"

      - ORA-06512: at "WMSYS.LTADM", line 9532

      - ORA-06512: at "WMSYS.OWM_DYNSQL_ACCESS", line 549

      - ORA-06512: at line 17

      - ORA-06512: at line 7

      - ORA-06512: at line 7

  -> Error at line 28420: script rdbms/admin/owmcvws.plb

      - ORA-04088: error during execution of trigger 'WMSYS.NO_VM_DDL'

      - ORA-00604: error occurred at recursive SQL level 1

      - ORA-04068: existing state of packages has been discarded

      - ORA-04061: existing state of package body "WMSYS.LTUTIL" has been invalidated

      - ORA-04065: not executed, altered or dropped package body "WMSYS.LTUTIL"

      - ORA-06508: PL/SQL: could not find program unit being called: "WMSYS.LTUTIL"

      - ORA-06512: at "WMSYS.LTADM", line 9437

      - ORA-06512: at "WMSYS.OWM_DYNSQL_ACCESS", line 544

      - ORA-06512: at line 15

Please refer to MOS Note 1609718.1 and/or the invocation log

/u01/oracle/cfgtoollogs/sqlpatch/sqlpatch_30994_2025_05_17_03_52_45/sqlpatch_invocation.log

for information on how to resolve the above errors.

 

SQL Patching tool complete on Sat May 17 03:55:35 2025

Solution:-

To resolve the issue we did following

Step 1: Disable WMSYS Triggers

Run this as SYS:

SQL> BEGIN

  EXECUTE IMMEDIATE 'ALTER TRIGGER WMSYS.NO_VM_DDL DISABLE';

  EXECUTE IMMEDIATE 'ALTER TRIGGER WMSYS.REFRESH_ON_ALTER DISABLE';

  EXECUTE IMMEDIATE 'ALTER TRIGGER WMSYS.ADD_OBJ_TRIGGER DISABLE';

EXCEPTION

  WHEN OTHERS THEN

    DBMS_OUTPUT.put_line(SQLERRM);

END;

/

 

 

Step 2: Recompile WMSYS Schema

SQL> BEGIN

  DBMS_UTILITY.compile_schema(schema => 'WMSYS', compile_all => TRUE);

END;

/

 

Step 3: Rerun datapatch

 

cd $ORACLE_HOME/OPatch

./datapatch -verbose

 

This time we didn’t face the error as mentioned above. So disable the triggers mentioned above fixed the issue.

 

Step 4: Re-enable the Triggers

SQL>BEGIN

  EXECUTE IMMEDIATE 'ALTER TRIGGER WMSYS.NO_VM_DDL ENABLE';

  EXECUTE IMMEDIATE 'ALTER TRIGGER WMSYS.REFRESH_ON_ALTER ENABLE';

  EXECUTE IMMEDIATE 'ALTER TRIGGER WMSYS.ADD_OBJ_TRIGGER ENABLE';

EXCEPTION

  WHEN OTHERS THEN

    DBMS_OUTPUT.put_line(SQLERRM);

END;

/

 

 

Now when we checked dba_registry_sqlpatch we could see the patch application was successful.



Shell Script to Automate Oracle 19c TDE Wallet & sqlnet.ora Backups

  Recently, one of my junior colleague had a requirement to clone a production database. While doing so he faced the following error while o...