#!/bin/bash
# Define the path to oratab
ORATAB="/etc/oratab"
# Check if oratab exists
if [ ! -f $ORATAB ]; then
echo "$ORATAB not found. Exiting."
exit 1
fi
DB_STATUS_FILE="/tmp/db_status.log"
GGSCI_PATH="/usr/local/bin/ggsci" # Modify this to your GoldenGate installation path
LAG_THRESHOLD=0 # Set your lag threshold in seconds (0 for no lag allowed)
# Arrays to hold summary information
DB_HEALTH_GREEN=()
DB_NOT_OK=()
WALLET_COUNT=0
WALLET_DB_LIST=()
GOLDENGATE_FOUND="No"
# Function to set Oracle environment for a specific database
set_oracle_env() {
DB_NAME=$1
ORACLE_HOME=$2
export ORACLE_HOME=$ORACLE_HOME
export ORACLE_SID=$DB_NAME
export PATH=$ORACLE_HOME/bin:$PATH
echo "Set environment for database: $DB_NAME with ORACLE_HOME: $ORACLE_HOME"
}
# Function to check if a database is up and running
check_db_status() {
DB_NAME=$1
echo "Checking status for database: $DB_NAME..."
ps -ef | grep pmon | grep $DB_NAME | grep -v grep > $DB_STATUS_FILE
if [ -s $DB_STATUS_FILE ]; then
echo "Database $DB_NAME is up and running."
else
echo "Database $DB_NAME is down."
fi
}
# Function to perform Data Guard checks with dgmgrl, including lag
check_dgmgrl_lag() {
DB_NAME=$1
echo "Performing Data Guard checks for $DB_NAME (Step 1: show configuration)..."
# Step 1: Run "show configuration" in dgmgrl and check for errors
dgmgrl <<EOF > /tmp/dg_status.log
connect /;
show configuration;
exit;
EOF
if grep -q "ORA-" /tmp/dg_status.log; then
echo "$DB_NAME DG Broker checks for $DB_NAME >> NOT_OK"
DB_NOT_OK+=("$DB_NAME DG Broker check: NOT_OK")
return 1
elif grep -q "SUCCESS" /tmp/dg_status.log; then
echo "$DB_NAME DG Broker check successful. Proceeding to Step 2 (Gap check)..."
# Step 2: Check for gap in archived logs using SQLPlus
sqlplus -s / as sysdba <<EOF > /tmp/dg_gap_check.log
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF;
select distinct a.name "DBName", b.t1 thread#, b.ps "Last_Seq_On_Primary",
c.ss "Last_Seq_Applied_on_Standby", b.ps-c.ss "GAP"
from (select name from v\$database) a,
(select thread# t1, max(sequence#) ps from v\$archived_log group by thread#) b,
(select thread# t2, max(sequence#) ss from v\$archived_log where applied='YES' group by thread#) c
where b.t1 = c.t2;
EXIT;
EOF
# Parse gap check result
GAP=$(awk '{print $NF}' /tmp/dg_gap_check.log | grep -Eo '[0-9]+')
if [ -n "$GAP" ] && [ "$GAP" -gt 0 ]; then
echo "$DB_NAME has a replication gap of $GAP. LAG detected: NOT_OK"
DB_NOT_OK+=("$DB_NAME LAG: NOT_OK")
else
echo "$DB_NAME has no replication gap. DB HC green"
DB_HEALTH_GREEN+=("$DB_NAME DB HC green")
fi
else
echo "Unknown issue with Data Guard checks for $DB_NAME"
DB_NOT_OK+=("$DB_NAME Data Guard check failed: NOT_OK")
fi
}
# Function to check if the database is in restricted mode and primary/standby
check_db_mode() {
DB_NAME=$1
echo "Checking mode for database: $DB_NAME..."
sqlplus -s / as sysdba <<EOF > /tmp/db_mode.log
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF;
Select restricted, database_role from v\$pdbs, v\$database;
EXIT;
EOF
if [ $? -eq 0 ]; then
DATABASE_ROLE=$(grep -i "STANDBY" /tmp/db_mode.log)
PRIMARY_ROLE=$(grep -i "PRIMARY" /tmp/db_mode.log)
RESTRICTED=$(grep -i "YES" /tmp/db_mode.log)
if [ -n "$DATABASE_ROLE" ]; then
echo "Database $DB_NAME is a standby database."
DB_HEALTH_GREEN+=("$DB_NAME (Standby) DB HC green")
elif [ -n "$PRIMARY_ROLE" ] && [ -z "$RESTRICTED" ]; then
echo "Database $DB_NAME is in primary role and not restricted."
DB_HEALTH_GREEN+=("$DB_NAME (Primary) DB HC green")
elif [ -n "$PRIMARY_ROLE" ] && [ -n "$RESTRICTED" ]; then
echo "Database $DB_NAME is in primary role but restricted."
DB_NOT_OK+=("$DB_NAME (Primary) in restricted mode: NOT_OK")
else
echo "Database $DB_NAME is not in the expected mode."
DB_NOT_OK+=("$DB_NAME not in expected mode: NOT_OK")
fi
else
echo "Failed to check database mode for $DB_NAME."
fi
}
# Function to check wallet identifiers in /u01/app/oracle/okv/
check_wallet_identifiers() {
echo "Checking for wallet identifiers in /u01/app/oracle/okv/..."
# Ensure the directory exists
if [ -d "/u01/app/oracle/okv" ]; then
# List files in /u01/app/oracle/okv/ and capture their names
WALLET_FILES=$(ls /u01/app/oracle/okv/)
if [ -n "$WALLET_FILES" ]; then
while IFS= read -r FILE; do
WALLET_COUNT=$((WALLET_COUNT + 1))
WALLET_DB_LIST+=("$FILE")
done <<< "$WALLET_FILES"
fi
else
echo "/u01/app/oracle/okv directory does not exist."
fi
}
# Function to check for Goldengate executable (ggsci)
check_goldengate() {
echo "Checking for Goldengate executable using 'locate ggsci'..."
locate ggsci > /tmp/ggsci_check.log
if [ -s /tmp/ggsci_check.log ]; then
GOLDENGATE_FOUND="Yes"
fi
}
# Read oratab and loop through each database
while IFS=: read -r DB_NAME ORACLE_HOME DB_STARTUP_FLAG; do
# Skip comments and entries with no ORACLE_HOME
if [[ "$DB_NAME" =~ ^# ]] || [ -z "$ORACLE_HOME" ] || [[ "$DB_NAME" =~ ^\+ASM ]] || [[ "$DB_NAME" == "oracon_1" ]]; then
continue
fi
# Set the Oracle environment for each database
set_oracle_env "$DB_NAME" "$ORACLE_HOME"
# Run checks for each database
check_db_status "$DB_NAME"
check_dgmgrl_lag "$DB_NAME"
check_db_mode "$DB_NAME"
echo "-------------------------------------------"
done < $ORATAB
# Run wallet identifier check
check_wallet_identifiers
# Run Goldengate check
check_goldengate
# Print summary of wallet identifiers
echo "================== SUMMARY =================="
# Check wallet count and output result
if [ "$WALLET_COUNT" -gt 0 ]; then
echo "Action required: $WALLET_COUNT databases found with wallet configured."
echo "Databases with wallets:"
for wallet_db in "${WALLET_DB_LIST[@]}"; do
echo "$wallet_db"
done
else
echo "No wallet-configured databases found."
fi
# Check for Goldengate and report in summary
if [ "$GOLDENGATE_FOUND" == "Yes" ]; then
echo "Goldengate executable found. Please double-check and perform GG health check manually."
fi
# Print databases that have any issues (NOT_OK)
echo "================== HEALTH CHECK =================="
if [ ${#DB_NOT_OK[@]} -eq 0 ]; then
echo "All databases passed the health check."
else
for db in "${DB_NOT_OK[@]}"; do
echo "$db"
done
fi
# Print databases that passed all checks
echo "================== HEALTH CHECK =================="
if [ ${#DB_HEALTH_GREEN[@]} -eq 0 ]; then
echo "No databases passed the health check."
else
for db in "${DB_HEALTH_GREEN[@]}"; do
echo "$db"
done
fi
echo "============================================="





0 comments:
Post a Comment