# # ALTRAN_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # Copyright (C) Altran ACT S.A.S. 2017,2018,2019,2020,2021. All rights reserved. # # ALTRAN_PROLOG_END_TAG # # @(#) 7d4c34b 43haes/usr/sbin/cluster/sa/oracle/sbin/DBControl.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM #---------------------------------------------------------------------------- # Global Definitions: #---------------------------------------------------------------------------- . /usr/es/sbin/cluster/sa/oracle/sbin/IO . /usr/es/sbin/cluster/sa/oracle/sbin/DBUtilities . /usr/es/sbin/cluster/sa/oracle/sbin/DBStatus . /usr/es/sbin/cluster/sa/oracle/sbin/DBConfig #Added for Availability Metrics logs . /usr/es/lib/ksh93/availability/cl_amlib #---------------------------------------------------------------------------- # Functions: # osaStartAll # osaDBStopAll # osaStartBgProcs # osaStopBgProcs # osaStartListeners # osaStopListeners # osaListenerCmd # osaStartStopSpecListener # osaAddListeners # #---------------------------------------------------------------------------- # Function: # osaStartAll # # Purpose: # Starts an instance and associated listeners # # Arguments: # (1) name: Oracle DB instance name # # Returns: # 0 on success # 1 on failure # function osaDBStartAll { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x typeset appname=$1 # Fetch the resource group associated to DB application rgname=$(clodmget -n -q "application_id=$appname and name=RESOURCE_GROUP" -f value HACMPsa_metadata) amlog_trace $AM_SA_ORACLE_START_BEGIN "Start Oracle Database|$rgname" osaStartBgProcs $appname if (( $? != 0 )); then # Unable to start Background Processes. DB START FAILED user_msg 60 1 osaStopBgProcs $appname amlog_trace $AM_SA_ORACLE_START_FAILURE "Start Oracle Database|$rgname" return 1 else amlog_trace $AM_SA_ORACLE_START_END "Start Oracle Database|$rgname" amlog_trace $AM_SA_ORACLE_START_BEGIN "Start Oracle Listeners|$rgname" osaStartListeners $appname stat=$? if (( $stat != 0 )); then # Unable to start DB listeners. DBStartAll FAILED. user_msg 60 2 osaStopBgProcs $appname amlog_trace $AM_SA_ORACLE_START_FAILURE "Start Oracle Listeners|$rgname" return 1 fi amlog_trace $AM_SA_ORACLE_START_END "Start Oracle Listeners|$rgname" fi return stat } #---------------------------------------------------------------------------- # Function: # osaDBStopAll # # Purpose: # Stop all database processes # # Arguments: # n/a # # Returns: # 0 on success # 1 on failure # function osaDBStopAll { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x typeset appname=$1 # Fetch the resource group associated to DB application rgname=$(clodmget -n -q "application_id=$appname and name="RESOURCE_GROUP"" -f value HACMPsa_metadata) amlog_trace $AM_SA_ORACLE_STOP_BEGIN "Stop Oracle Listeners|$rgname" osaStopListeners $appname if (( $? != 0 )); then # "Unable to stop listeners. DB STOP FAILED." amlog_trace $AM_SA_ORACLE_STOP_FAILURE "Stop Oracle Listeners|$rgname" user_msg 60 3 return -1 else amlog_trace $AM_SA_ORACLE_STOP_END "Stop Oracle Listeners|$rgname" amlog_trace $AM_SA_ORACLE_STOP_BEGIN "Stop Oracle Database|$rgname" osaStopBgProcs $appname if (( $? != 0 )); then # "Unable to stop DB Background Processes. DBStopAll FAILED." amlog_trace $AM_SA_ORACLE_STOP_FAILURE "Stop Oracle Database|$rgname" user_msg 60 4 return -2 fi amlog_trace $AM_SA_ORACLE_STOP_END "Stop Oracle Database|$rgname" fi return 0 } #---------------------------------------------------------------------------- # Function: # osaStartBgProcs # # Purpose: # Starts Oracle DB background processes (`startup' command on SQL-Plus) # # Arguments: # n/a # # Returns: # 0 on success # 1 on failure # function osaStartBgProcs { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x typeset appname=$1 osaProcStatus $appname if (( $? == 0 )); then # DB Background Processes ALREADY STARTED user_msg 50 1 return 0 fi osaSQLPlusStartup osaSQLStatus if (( $? == 0 )); then # DB Background Processes STARTED successfully. user_msg 50 1 return 0 else # DB Background Processes could NOT be STARTED. user_msg 50 2 return 1 fi } #---------------------------------------------------------------------------- # Function: # osaStopBgProcs # # Description: # Stops Oracle DB background processes. # Runs one of the below commands on SQL-Plus based on user input # "shutdown immediate", # "shutdown abort", # "shutdown normal" or # "shutdown transactional" # # Arguments: # (1) appname: Oracle DB instance name # # Returns: # 0 on success # 1 on failure # function osaStopBgProcs { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x typeset appname=$1 typeset -A pnames typeset -l process typeset PID typeset shutopt shutopt=$(clodmget -q "application_id=\"$appname\" and name=SHUTDOWN" -n -f value HACMPsa_metadata) # Use default option, in case if output is empty. [[ -z "$shutopt" ]] && { shutopt="immediate" } osaSQLPlusRun "shutdown $shutopt" osaSQLStatus if (( $? == 10 )); then # DB Background Processes STOPPED successfully. user_msg 50 3 return 0 elif (( $? == 1 )); then # Ensure that DB is successfully stopped in case of error with oracle shutdown command. osaDBGetManProcs pnames $appname for process in ${pnames[*]}; do #get the process name format ora__sid realprocess="ora_${process}_${ORACLE_SID}" PID=$(ps -eaf |grep -v grep|grep -w $realprocess| awk '{print $2}') if [[ -n $PID ]]; then # Killing one of the oracle mandatory processes, shutdown the DB log_msg "Killing oracle mandatory process $process with PID: $PID." kill -9 $PID sleep 1 break fi done user_msg 50 3 return 0 else # DB Background Processes was not STOPPED. user_msg 50 4 return 1 fi } #---------------------------------------------------------------------------- # Function: # osaStartListeners # # Purpose: # Start all listeners defined for current instance. # # Arguments: # (1) Application Name # # Returns: # 0 on success # 1 on failure # function osaStartListeners { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x osaGetListeners $1 [[ -z ${allDBListeners[*]} ]] && return 0 # lsnrstatus - An Associative array which holds the status # of each listener.This array is populated by # osaListenerStatus() function. typeset -A lsnrstatus osaListenerStatus lsnrstatus if (( $? == 0 )); then # Listeners already started return 0 fi osaListenerCmd "start" lsnrstatus } #******************************************************************************* # Function: # osaStopListeners # # Purpose: # Stop all listeners defined for current instance. # # Arguments: # (1) Application Name # # Returns: # 0 on success # 1 on failure # function osaStopListeners { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x osaGetListeners $1 [[ -z ${allDBListeners[*]} ]] && return 0 # lsnrstatus - An Associative array which holds the status # of each listener.This array is populated by # osaListenerStatus() function. typeset -A lsnrstatus osaListenerStatus lsnrstatus if (( $? != 0 )); then # osaListenerStatus() returns a nonzero value even if # one of the listeners is stopped. We need to return # from here only if ALL listeners are stopped. Otherwise # call osaListenerCmd to stop the remaining listeners. # ALL_LISTENERS_STOPPED=1 indicates that ALL listeners are stopped. # ALL_LISTENERS_STOPPED=0 indicates that atleast one listener is active. typeset -i ALL_LISTENERS_STOPPED=1 for lis in ${!lsnrstatus[*]} do if (( ${lsnrstatus["$lis"]} == 0 )); then ALL_LISTENERS_STOPPED=0 break fi done if (( "$ALL_LISTENERS_STOPPED" == 1 )); then # Listeners already stopped return 0 fi fi osaListenerCmd "stop" lsnrstatus } #******************************************************************************* # Function: # osaListenerCmd # # Purpose: # A generic command that is capable of running `lsnrctl.' It is # used by osaStartListeners and osaStopListeners. # # Arguments: # (1) command: `lsnrctl' command to be run. # # Returns: # 0 on success # 1 on failure # function osaListenerCmd { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x typeset command=$1 typeset -n lsnrstatus=$2 typeset -i num=${#allDBListeners[*]} typeset -i stat=0 typeset -A listeners typeset -i i=0; if (( $num != 0 )); then log_msg "Number of listeners defined : "$num while (( $i < ${#allDBListeners[*]} )); do set -A x ${allDBListeners[$i]} if [[ ${x[0]} == "$ORACLE_SID" ]]; then typeset lisn=${x[1]} listeners["$lisn"]=1 fi (( i = $i + 1 )) done typeset lisn for lisn in ${!listeners[*]}; do # Filter out listeners which are already started/stopped. case $command in "start") if (( ${lsnrstatus["$lisn"]} == 0 )); then log_msg "Listener $lisn is already STARTED." continue fi ;; "stop") if (( ${lsnrstatus["$lisn"]} == 1 )); then log_msg "Listener $lisn is already STOPPED." continue fi ;; esac user_msg 50 16 $command $lisn log_msg "executing: ${ORACLE_HOME}/bin/lsnrctl $command $lisn" ORA_SHELL_ENV=$(lsuser -a shell $ORACLE_USER | awk -F = '{print $2}') if [[ $ORA_SHELL_ENV == *csh* ]]; then ORA_SHELL_ENV="csh" elif [[ $ORA_SHELL_ENV == *ksh* ]]; then ORA_SHELL_ENV="ksh" fi if [[ "$ORA_SHELL_ENV" == "ksh" ]]; then /usr/bin/su - $ORACLE_USER -c "ORACLE_HOME=$ORACLE_HOME ORACLE_SID=$ORACLE_SID ${ORACLE_HOME}/bin/lsnrctl $command $lisn" (( stat = $stat + $? )) elif [[ "$ORA_SHELL_ENV" == "csh" ]]; then /usr/bin/su - $ORACLE_USER -c "set ORACLE_HOME=$ORACLE_HOME; set ORACLE_SID=$ORACLE_SID; ${ORACLE_HOME}/bin/lsnrctl $command $lisn" (( stat = $stat + $? )) fi done return $stat else osaError "No Listeners found!" return 1 fi } #******************************************************************************* # Function: # osaStartStopSpecListener # # Purpose: # Start or Stop a specific listener defined for current DB instance # based on the input command argument provided. # # Arguments: # (1) Listener Name # (2) Action to be performed on listener(start/stop) # # Returns: # 0 on success # >= 1 on failure # function osaStartStopSpecListener { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x if (( $# != 2 )); then osaError "Invalid Arguments!" return 1 fi typeset -i stat=0 typeset lisn=$1 typeset command=$2 # lsnrstatus - An Associative array which holds the status of a # specific listener. This array is populated by # osaSpecListenerStatus() function. typeset -A lsnrstatus osaSpecListenerStatus $lisn lsnrstatus if (( $? != 0 )); then if [[ "$command" == "stop" ]] && [[ ${lsnrstatus["$lisn"]} == 1 ]] ; then log_msg "Listener $lisn is already STOPPED." return 0 fi else if [[ "$command" == "start" ]]; then # Listener already started log_msg "Listener $lisn is already STARTED." return 0 fi fi user_msg 50 16 $command $lisn log_msg "executing: ${ORACLE_HOME}/bin/lsnrctl $command $lisn" ORA_SHELL_ENV=$(lsuser -a shell $ORACLE_USER | awk -F = '{print $2}') if [[ $ORA_SHELL_ENV == *csh* ]]; then ORA_SHELL_ENV="csh" elif [[ $ORA_SHELL_ENV == *ksh* ]]; then ORA_SHELL_ENV="ksh" fi if [[ "$ORA_SHELL_ENV" == "csh" ]]; then /usr/bin/su - $ORACLE_USER -c "set ORACLE_HOME=$ORACLE_HOME; set ORACLE_SID=$ORACLE_SID; ${ORACLE_HOME}/bin/lsnrctl $command $lisn" (( stat = $stat + $? )) elif [[ "$ORA_SHELL_ENV" == "ksh" ]]; then /usr/bin/su - $ORACLE_USER -c "ORACLE_HOME=$ORACLE_HOME ORACLE_SID=$ORACLE_SID ${ORACLE_HOME}/bin/lsnrctl $command $lisn" (( stat = $stat + $? )) fi return $stat } #******************************************************************************* # Function: # osaAddListeners # # Purpose: # Add application monitor to each oracle listener associated with # oracle application Id # # Arguments: # (1) Application Id # (2) Resource Group name # # Returns: # 0 on success # >= 1 on failure # function osaAddListeners { [[ "$VERBOSE_LOGGING" == "high" ]] && set -x typeset -A lsnrmonname typeset -L32 rgname appname typeset slsEnabled="True" appid typeset -i MAX_LSNR_MONITORS=127 typeset -i stabilization_interval=180 if (( $# != 2 )); then osaError "Invalid Arguments!" return 1 fi appid=$1 rgname=$2 # # Update HACMPsa_metadata with flag SLSENABLED to indicate that oracle shared # listener support is enabled. # claddsaapp -a $appid SLSENABLED=$slsEnabled osaGetListeners $1 [[ -z ${allDBListeners[*]} ]] && return 0 # : For all the listeners defined for this DB, $RDBMS_DB, : get the unique listener monitors in an associative array. # appname=$(clodmget -n -q "group=$rgname and name="APPLICATIONS"" -f value HACMPresource) typeset lisn lmonname sname typeset -i lmoncount=1 sname=$(echo "$ORACLE_SID" | cut -c1-5) for (( index=0 ; $index < ${#allDBListeners[*]} ; index++ )) do set -A x ${allDBListeners[$index]} if [[ ${x[0]} == "$ORACLE_SID" ]]; then # # PowerHA SystemMirror supports maximum of 128 monitors associated to an application server. # For oracle database application server, maximum of 127 listener monitors are supported along # with one main database monitor. # if (( $lmoncount > $MAX_LSNR_MONITORS )); then (( lmoncount-- )) user_msg 20 21 $MAX_LSNR_MONITORS $lmoncount $appname break fi lisn=${x[1]} lmonname=$sname"_LM"$lmoncount"_RDBMS" lsnrmonname["$lisn"]=$(getUnusedName $lmonname "application_monitor") (( lmoncount++ )) fi done # : Creating Listener application monitor for each listener defined for DB instance ... # typeset lis typeset appmonlist # : Define the stabilization interval based on number of monitors # (( stabilization_interval += lmoncount*30 )) for lis in ${!lsnrmonname[*]} do result=$(clmgr query application_monitor ${lsnrmonname["$lis"]} 2>/dev/null) [[ -n $result ]] && { user_msg 30 6 ${lsnrmonname["$lis"]} # Deleting listener monitors created earlier. if [[ -n $appmonlist ]]; then clmgr delete application_monitor "$appmonlist" >/dev/null 2>&1 fi clrmsaapp -a $appid LSNRMONITOR # Return with 1 in failure scenarios to perform cleanup before exit. return 1 } user_msg 20 3 ${lsnrmonname["$lis"]} clmgr add application_monitor ${lsnrmonname["$lis"]} \ TYPE='user' \ APPLICATIONS=$appname \ MODE='longrunning' \ FAILUREACTION='fallover' \ RESTARTMETHOD="$ORACLESA_SBIN/cl_oraStartLSNR -d $RDBMS_DB -a $APPLICATION_ID -l $lis" \ CLEANUPMETHOD="$ORACLESA_SBIN/cl_oraStopLSNR -d $RDBMS_DB -a $APPLICATION_ID -l $lis" \ MONITORMETHOD="$ORACLESA_SBIN/cl_oraMonitorLSNR -d $RDBMS_DB -a $APPLICATION_ID -l $lis" \ MONITORINTERVAL='60' \ HUNGSIGNAL='9' \ STABILIZATION="$stabilization_interval" \ RESTARTCOUNT=6 \ RESTARTINTERVAL=792 >/dev/null 2>&1 (( $? != 0 )) && { user_msg 30 5 ${lsnrmonname["$lis"]} # Deleting listener monitors created earlier. if [[ -n $appmonlist ]]; then clmgr delete application_monitor "$appmonlist" >/dev/null 2>&1 fi clrmsaapp -a $appid LSNRMONITOR InternalErrorAbort # Return with 1 in failure scenarios to perform cleanup before exit. return 1 } # # Update HACMPsa_metadata with listener monitor name associated with a specific listener. # claddsaapp -a $appid LSNRMONITOR=$lis" "${lsnrmonname["$lis"]} appmonlist=$appmonlist" "${lsnrmonname["$lis"]} done return 0 }