Thursday, September 7, 2023

#!/bin/bash # # GI callout script to catch INSTANCE up event from clusterware and relocate services to preferred instance # Copy or symlink this script to $GRID_HOME/racg/usrco # 2012 Ilmar Kerm # LOGFILE=/u02/app/oracle/grid_callout/log.txt SCRIPTDIR=`dirname $0` # Determine grid home if [[ "${SCRIPTDIR:(-11)}" == "/racg/usrco" ]]; then CRS_HOME="${SCRIPTDIR:0:$(( ${#SCRIPTDIR} - 11 ))}" export CRS_HOME fi # Only execute script for INSTANCE events if [ "$1" != "INSTANCE" ]; then exit 0 fi STATUS="" DATABASE="" INSTANCE="" # Parse input arguments args=("$@") for arg in ${args[@]}; do if [[ "$arg" == *=* ]]; then KEY=${arg%=*} VALUE=${arg#*=} case "$KEY" in status) STATUS="$VALUE" ;; database) DATABASE="$VALUE" ;; instance) INSTANCE="$VALUE" ;; esac fi done # If database, status and instance values are not set, then exit # status must be up if [[ -z "$DATABASE" || -z "$INSTANCE" || "$STATUS" != "up" ]]; then exit 0 fi echo "`date`" >> "$LOGFILE" echo "[$DATABASE][`hostname`] Instance $INSTANCE up" >> "$LOGFILE" # # Read database software home directory from clusterware # DBCONFIG=`$CRS_HOME/bin/crsctl status res ora.$DATABASE.db -f | grep "ORACLE_HOME="` if [ -z "$DBCONFIG" ]; then exit 0 fi declare -r "$DBCONFIG" echo "ORACLE_HOME=$ORACLE_HOME" >> "$LOGFILE" # Array function in_array() { local hay needle=$1 shift for hay; do [[ $hay == $needle ]] && return 0 done return 1 } # # Read information about services # for service in `$CRS_HOME/bin/crsctl status res | grep -E "ora\.$DATABASE\.(.+)\.svc" | sed -rne "s/NAME=ora\.$DATABASE\.(.+)\.svc/\1/gip"`; do SERVICECONFIG=`$ORACLE_HOME/bin/srvctl config service -d $DATABASE -s $service` echo "Service $service" >> "$LOGFILE" if [[ "$SERVICECONFIG" == *"Service is enabled"* ]]; then echo " enabled" >> "$LOGFILE" PREFERRED=( `echo "$SERVICECONFIG" | grep "Preferred instances:" | sed -rne "s/.*\: ([a-zA-Z0-9]+)/\1/p" | tr "," "\n"` ) # # Check if current instance is preferred for this service # if in_array "$INSTANCE" "${PREFERRED[@]}" ; then echo " preferred" >> "$LOGFILE" # # Check if service is already running on current instance # SRVSTATUS=`$ORACLE_HOME/bin/srvctl status service -d $DATABASE -s $service` if [[ "$SRVSTATUS" == *"is not running"* ]]; then # # if service is not running, then start it # echo " service stopped, starting" >> "$LOGFILE" $ORACLE_HOME/bin/srvctl start service -d "$DATABASE" -s "$service" >> "$LOGFILE" else # # Service is running, but is it running on preferred instance? # RUNNING=( `echo "$SRVSTATUS" | sed -rne "s/.* ([a-zA-Z0-9]+)/\1/p" | tr "," "\n"` ) # echo "${RUNNING[@]} = ${PREFERRED[@]}" if ! in_array "$INSTANCE" "${RUNNING[@]}" ; then echo " not running on preferred $INSTANCE" >> "$LOGFILE" # # Find the first non-preferred running instance # CURRENT="" for inst in "${RUNNING[@]}"; do if ! in_array "$inst" "${PREFERRED[@]}" ; then CURRENT="$inst" break fi done # # Relocate # if [[ -n "$CURRENT" ]]; then echo " relocate $CURRENT -> $INSTANCE" >> "$LOGFILE" $ORACLE_HOME/bin/srvctl relocate service -d "$DATABASE" -s "$service" -i "$CURRENT" -t "$INSTANCE" >> "$LOGFILE" fi else # # Service is already running on preferred instance, no need to do anything # echo " running on preferred $INSTANCE" >> "$LOGFILE" fi fi fi fi done