Compare Oracle Database Patches Across Different Homes
How to Compare Oracle Database Patches Across Different Homes
When working with multiple Oracle Database homes on the same or different servers, it’s essential to verify and compare the applied patches. This ensures consistency, identifies discrepancies, and helps maintain compliance with patching policies.
This guide demonstrates a script-based approach to:
- Dynamically retrieve Oracle Home paths and database names as input.
- Compare patches applied to different Oracle Homes.
- Generate a detailed report highlighting unique and common patches.
Requirements
- Oracle
opatchutility installed and accessible in the Oracle Home. - Shell environment with basic tools like
grep,awk, andsed. - User privileges to access the Oracle Home and execute
opatchcommands.
The Script
Here’s the script that compares patches across Oracle Database homes dynamically based on user input.
#!/bin/bash
#Author Rohit Misri
# Prompt for Oracle Home paths and database names
read -p "Enter the database name for the first Oracle Home: " DBNAME1
read -p "Enter the Oracle Home path for the first database: " ORACLE_HOME1
read -p "Enter the database name for the second Oracle Home: " DBNAME2
read -p "Enter the Oracle Home path for the second database: " ORACLE_HOME2
# Temporary files to store patch information
PATCHES_HOME1="/tmp/patches_${DBNAME1}.txt"
PATCHES_HOME2="/tmp/patches_${DBNAME2}.txt"
LOGFILE="/tmp/patch_comparison_${DBNAME1}_${DBNAME2}_debug.log"
REPORT="/tmp/patch_comparison_${DBNAME1}_${DBNAME2}_report.txt"
# Log function
log() {
echo "[$(date)] $1" >> "$LOGFILE"
}
# Function to execute opatch and retrieve inventory
get_patch_inventory() {
local oracle_home=$1
export ORACLE_HOME="$oracle_home"
$ORACLE_HOME/OPatch/opatch lsinventory 2>&1
}
# Collect patch inventory and release version for each Oracle Home
echo "Collecting patch inventory and release information for $DBNAME1..."
RELEASE_HOME1=$(get_patch_inventory "$ORACLE_HOME1" | tee -a "$LOGFILE" | grep "Patch description:" | grep "Release Update" | head -1 | awk -F "Patch description:" '{print $2}' | sed 's/^ *//;s/ *$//')
if [[ -z "$RELEASE_HOME1" ]]; then
RELEASE_HOME1="Unknown (Could not retrieve release)"
fi
get_patch_inventory "$ORACLE_HOME1" | grep -E "Patch.*:|Release Update" > $PATCHES_HOME1
echo "Collecting patch inventory and release information for $DBNAME2..."
RELEASE_HOME2=$(get_patch_inventory "$ORACLE_HOME2" | tee -a "$LOGFILE" | grep "Patch description:" | grep "Release Update" | head -1 | awk -F "Patch description:" '{print $2}' | sed 's/^ *//;s/ *$//')
if [[ -z "$RELEASE_HOME2" ]]; then
RELEASE_HOME2="Unknown (Could not retrieve release)"
fi
get_patch_inventory "$ORACLE_HOME2" | grep -E "Patch.*:|Release Update" > $PATCHES_HOME2
# Generate comparison report
echo "Generating patch comparison report..."
{
echo "================ PATCH COMPARISON REPORT ================"
echo "Date: $(date)"
echo "Database 1: $DBNAME1"
echo "Oracle Home: $ORACLE_HOME1"
echo "Release: $RELEASE_HOME1"
echo ""
echo "Database 2: $DBNAME2"
echo "Oracle Home: $ORACLE_HOME2"
echo "Release: $RELEASE_HOME2"
echo ""
echo "Unique patches in $DBNAME1:"
comm -23 <(sort $PATCHES_HOME1) <(sort $PATCHES_HOME2) | sed "s/^/${DBNAME1}: /"
echo ""
echo "Unique patches in $DBNAME2:"
comm -13 <(sort $PATCHES_HOME1) <(sort $PATCHES_HOME2) | sed "s/^/${DBNAME2}: /"
echo ""
echo "Common patches in both databases:"
comm -12 <(sort $PATCHES_HOME1) <(sort $PATCHES_HOME2)
echo ""
echo "========================================================="
} > $REPORT
# Display the report
cat $REPORT
echo "Logs saved to $LOGFILE"
echo "Report saved to $REPORT"
How It Works
- Dynamic Inputs:
- The script prompts for the Oracle Home paths and database names, ensuring flexibility.
- Patch Retrieval:
- Uses
opatch lsinventoryto list applied patches and retrieves theRelease Updatedescription.
- Comparison:
- Compares patch lists and highlights:
- Unique patches for each database.
- Common patches shared by both.
- Report Generation:
- Outputs a detailed report in
/tmp/patch_comparison_<DBNAME1>_<DBNAME2>_report.txt.
- Debugging Logs:
- Logs the raw
opatchoutputs for troubleshooting in/tmp/patch_comparison_<DBNAME1>_<DBNAME2>_debug.log.
Sample Report
================ PATCH COMPARISON REPORT ================
Date: Mon Jan 6 04:30:00 UTC 2025
Database 1: DB1
Oracle Home: /path/to/oracle/home_1
Release: 19.25.0.0.241015
Database 2: DB2
Oracle Home: /path/to/oracle/home_2
Release: 19.24.0.0.241012
Unique patches in DB1:
DB1: Patch 12345678 : Fix for DBMS_STATS issue
Unique patches in DB2:
DB2: Patch 87654321 : Security fix for vulnerability ABC
Common patches in both databases:
Patch 11223344 : Critical Patch Update (CPU)
Patch 22446688 : Release Update 19.24.0.0.0
=========================================================
Use Cases
- Consistency Check:
- Ensure all Oracle Homes are patched consistently.
- Troubleshooting:
- Identify missing patches causing application failures or inconsistencies.
- Upgrade Planning:
- Verify patch levels before and after database upgrades.
Caution
Test the script in a development environment before using it in production.
