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:

  1. Dynamically retrieve Oracle Home paths and database names as input.
  2. Compare patches applied to different Oracle Homes.
  3. Generate a detailed report highlighting unique and common patches.

Requirements

  1. Oracle opatch utility installed and accessible in the Oracle Home.
  2. Shell environment with basic tools like grep, awk, and sed.
  3. User privileges to access the Oracle Home and execute opatch commands.

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

  1. Dynamic Inputs:
  • The script prompts for the Oracle Home paths and database names, ensuring flexibility.
  1. Patch Retrieval:
  • Uses opatch lsinventory to list applied patches and retrieves the Release Update description.
  1. Comparison:
  • Compares patch lists and highlights:
  • Unique patches for each database.
  • Common patches shared by both.
  1. Report Generation:
  • Outputs a detailed report in /tmp/patch_comparison_<DBNAME1>_<DBNAME2>_report.txt.
  1. Debugging Logs:
  • Logs the raw opatch outputs 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

  1. Consistency Check:
  • Ensure all Oracle Homes are patched consistently.
  1. Troubleshooting:
  • Identify missing patches causing application failures or inconsistencies.
  1. Upgrade Planning:
  • Verify patch levels before and after database upgrades.

Caution

Test the script in a development environment before using it in production.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *