#!/bin/ksh # chkconfig: 2345 90 10 # description: rc.oracle: System V start / stop script, Veritas Cluster Agent, \ # and a generic utility. [[ -n $BASH_VERSION ]] && shopt -s extglob OPATH=; unset OPATH OPATH=$PATH PATH=$(PATH=/bin:/usr/bin \getconf PATH) function shdoc { typeset version="3.1, 2008-05-28, Michael Wang ." typeset help doc file typeset tmpdir=/tmp/shdoc_$$_$RANDOM typeset base tmpf i flag=N eval help=y doc=pod "$@" [[ -n ${OPATH:-} ]] && typeset PATH=$OPATH set -- $(echo $help $doc | tr '[a-z]' '[A-Z]') help=$1 doc=$2 base=${file##*/} base=${base%.*sh} case ${doc} in (POD) mkdir -p ${tmpdir} && tmpf=${tmpdir}/${base}.pod ;; (MAN) mkdir -p ${tmpdir}/man/man1 && tmpf=${tmpdir}/man/man1/${base}.1 ;; esac while IFS= read -r i; do [[ $i = "## ${doc}_START"* ]] && { flag=Y; continue; } [[ $i = "## ${doc}_STOP"* ]] && { flag=N; continue; } if [[ $flag = "Y" ]]; then i=${i#"##"} i=${i#" "} printf "%s\n" "${i}" fi done < ${file} > ${tmpf} case $help in (Y) case ${doc} in (POD) perldoc ${tmpf} ;; (MAN) MANPATH=${tmpdir}/man man ${base} ;; esac ;; (PS|PDF) case ${doc} in (POD) pod2man ${tmpf} ;; (MAN) cat ${tmpf} ;; esac | groff -man | case ${help} in (PS) cat >${base}.ps ;; (PDF) ps2pdf - ${base}.pdf ;; esac ;; (POD) cp ${tmpf} ${base}.pod ;; (HTML) pod2html ${tmpf} > ${base}.html rm pod2htmd.tmp pod2htmi.tmp ;; esac rm -rf ${tmpdir} return 0 } typeset -l my_args="$@" [[ ${my_args} = *"help="?* ]] && { help=; unset help help=${my_args##*help=} help=${help%% *} [[ ${my_args} = *"doc="?* ]] && { doc=; unset doc doc=${my_args##*doc=} doc=${doc%% *} } : ${doc:=man} shdoc file=$0 doc=$doc help=$help exit 0 } [[ ${my_args} = *"version=y"* ]] && { sed -n "/^## version/{p; /^/q;}" $0 exit 0 } my_base=${0##*/} function get_cdate { date "+%Y-%m-%d %H:%M:%S"; } function get_tmpfile { typeset -Z6 pid=$$ random=${RANDOM} cdate=$(get_cdate) cdate=$(echo "$cdate" | sed "s/[-: ]//g") echo /tmp/.rc.oracle.${cdate}.${pid}.${random} } my_logdir=$(get_tmpfile) [[ -d ${my_logdir} ]] || mkdir ${my_logdir} my_logfile=${my_logdir}/${my_base}_00.out exec 3>&1 4>&2 1>${my_logfile} 2>&1 find /tmp/. \ \( -name "." -o -prune \) \ -name ".rc.oracle.[0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*" \ -type d -mtime +7 -exec rm -rf '{}' \; unset LD_LIBRARY_PATH unset ORA_NLS33 unset NLSPATH my_uname_n=$(uname -n) my_uname_s=$(uname -s) [[ ${my_uname_s} = "HP-UX" ]] && typeset -x UNIX95="set" MY_RUN_USER=$(id -un) MY_RUN_UID=$(id -u) for i in /var/opt/oracle/oratab /etc/oratab; do [[ -r ${i} ]] && { MY_ORATAB=${i}; break; } done [[ -z "${MY_ORATAB}" ]] && { print "$(get_cdate) oratab not found." return 127 } function rc_oracle { typeset SID SUBJECT typeset -u FLAG ACTION STATE METHOD FLAG_TAB FLAG_TAB2 typeset -u DBTYPE MANAGED DTIME ROLLTIME ARCHIVELOG typeset -u I MODE DBTYPE_TAB MANAGED_TAB LOGFILE_TAB LOGFILE typeset i j status SID_X SID_LINE SID_LINE_A typeset SID_TAB ISQL ENVFILE ORACLE_BASE ORACLE_HOME_TAB UMASK_TAB typeset FTIME Perl MA MP OWNER BPID T0 typeset THE_SEQ THE_PID THE_DTIME THE_GLOBAL THE_AUDIT_DEST THE_UDUMP_DEST for i do I=${i} if [[ ${I} = FLAG=@(Y|N|NO_CHANGE|NC) || ${I} = ACTION=@(START|STOP|RESTART|STAT?(US)|FLAG|ARCHIVE|PAGE|MAIL) || ${I} = STATE=@(NOMOUNT|MOUNT|OPEN|ALTER_MOUNT|ALTER_OPEN|ALTER_MOUNT_OPEN) || ${I} = METHOD=@(IMMEDIATE|ABORT|ROLLOVER) || ${I} = DBTYPE=@(PRIMARY|STANDBY) || ${I} = MANAGED=[YN] || ${I} = LOGFILE=[YN] || ${I} = DTIME=+([0-9]) || ${I} = ROLLTIME=+([0-9]) || ${I} = ARCHIVELOG=[YN] ]] then eval ${I} elif [[ ${I} = SID=+([a-zA-Z0-9_:-]) || ${I} = SUBJECT=* ]]; then eval ${I%%=*}=\"${i#*=}\" fi done SID_X=${SID} SID=${SID_X%:*} [[ ${SID_X} = *:* ]] && MODE=${SID_X#*:} [[ -z "${SID}" ]] && { print "$(get_cdate) SID name not specified." return 127 } while IFS= read -r i; do if [[ ${i} = "#_${SID}:"* ]]; then SID_LINE=${i} break elif [[ ${i} = "${SID}:"* ]]; then : ${SID_LINE_A:=${i}} fi done < ${MY_ORATAB} : ${SID_LINE:=${SID_LINE_A}} [[ -z ${SID_LINE} ]] && { print "$(get_cdate) SID_LINE not found in ${MY_ORATAB}." return 127 } set -- $(echo ${SID_LINE} | sed "s/:/ /g") # $(IFS=:; echo {SID_LINE}) has problems # for some versions of ksh93. SID_TAB=${1} ORACLE_HOME_TAB=${2} FLAG_TAB=${3} [[ -z ${ORACLE_HOME_TAB} ]] && { print "$(get_cdate) ORACLE_HOME not found from ${SID_LINE}." return 127 } [[ -d ${ORACLE_HOME_TAB} ]] || { print "$(get_cdate) ${ORACLE_HOME_TAB} not found. Possibly on other node of cluster." return 59 } ISQL=${ORACLE_HOME_TAB}/bin/sqlplus [[ -x ${ISQL} ]] || { print "$(get_cdate) ${ISQL} not found." return 127 } ORACLE_BASE=${ORACLE_HOME_TAB%/product/*} ENVFILE=${ORACLE_BASE}/.ora_${SID}_env.sh function get_var { typeset -l var=$1 line typeset envfile=$2 [[ -r ${envfile} ]] || return 1 while read line; do [[ $line = ?(* )${var}?( *)=* ]] && { print ${line##*=*( )} return 0 } done < ${envfile} return 1 } DBTYPE_TAB=$(get_var DBTYPE ${ENVFILE}) MANAGED_TAB=$(get_var MANAGED ${ENVFILE}) LOGFILE_TAB=$(get_var LOGFILE ${ENVFILE}) : ${DBTYPE:=${DBTYPE_TAB}} : ${DBTYPE:=PRIMARY} : ${MANAGED:=${MANAGED_TAB}} : ${LOGFILE:=${LOGFILE_TAB}} set -- $(ls -l ${ISQL}) OWNER=${3} if (( MY_RUN_UID == 0 )); then chown ${OWNER} ${my_logdir} function RUN_ISQL { su ${1} -c "env ORACLE_HOME=${2} \ ORACLE_SID=${3} \ ${4} /nolog @$5" } elif [[ ${MY_RUN_USER} = ${OWNER} ]]; then function RUN_ISQL { ORACLE_HOME=${2} \ ORACLE_SID=${3} \ ${4} /nolog @$5 } else print "$(get_cdate) You must be root or ${OWNER} to run this." exit 127 fi [[ -o xtrace ]] && typeset -ft $(typeset +f) case ${ACTION} in (STAT?(US)) : ${DTIME:=999999} : ${FLAG:=N} [[ ${MODE} = "NOMONITOR" ]] && { print "$(get_cdate) ${SID} was not tested (nomonitor option)." return 55 } [[ ${FLAG} = Y && ${FLAG_TAB} = N ]] && { print "$(get_cdate) ${SID} was not tested (N flag); \c" for i in $( print /opt/VRTSvcs/bin/perl5 print /usr/bin/perl print /bin/perl print /usr/local/bin/perl ); do [[ -x ${i} ]] && { Perl=${i}; break; } done FTIME=$(get_var FLAG_TIME ${ENVFILE}) if [[ ${FTIME} = +([0-9]) && -x ${Perl} ]]; then (( i=$(${Perl} -le "print ((-M \"${MY_ORATAB}\")*1440)") )) if (( i >= FTIME )); then print "N flag >= ${FTIME} minutes." return 54 else print "N flag < ${FTIME} minutes." return 53 fi elif [[ -z $(find ${MY_ORATAB} -mtime -1) ]]; then print "N flag >= 1 day." return 54 else print "N flag < 1 day." return 53 fi } ps -u ${OWNER} -o pid,args > ${my_logdir}/stat_${SID}_01.out (( j = 0 )) while IFS= read -r i; do [[ ${i} = *( )+([0-9])@( )ora_@(pmon|smon)_${SID}*( ) ]] && { print -r -- "${i}" (( j = j + 1 )) } (( j == 2 )) && break done < ${my_logdir}/stat_${SID}_01.out (( j == 2 )) || { print "$(get_cdate) ${SID} was down." return 51 } [[ ${MODE} = "PSONLY" ]] && { print "$(get_cdate) ${SID} was up (psonly option)." return 50 } { print "set linesize 160" print "set head off" print "set echo on" print "connect / as sysdba" if [[ ${DBTYPE} = STANDBY ]]; then print "SELECT 'THE_DTIME=' || ROUND((SYSDATE-first_time)*1440)," print "'THE_SEQ=' || sequence# FROM v\$log_history" print "WHERE sequence# = (SELECT MAX(sequence#) FROM v\$log_history);" THE_GLOBAL=${SID} else print "SELECT 'THE_GLOBAL=' || global_name FROM global_name;" THE_DTIME=-1 DTIME=999999 THE_SEQ=0 fi print "SELECT 'THE_PID=' || p.spid" print 'FROM v$process p, v$session s, v$mystat stat' print "WHERE s.sid = stat.sid AND p.addr = s.paddr AND rownum = 1;" print "SELECT 'THE_AUDIT_DEST=' || value" print "FROM v\$parameter WHERE name='audit_file_dest';" print "SELECT 'THE_UDUMP_DEST=' || value" print "FROM v\$parameter WHERE name='user_dump_dest';" print "exit" } > ${my_logdir}/stat_${SID}_02.sql RUN_ISQL ${OWNER} ${ORACLE_HOME_TAB} ${SID} ${ISQL} ${my_logdir}/stat_${SID}_02.sql 2>&1 | tee ${my_logdir}/stat_${SID}_03.out (( j = 0 )) while IFS= read -r i; do [[ ${i} = THE_@(GLOBAL|PID|AUDIT_DEST|UDUMP_DEST|DTIME|SEQ)=* ]] || continue if [[ ${i} = *=[?]* ]]; then b=; unset b a=; unset a b=${i%%=*} a=${i#*=\?} eval $b=${ORACLE_HOME_TAB}/$a else eval $i fi (( j = j + 1 )) done < ${my_logdir}/stat_${SID}_03.out if (( j == 4 )) && [[ -n ${THE_GLOBAL} ]] && # primary (( THE_DTIME <= DTIME )) && # standby [[ ${THE_SEQ} = +([0-9]) ]] && # standby [[ ${THE_PID} = +([0-9]) ]] && # common [[ -n ${THE_AUDIT_DEST} ]] && # common [[ -n ${THE_UDUMP_DEST} ]] # common then set -- ${THE_AUDIT_DEST}/*ora_${THE_PID}*.aud (( $# == 1 )) && [[ -f $1 ]] && rm -f $1 set -- ${THE_UDUMP_DEST}/*ora_${THE_PID}@([._])*trc (( $# == 1 )) && [[ -f $1 ]] && rm -f $1 print "$(get_cdate) ${SID} was up." return 50 else print "$(get_cdate) ${SID} needs attention (ps up but stat failed)." return 52 fi ;; (START) : ${FLAG:=Y} : ${STATE:=OPEN} { print "set feed on" print "set head off" print "set linesize 80" print "set trims on" print "set echo on" print "connect / as sysdba" if [[ ${DBTYPE} = STANDBY ]]; then print "startup nomount" print "alter database mount standby database;" [[ ${MANAGED} = Y ]] && { if [[ ${LOGFILE} = Y ]]; then print "recover managed standby database using current logfile disconnect from session;" else print "recover managed standby database disconnect from session;" fi } else [[ ${STATE} = NOMOUNT ]] && print "startup nomount" [[ ${STATE} = @(MOUNT|OPEN) ]] && print "startup mount" [[ ${STATE} = @(ALTER_MOUNT|ALTER_MOUNT_OPEN) ]] && print "alter database mount;" [[ ${STATE} = @(OPEN|ALTER_OPEN|ALTER_MOUNT_OPEN) ]] && { if [[ ${ARCHIVELOG} = Y ]]; then print "alter database archivelog;" print "alter system archive log start;" elif [[ ${ARCHIVELOG} = N ]]; then print "alter database noarchivelog;" print "alter system archive log stop;" fi print "spool ${my_logdir}/start_${SID}_01.out" print "SELECT 'ALTER DATABASE DATAFILE ' || file# || ' END BACKUP;'" print "FROM v\$backup WHERE status='ACTIVE';" print "spool off" print "set echo off" print "!$(whence grep) \"^ALTER\" ${my_logdir}/start_${SID}_01.out > ${my_logdir}/start_${SID}_02.sql" print "set echo on" print "@${my_logdir}/start_${SID}_02.sql" print "alter database open;" } fi print "exit" } > ${my_logdir}/start_${SID}_03.sql UMASK_TAB=$(get_var UMASK ${ENVFILE}) [[ ${UMASK_TAB} = +([0-9]) ]] && { UMASK_OLD=$(umask) umask ${UMASK_TAB} } RUN_ISQL ${OWNER} ${ORACLE_HOME_TAB} ${SID} ${ISQL} ${my_logdir}/start_${SID}_03.sql [[ ${UMASK_TAB} = +([0-9]) ]] && umask ${UMASK_OLD} [[ ( ${STATE} = *OPEN || ${DBTYPE} = STANDBY ) && ${FLAG} = [YN] ]] && { rc_oracle sid=${SID} action=flag flag=${FLAG} } ;; (STOP) : ${METHOD:=ROLLOVER} : ${FLAG:=N} [[ ${METHOD} = ROLLOVER ]] && { [[ ${FLAG} = [YN] ]] && rc_oracle sid=${SID_X} action=flag flag=${FLAG} rc_oracle sid=${SID_X} action=stop method=immediate DBTYPE=${DBTYPE} flag=NC & BPID=$! (( T0 = SECONDS )) while (( SECONDS - T0 <= ${ROLLTIME:-300} )); do sleep 5 rc_oracle sid=${SID_X} action=status DBTYPE=${DBTYPE} (( $? == 51 )) && { ps -p ${BPID} -o pid,args || return 51 } done > ${my_logdir}/stop_${SID}_02.out rc_oracle sid=${SID_X} action=stop method=abort DBTYPE=${DBTYPE} flag=NC status=$? sleep 3 ps -p ${BPID} -o pid,args && { kill -TERM ${BPID} sleep 3 ps -p ${BPID} -o pid,args && { kill -KILL ${BPID} sleep 3 ps -p ${BPID} -o pid,args } } return ${status} } [[ ${FLAG} = [YN] ]] && { rc_oracle sid=${SID} action=flag flag=${FLAG} } { print "set feed on" print "set head off" print "set echo on" print "connect / as sysdba" print "shutdown ${METHOD}" if [[ ${DBTYPE} = STANDBY ]]; then [[ ${METHOD} = ABORT ]] && { print "startup nomount" print "alter database mount standby database;" print "shutdown immediate" } else [[ ${METHOD} = ABORT ]] && { print "startup restrict open" print "shutdown" } fi print "exit" } > ${my_logdir}/stop_${SID}_01.sql RUN_ISQL ${OWNER} ${ORACLE_HOME_TAB} ${SID} ${ISQL} ${my_logdir}/stop_${SID}_01.sql ;; (RESTART) rc_oracle sid=${SID_X} action=stop flag=N sleep 3 rc_oracle sid=${SID_X} action=start flag=Y ;; (FLAG) [[ ${FLAG} = [YN] ]] || { print ${FLAG_TAB} return 0 } [[ ${FLAG} = ${FLAG_TAB} ]] && { print "$(get_cdate) ${SID_X} flag was already ${FLAG}." return 62 } function lock_unlock { # BASH users should set the following option: # # [[ -n $BASH_VERSION ]] && shopt -s extglob # # or equivalent BEFORE using the function. typeset PATH=$(PATH=/bin:/usr/bin getconf PATH) typeset action psid inode name pid time ttl abba id typeset expire=99999999 wait=99999999 T0 eval "$@" function epoch { typeset y m d H M S d dd i seconds set $(LC_ALL=C date -u +"%Y %m %d %H %M %S") y=${1#0} m=${2#0} d=${3#0} H=${4#0} M=${5#0} S=${6#0} (( t = (y-1600+3)/4 - (y-1600+99)/100 + (y-1600+399)/400 - 90 )) (( dd = (y-1970)*365 + t )) (( i = 1 )) while (( i < m )); do if (( i == 4 || i == 6 || i == 9 || i == 11 )); then (( t = 30 )) elif (( i == 2 )); then if (( y%4 == 0 && y%100 != 0 || y%400 == 0 )); then (( t = 29 )) else (( t = 28 )) fi else (( t = 31 )) fi (( dd = dd + t )) (( i = i + 1 )) done (( dd = dd + d - 1 )) (( seconds = dd*24*60*60 + H*60*60 + M*60 + S )) printf "%s\n" $seconds } abba=$(function t { trap 'printf "%s" a' EXIT; }; t; printf "%s" b) function lock_stat { typeset inode lsout name=$1 [[ -L ${name} ]] || { printf "%s\n" "inode=" && return 0; } set -- $(LC_ALL=C ls -il ${name}) printf "%s\n" "inode=${1} ${12} ${13} ${14} ${15}" } function ps_iden { set -- $(LC_ALL=C ps -o user= -o group= -o ppid= -o pgid= -p $1 2>/dev/null) echo $1.$2.$3.$4 return 0 } case ${action} in lock) (( T0 = SECONDS )) while (( SECONDS - T0 <= wait )); do ln -s "pid=$$ time=$(epoch) ttl=${expire} psid=$(ps_iden $$) id=$id" ${name} 2>/dev/null && { case $abba in ab) trap "trap \"rm -f ${name}\" EXIT" EXIT;; *) trap "rm -f ${name}" EXIT;; esac rm -f ${name}.+([0-9]).+([0-9]) return 0 } eval $(lock_stat ${name}) [[ -n ${inode} ]] && { ps -p ${pid} >/dev/null 2>&1 && [[ $(ps_iden ${pid}) = "$psid" ]] && (( $(epoch) < time + ttl )) || find ${name} -inum ${inode} -exec mv -f {} ${name}.$$.${RANDOM} \; } sleep 3 done;; unlock) eval $(lock_stat ${name}) [[ -n ${inode} ]] && find ${name} -inum ${inode} -exec rm -f {} \; && case $abba in ab) trap "trap - EXIT" EXIT;; *) trap - EXIT;; esac && return 0;; esac return 1 } my_lock=; unset my_lock my_lock=/tmp/rc.oracle.lock if lock_unlock action=lock name=$my_lock wait=30; then i=${MY_ORATAB} j=/tmp/oratab.$$.tmp cp -p ${i} ${j} sed "s/^\(${SID_TAB}:[^:]*:\)[YNyn]\(.*\)$/\1${FLAG}\2/" ${i} > ${j} (( $(wc -c < ${i}) == $(wc -c < ${j}) )) && ( mv ${j} ${i} 2>/dev/null || cp ${j} ${i} ) && lock_unlock action=unlock name=$my_lock else print "$(get_cdate) ${SID_X}: Failed to create lock (${my_lock})." fi FLAG_TAB2=$(rc_oracle sid=${SID} action=flag) if [[ ${FLAG_TAB2} = ${FLAG} ]]; then print "$(get_cdate) ${SID_X} flag change to ${FLAG} was successful." return 60 else print "$(get_cdate) ${SID_X} flag change to ${FLAG} FAILED." return 61 fi ;; PAGE|MAIL) MA=$(get_var ${ACTION}list ${ENVFILE}) MP=$(whence mailx || whence mail) : ${SUBJECT:="${my_uname_n}: ${SID_X} ${my_base} alert"} [[ -n ${MA} && -x ${MP} && -n "${SUBJECT}" ]] && { ${MP} -s "${SUBJECT}" ${MA} < /dev/null & } ;; esac } function print2 { print -u1 "$1" print -u3 "$1" } function remove_logdir { [[ ${my_args} = *debug=y* ]] && return 0 [[ $1 = /tmp/.rc.oracle.+([0-9]).+([0-9]).+([0-9]) ]] && { rm -f $1/*_[0-9][0-9].@(out|sql) rmdir $1 } } function flat_opt { typeset o=: i for i; do o=${o}${i}: done print ${o} } [[ -o xtrace ]] && typeset -ft $(typeset +f) case ${my_base} in (monitor) if (( $# >= 2 )); then SID_X=$2 elif (( $# == 1 )); then SID_X=$1 else print2 "$(get_cdate) Wrong number of arguments, type \"$0 help=y\"." exit 100 fi SID=${SID_X%%:*} rc_oracle sid=${SID_X} action=status flag=y STATUS=$? m=; unset m if (( STATUS == 50 || STATUS == 55 )); then print2 "$(get_cdate) ${SID_X} was up." remove_logdir ${my_logdir} exit 110 elif (( STATUS == 59 )); then remove_logdir ${my_logdir} exit 100 elif (( STATUS == 51 )); then m="$(get_cdate) ${SID_X} was down. Details in ${my_logdir}" print2 "${m}" rc_oracle sid=${SID_X} action=page subject="${m}" exit 100 elif (( STATUS == 52 )); then m="$(get_cdate) ${SID_X} needed attention. Details in ${my_logdir}" print2 "${m}" rc_oracle sid=${SID_X} action=page subject="${m}" exit 110 elif (( STATUS == 53 )); then print2 "$(get_cdate) ${SID_X} was not tested with recent N flag." remove_logdir ${my_logdir} exit 110 elif (( STATUS == 54 )); then m="$(get_cdate) ${SID_X} was not tested with old N flag." print2 "${m}" T=; unset T (( T = $(date +%Y%H%M)%10000 )) (( T >= 800 && T <= 815 )) && rc_oracle sid=${SID_X} action=mail subject="${m}" remove_logdir ${my_logdir} exit 110 else m="$(get_cdate) ${SID_X} had unexpected status. Details in ${my_logdir}" print2 "${m}" rc_oracle sid=${SID_X} action=mail subject="${m}" exit 110 fi ;; (online) print2 "$(get_cdate) Running ${my_base} with $(flat_opt "$@") option." print2 "This may take a few minutes." print2 "When in doubt, please check ${my_logdir}" if (( $# >= 2 )); then SID_X=$2 elif (( $# == 1 )); then SID_X=$1 else print "$(get_cdate) Wrong number of arguments, type \"$0 help=y\"." exit 100 fi rc_oracle sid=${SID_X} action=page subject="$(get_cdate) startup ${SID_X}." SID=${SID_X%%:*} rc_oracle sid=${SID} action=status flag=n STATUS=$? if (( STATUS == 51 )); then : elif (( STATUS == 50 )); then print "$(get_cdate) ${SID_X} was already online." exit 0 elif (( STATUS == 59 )); then print "$(get_cdate) ORACLE_HOME for ${SID} not found to online." exit 1 else rc_oracle sid=${SID_X} action=stop method=abort flag=NC fi rc_oracle sid=${SID_X} action=start flag=NC sleep 3 rc_oracle sid=${SID} action=status flag=n STATUS=$? ESTATUS=; unset ESTATUS if (( STATUS == 50 )); then print2 "$(get_cdate) ${SID_X} online was successful." remove_logdir ${my_logdir} ESTATUS=0 else print2 "$(get_cdate) ${SID_X} online FAILED." ESTATUS=1 fi print2 "$(rc_oracle sid=${SID_X} action=flag flag=y)" exit ${ESTATUS} ;; (offline) print2 "$(get_cdate) Running ${my_base} with $(flat_opt "$@") option." print2 "This may take a few minutes." print2 "When in doubt, please check ${my_logdir}" if (( $# >= 2 )); then SID_X=${2} elif (( $# == 1 )); then SID_X=${1} else print "$(get_cdate) Wrong number of arguments, type \"$0 help=y\"." exit 100 fi rc_oracle sid=${SID_X} action=page subject="$(get_cdate) shutdown ${SID_X} immediate." SID=${SID_X%%:*} rc_oracle sid=${SID} action=stat flag=n STATUS=$? ESTATUS=; unset ESTATUS if (( STATUS == 51 )); then print "$(get_cdate) ${SID_X} was already offline." ESTATUS=0 elif (( STATUS == 59 )); then print "$(get_cdate) ORACLE_HOME for ${SID} not found to offline." ESTATUS=1 else rc_oracle sid=${SID_X} action=stop flag=NC sleep 3 rc_oracle sid=${SID} action=stat flag=n STATUS=$? if (( STATUS == 51 )); then print2 "$(get_cdate) ${SID_X} offline was successful." remove_logdir ${my_logdir} ESTATUS=0 else print2 "$(get_cdate) ${SID_X} offline FAILED." ESTATUS=1 fi fi print2 "$(rc_oracle sid=${SID_X} action=flag flag=y)" exit ${ESTATUS} ;; (clean) print2 "$(get_cdate) Running ${my_base} with $(flat_opt "$@") option." print2 "This may take a few minutes." print2 "When in doubt, please check ${my_logdir}" CR=; unset CR SID_X=; unset SID_X if (( $# >= 3 )); then CR=$2 SID_X=${3} elif (( $# == 1 )); then SID_X=${1} CR="manual" else print "$(get_cdate) Wrong number of arguments, type \"$0 help=y\"." exit 100 fi print2 "This reason code for this action is ${CR}." rc_oracle sid=${SID_X} action=page subject="$(get_cdate) shutdown ${SID_X} abort." rc_oracle sid=${SID_X} action=stop method=abort flag=NC sleep 3 SID=${SID_X%%:*} rc_oracle sid=${SID} action=status flag=n STATUS=$? if (( STATUS == 51 )); then print2 "$(get_cdate) ${SID_X} clean was successful." remove_logdir ${my_logdir} elif (( STATUS == 59 )); then print "$(get_cdate) ORACLE_HOME for ${SID} not found to offline." else print2 "$(get_cdate) ${SID_X} clean FAILED." fi print2 "$(rc_oracle sid=${SID_X} action=flag flag=y)" exit 0 ;; ([SK]+([0-9])?(rc.)oracle?(-*)) i=; unset i j=; unset j k=; unset k l=; unset l flag_option=; unset flag_option if [[ ${my_base} = *oracle-* ]]; then i=${my_base##*oracle-} flag_option= else i=$(sed -n "s/^#_\([^:]*\):[^:]*:[Yy].*/\1/p" ${MY_ORATAB}) : ${i:=$(sed -n "/#/!s/\([^:]*\):[^:]*:[Yy].*/\1/p" ${MY_ORATAB})} flag_option="flag=NC" fi print2 "$(get_cdate) Running ${my_base} with $(flat_opt "$@") option." print2 "This may take a few minutes." print2 "When in doubt, please check ${my_logdir}" for j in ${i}; do print2 "Working on ${j} ..." [[ $1 = @(start|stop|restart) ]] && { [[ $1 = start ]] && { k=$(awk -F: "/^${j}:/ { print \$2; exit; }" ${MY_ORATAB}) l=${k}/oracm/bin/ocmstart.sh [[ -x ${l} ]] && { rm -f ${k}/oracm/log/ocmstart.ts ORACLE_HOME=${k} ${l} sleep 3 } } [[ $1 = stop ]] && [[ -r /etc/redhat-release ]] && rm -f /var/lock/subsys/${my_base##[SK]+([0-9])} rc_oracle sid=${j} action=$1 ${flag_option} sleep 3 [[ $1 = start ]] && [[ -r /etc/redhat-release ]] && touch /var/lock/subsys/${my_base##[SK]+([0-9])} } print2 "$(rc_oracle sid=${j} action=status flag=n | grep '^[0-9]\{4\}-')" done exit 0 ;; (rc.oracle) exec 1>&- 2>&- 1>&3 2>&4 i=; unset i { rc_oracle "$@" print "STATUS=$?" } | while IFS= read -r i do [[ ${i} = STATUS=+([0-9]) ]] && { eval ${i}; break; } if [[ ${my_args} = *@(action=@(start|stop|restart)|verbose=y)* ]]; then print -r -- "${i}" else [[ ${i} = @([0-9][0-9][0-9][0-9]-*|[YN]) ]] && { print -r -- "${i}" } fi done remove_logdir ${my_logdir} if (( STATUS == 50 || STATUS == 60 )); then exit 0 elif (( STATUS == 51 )); then exit 1 elif (( STATUS == 1 )); then exit 127 else exit ${STATUS} fi ;; esac ## POD_START ## =head1 NAME ## ## rc.oracle - General purpose maintenance utilities for Oracle database, ## System V (Solaris, HP, AIX, Linux) start/stop scripts, and VCS Oracle agents. ## ## =head1 SYNOPSIS ## ## B ## sid=I ## action=start ## flag=I (Default Y) ## state=I ## I ## I (Default OPEN) ## dbtype=I (Default PRIMARY) ## managed=I (Default N) ## archivelog=I (Default NO_CHANGE) ## verbose=I (Default N) ## ## B ## sid=I ## action=stop ## flag=I (Default N) ## method=I (Default ROLLOVER) ## rolltime=I (Default 300) ## verbose=I (Default N) ## ## B ## sid=I ## action=I ## flag=I (Default N) ## dtime=I (Default 999999) ## verbose=I (Default N) ## ## B ## sid=I ## action=I ## verbose=I (Default N) ## ## B ## sid=I ## action=I ## flag=I (Default SHOW) ## ## BIB I ## ## BIB-I I ## ## B I ## ## B B<.> I ## ## B I ## ## B B<.> I ## ## B I ## ## B B<.> B<0|1|2|3|4> I ## ## B I ## ## B B<.> I ## ## B<*> B ## ## B<*> B ## ## =head1 DESCRIPTION ## ## I is a single shell program to start, stop, test oracle ## database (primary and standby); check and update the flag; and send ## notifications, if configured, for abnormal database conditions, and ## when the N flag becomes too old. ## ## I is 3-in-1, multifunctional program serving different ## purposes when installed with different names. When named I, ## its canonical name, it is a general purpose program; when linked as ## BIB or BIB-I, ## it is used as System V start / stop script; when linked as ## B, B, B, and B, it is VCS ## (Veritas Cluster Server) Oracle agent. ## ## ( This is like Atlantic Coast Airlines. When flying for United ## it is United Express; when flying for Delta, it is Delta connection; ## when flying on its own, it is Independence Air. All shares the same ## management structure, same support channel, and payroll system. ) ## ## In order to describe each functionalities, a few concepts need to ## be cleared first. ## ## =head2 ORATAB ## ## Each database needs to be listed in oratab. This is not I ## requirement, but part of standard installation procedure. ## ## The complication comes that oratab is located in /var/opt/oracle on ## Solaris, in /etc on AIX and Linux. On systems that use /etc/oratab, ## it is better to make the following changes once: ## ## mkdir -p /var/opt/oracle ## cp /etc/oratab /var/opt/oracle/oratab ## chown oracle:dba /var/opt/oracle /var/opt/oracle/oratab ## chmod 775 /var/opt/oracle ## chmod 664 /var/opt/oracle/oratab ## rm /etc/oratab ## ln -s ../var/opt/oracle/oratab /etc/oratab ## ## and don't think about it. However, if you want to think about it ## please read MISCELLANEOUS INFORMATION section. ## ## =head2 FLAG ## ## Each database has a flag in oratab. As documented in Oracle I ## program, the Y flag means to start the database when server reboots. ## As a corollary, this flag is an indication the database is up, and can ## be monitored. ## ## The VCS agent uses the flag to determine whether to monitor the database ## or not. If you shutdown the database for maintenance, or cold backup, ## you should change the flag to N so that the agent won't start it up. ## Change the flag to Y if you want to the agent to monitor it. ## ## B combines the two steps - database start/stop and flag change - ## for you. ## ## =head2 GENERAL PURPOSE UTILITY ## ## When used as a general purpose utility for most common use, ## you specify two parameters, the Sid you are operate on, and the ## action which is either start, stop, restart, status, flag (show or ## change flag. The I option allows you to see what happens ## behind the scene. ## ## For the START action, the default behavior is to startup an idle instance ## of a primary database, and change the flag to Y (Please see the FLAG ## section). However you can specify the flag to be either Y or N, or ## NO_CHANGE. ## ## The default is to open the primary database, you can specify the ## state you want to alter database to, I, I, I; ## or if the database was already in a I or I state, ## you can specify the state change to I, I, ## or I (first alter database mount, then alter ## database open). ## ## If the database is an standby database, you need to tell I ## either using the configuration file (see CONFIGURATION), or ## command line options (DBTYPE, MANAGED, LOGFILE) that: ## ## DBTYPE=STANDBY : it is a standby database. ## MANAGED=Y : it is a managed standby. ## LOGFILE=Y : it is a managed standby using current logfile. ## ## The command line options have higher precedence over configuration file. ## ## The archivelog option allows you to change archivelog mode. ## ## For the STOP action, the default behavior is to shutdown the instance ## and change the flag to N. Again you can specify the flag to be either ## Y or N, or NO_CHANGE. ## ## The method option lets you specify how you want to shutdown. The default ## is ROLLOVER. B first tries to shutdown IMMEDIATE. If it was ## not successful after ROLLTIME seconds (default 300), it executes shutdown ABORT ## and kill the "shutdown immediate" process. "shutdown ABORT" is followed ## by "startup restrict open" for immediate recovery, and then a clean ## "shutdown". ## ## The FLAG action shows you the current flag, or change it to what you ## asked for. ## ## The STATUS or STAT action checks the health of the database. ## If the FLAG option is Y, it checks the flag for the database in ## oratab and only test the database when the flag is Y. The DTIME ## only applies to STANDBY database. It checks if the elapsed time since ## the last log application exceeds the DTIME you specified. ## ## The B utility can used manually, or in other programs ## such as Oracle cold backup, database monitoring. ## ## For example, in a Oracle rman cold backup, put in pre-script: ## ## rc.oracle sid= action=stop ## rc.oracle sid= action=start state=mount ## ## and in post script, put in post-script: ## ## rc.oracle sid= action=start state=alter_open ## ## This is better than putting ## ## shutdown immediate ## startup mount ## ... ## alter database open ## ## in rman script, because the default shutdown method for I ## is ROLLOVER; and the post-script will startup the database even when ## the rman backup fails. ## ## =head2 SYSTEM V START/STOP SCRIPT ## ## When the program is named as BIB>, or ## BIB, it can be used as ## system V start/stop scripts. The former is to start/stop ## the particular I regardless the flag. The latter is to ## start/stop ALL Sids whoes flag is Y. ## ## For example: ## ## To start / stop Sids with Y flag on Solaris: ## ## cp rc.oracle /etc/init.d/rc.oracle ## ln /etc/init.d/rc.oracle /etc/rc2.d/S90oracle ## ln /etc/init.d/rc.oracle /etc/rc0.d/K10oracle ## ## The location and naming conventions are slightly different ## on other Sys V derived systems: ## ## On AIX 5.2: ## ## cp rc.oracle /etc/rc.d/init.d/rc.oracle ## ln /etc/rc.d/init.d/rc.oracle /etc/rc.d/rc2.d/S90oracle ## ln /etc/rc.d/init.d/rc.oracle /etc/rc.d/rc2.d/K10oracle ## ## On SuSE Linux (2.4.7): ## ## cp rc.oracle /etc/init.d/rc.oracle ## ln /etc/init.d/rc.oracle /etc/init.d/rc3.d/S90oracle ## ln /etc/init.d/rc.oracle /etc/init.d/rc3.d/K90oracle ## ## B supports chkconfig. On redhat based systems, you ## can use chkconfig to add and delete the service: ## ## # chkconfig --add rc.oracle ## # chkconfig --list rc.oracle ## rc.oracle 0:off 1:off 2:on 3:on 4:on 5:on 6:off ## # chkconfig --del rc.oracle ## ## =head2 VCS ORACLE AGENT ## ## When the program is named B, B, B, and ## B, it can be used as VCS (Veritas Cluster Server) ## Oracle agent. ## ## This is done by installing the Solaris package MERotas provided ## in rc.oracle distribution. The following procedure is for ## I purpose only. ## ## #* For illustration purpose only, please use package for your platform. *# ## ## mkdir -p /opt/VRTSvcs/bin/Oracle ## cp rc.oracle /opt/VRTSvcs/bin/Oracle/rc.oracle ## cd /opt/VRTSvcs/bin/Oracle ## for i in online offline clean monitor; do ## ln rc.oracle $i ## done ## ln -s ../ScriptAgent OracleAgent # VCS provided ## ## Please also see I in the distribution ## on how to add the service to VCS. Sid is the sole parameter ## that needs to register in VCS. Basically, ## ## online SID = rc.oracle sid= action=start flag=Y ## offline SID = rc.oracle sid= action=stop method=immediate flag=Y ## clean SID = rc.oracle sid= action=stop method=abort flag=Y ## monitor SID = rc.oracle sid= action=stat flag=Y ## ## We can run the commands on the left side manually before ## testing VCS. ## ## =head2 PSONLY AND NOMONITOR ## ## The I Sid can be used in the format SID:psonly|nomonitor. ## The qualifiers I and I, which are case inSENsiTIVE, ## are only applicable how the Sid is tested. ## ## I, as the name suggests, is used to test only the shadow processes, ## pmon and smon. If the two processes exist, the instance is considered ## up even when it is in nomount state. ## ## I, as the name suggests, is used not to test the the ## database, but considers it to be up. ## ## These two qualifiers are used mainly for VCS, to prevent it from ## automatically restart the database. It does not affect the failover. ## ## A monitor program should be in place when used these two qualifiers. ## ## =head2 CONFIGURABLE PARAMETERS AND VCS NOTIFICATION ## ## I configuration is required for normal use of I. ## ## However, following the philosophy of "simple things should be easy ## but complicated things should be possible", the configuration ## file in $ORACLE_BASE/.ora_I_env.ksh can be used for these ## parameters: ## ## DBTYPE ## MANAGED ## MAILLIST ## PAGELIST ## FTIME ## UMASK ## ## The format of specification is "key = value". The left side should ## I the key as one word; ## the right side should contain the value and possibly spaces. ## The key is case INsenSItive. ## ## So the following format all valid, and equivalent: ## ## # MailList = dba_list@foo.com ## MAILlist=dba_list@foo.com ## ## I and I are introduced before. ## ## I and I are used for VCS agent notification. ## The agent sends page to I when (a) monitor failed; (b) ## monitor produced an unexpected status; (c) database start and stop. ## Unfortunately, monitor can not send page when the it times ## out. But hopefully, the notification will be sent by clean and ## online. The agent sends mail to I when the N flag for the ## database becomes too old (older than I if set, or 1 day). ## ## The FTIME is a number in minutes, which provides a way for you to tell ## I that you the flag is changed to N for x minutes. I ## will send email to I if this limit is exceeded, once per day ## between 08:00 and 08:15 hours. ## ## I is the umask value under which to start Oracle. ## ## =head2 RETURN CODE AND ERROR MESSAGES ## ## The VCS monitor spits the following informational messages ## which can be used for log monitor. The "110" and "100" are ## return code required by VCS. They are I part of the message. ## ## 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was up. ## 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] needed attention. Details in . ## 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was not tested with recent N flag. ## 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was not tested with old N flag. ## 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] had unexpected status. Details in . ## 100 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was down. Details in . ## ## The return codes for system V start / stop script are not used. ## The brief message informs the SA what is going on: ## ## YYYY-MM-DD HH24:MI:SS Running S|Koracle with start|stop option. ## This may take a few minutes. ## When in doubt, please check . ## Working on ... ## YYYY-MM-DD HH24:MI:SS was up|down. ## ## The return codes for start/stop should not be trusted. Either check the specific ## messages produced by I, or follow up start/stop with stat. The return ## code and informational messages for B status option are: ## ## 0 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was up. ## 1 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was down. ## !0 YYYY-MM-DD HH24:MI:SS ## ## For example, you can say: ## ## rc.oracle sid= action=stat || print " did not come up." ## ## For flag change, it is better to check directly, for example: ## ## [[ $(rc.oracle sid= action=flag) == "Y" ]] || exit 1 ## ## =head1 PHILOSOPHY ## ## The overriding philosophy used in developing this utility is ## KISS (Keep It Simple Stupid). ## ## This philosophy is reflected in one script zero configuration ## (for normal usage), and one parameter to pass to VCS ## (unfortunately, the one's can not be changed to zero's). ## ## The simplicity helps in following areas: ## ## Maintenance. It is easier to maintain one script than N scripts. ## It eliminates the confusion what script is used for what purposes. ## ## Deployment. Just copy the file to the right place, link with right ## names. (pkgadd and chkconfig for VCS and on Linux makes things easier). ## Zero coding is needed. Only one parameter I is communicated ## to the SA's for VCS. ## ## Operation. Due to a simple interface with VCS (one parameter), ## during Oracle upgrade, all we need to do is change the flag N, ## upgrade, and change the flag back to Y. And SA does not need ## get involved the database is shutdown for maintenance, or cold ## backup. ## ## =head1 MISCELLANEOUS INFORMATION ## ## M1. ORATAB LOCATION ## ## If I only reads the file, it does not matter whether it is ## located in a Oracle owned directory /var/opt/oracle, or a system directory ## /etc. It can detect the location and and use it. ## ## I changes the the flag in certain operations, and in order to ## guarantee the read consistency, mv is used: ## ## mv oratab.tmp oratab ## ## If copy is used, the oratab is not usable during the operation, producing ## unpredictable errors. I unlinks the old file, which is not possible ## if the executor does not own the directory. This also explains why link ## in reverse direction (/var/opt/oracle/oratab -> /etc/oratab) will not work. ## ## The read consistency is guaranteed by the POSIX standard ## I: ## ## If the link named by the new argument exists and the file's link count ## becomes 0 when it is removed and no process has the file open, the ## space occupied by the file shall be freed and the file shall no longer ## be accessible. If one or more processes have the file open when the ## last link is removed, the link shall be removed before rename() ## returns, but the removal of the file contents shall be postponed until ## all references to the file are closed. ## ## M2. NON-MEANINGFUL RETURN CODE ## ## Return values for start/stop is not meaningful as shown below, ## therefore one should always follow start/stop with stat. ## ## $ svrmgrl ## SVRMGR> connect internal ## Connected. ## SVRMGR> shutdown ## ORA-01149: cannot shutdown - file 1 has online backup set ## ORA-01110: data file 1: '/ora01/oradata/IBKSAD1/system01.dbf' ## SVRMGR> ^D ## Server Manager complete. ## ## $ echo $? ## 0 ## ## This is where the Oracle supplied dbstart and dbshut erred. The ## following is excerpted from dbshut, ## ## ... ## connect internal ## shutdown ## EOF ## ## if test $? -eq 0 ; then ## echo "Database \"${ORACLE_SID}\" shut down." ## else ## echo "Database \"${ORACLE_SID}\" not shut down." ## fi ## ## =head1 AUTHOR AND ACKNOWLEDGMENT ## ## Michael Wang > with help from many people. ## Contributions are acknowledged in the version history within ## the programs. ## ## =head1 VERSION HISTORY ## ## version 10.7, 2008-09-16, Michael Wang . ## * Change [[ ${i} = *=\?* ]] to [[ ${i} = *=[?]* ]] ## + The former does not work on ksh88 on HP although it should. ## ## version 10.6, 2008-05-26, Michael Wang . ## * Port to ksh 88 requested and sponsored by ## + DataBase Intelligence Group (http://dbigusa.com). ## * Various fixes and clean up. ## ## version 10.5, 2004-10-18, Michael Wang . ## * Added UMASK configuration parameter. ## * Enhanced get_var function. ## * Fixed test relic in restarting RAC ocmstart. ## ## version 10.4, 2004-08-29, Michael Wang . ## * Tested on standalone AIX 5.2 with reboot. ## ## version 10.3, 2004-08-23, Michael Wang . ## * revert to changing flag to Y after online|offline|clean ## + per discovery of VCS behavior by Jose Bacalla. ## * Added flat_opt function. ## ## version 10.2, 2004-08-21, Michael Wang . ## * Tested Linux RAC (Oracle 9.2.0.4 on RHEL 3.0 compatible) with reboot. ## ## version 10.1, 2004-08-20, Michael Wang . ## * Tested on AIX 5.2 VCS with Roy Morton. ## ## version 10.0, 2004-08-10, Michael Wang . ## * Rewrite to address the following issues: ## + PSONLY and NOMONITOR options. ## + Optional notification for monitor failure and state change. ## + Self maintained logs: clean user experience and capability to debug. ## + ROLLOVER shutdown method as default: IMMEDIATE -> ABORT. ## + STARTUP state, eg: ALTER_MOUNT, ALTER_OPEN. ## + Linux (redhat) support: chkconfig and subsys lock. ## + RAC support: startup oracm. ## + STANDBY database support. ## + modularity attempt for futher development: rc_oracle function. ## ## version 9.5, 2003-03-04, Michael Wang . ## * Changed "ksh $0" to "$0" so that what in #! line will be used. ## * Set UNIX95 for HP-UX to get SUSv2 bahavior for ps command (-o option). ## ## version 9.4b, 2002-12-25, Michael Wang . ## * Changed _grep "[o]ra_.*_$ORACLE_SID *$")_ ## to _grep "[0-9] ora_.*_$ORACLE_SID *$")_ ## Otherwise, it will grep "grep ora_pmon_SID". ## ## version 9.4a, 2002-11-20, Michael Wang . ## * Default method=smart; "sleep 1" => "sleep 5". ## ## version 9.4, 2002-06-17, Michael Wang . ## * Changed "first_time = (SELECT MAX(first_time) FROM v\$log_history)" ## to "sequence# = (SELECT MAX(sequence#) FROM v\$log_history)" ## to ensure single row. ## * Initialize SMARTIME. ## ## version 9.3, 2002-04-25, Michael Wang . ## * Added method=smart. ## * Added version=y. ## ## version 9.2, 2002-01-14, Michael Wang . ## * Fixed the problem that "help=y" leaves an empty dir in /tmp. ## * Changed "exit -- $?" to "exit $?": (exit -- 1); print $? => 0 in ksh88. ## ## version 9.1, 2001-12-01, Michael Wang (xw73@columbia.edu). ## * New way of getting SID_LINE: ## (1) $ORACLE_BASE/.rc.oracle.cf: #_ORACLE_SID:* ## (2) /var/opt/oracle/oratab: #_ORACLE_SID:* ## (3) /var/opt/oracle/oratab: ORACLE_SID:* ## * Relaxed GLOBAL_NAME test. ## * Derive owner from $ORACLE_HOME/bin/oracle. ## * Default UPASS is "/ as sysdba". Oracle 7 needs to specify different UPASS. ## * Depress output for action=stat verbose=n. ## * Fix FTIME issue: ## j=; unset j; j=011; print "$j" => 9 ## typeset -Z6 j; j=; print "$j" => "" ## - Bourne shell detection simplification. "PATH= print" and (print) forks, ## and only forked stderr can be redirected in Bourne shell. ## - Spool to a tempfile in /tmp instead of /var/opt/oracle. ## - Changed "exit -- -1" to "exit 127". (exit -- -1); print $? => 0 in ksh88. ## ## version 9.0, 05/26/2001, Michael Wang (xw73@columbia.edu). ## * Eliminate "svrmgrl" and "connect internal" for Oracle 9i+ where these ## are no longer supported. ## * Creating an Oracle user is optional (put "/ as sysdba" in UPASS field). ## This is not new feature but never documented, never found and used. ## * Added pager/email notification, and action=page|mail, message=... options ## with help from Andrew Blatt, Janet Zhu on CVS. "A nasty solution for a ## nasty problem in a nasty world"(TM). ## * Check FLAG before lsnrctl to ease the upgrade per Raj Pande. ## * "help=y" now uses "real man"(TM) page. Eliminated less helpful online help. ## * More generic and safer removal of .aud and .trc files: ## Solaris: ${lower_case_sid}_ora_$spid.trc, Linux: ora_spid.trc, ## AIX: ora_$spid_${lower_case_sid}.trc. Oracle Enhancement #: 1665035. ## * FLAG/FTIME update fix. ## - used POSIX PATH. ## - Use of POSIX "id -u" and "id -un" command. ## - Added "print" in additon to "$RANDOM" for ksh test to exclude bash. ## - Change "exit -1" to "exit -- -1" to make it work with PD KSH ## (PD KSH v5.2.14 99/07/13.2 on Red Hat Linux 7.1, Kernel 2.4.4). ## - Workaround different behaviors on "Ctrl-C" on trap between PD KSH and ## AT&T KSH: PD KSH does not run exit trap upon "Ctrl-C", AT&T KSH does. ## - uses cp -p $ORATAB $ORATAB.tmp to create a temp file with same permission. ## - Eliminate fork (grep) in processing SID_LINE. ## - More concise KSH construct for startup with and without $PFILE. ## ## version 5.4, 02/21/2001, Michael Wang (xw73@columbia.edu). ## * Tightened up the locking code. ## * Added restart option for convenience only per Raj Pande. It stop and start ## the database with default options. ## * Added identifier "$ORACLE_SID: " for flag change message. ## * exit 255 => exit -1 ## * Change [[ -z $ORATAB && -r $i ]] && ORATAB=$i to ## [[ -r $i ]] && { ORATAB=$i; break; } ## * Last line of start/stop options was: [[ $SHOW = Y ]] && exit -1. ## [[ $SHOW = Y ]] would be the last command if it is false and hence its ## status becomes the status of the script. The last line is changed to: ## (( status == 0 && fstatus == 0 )). ## ## version 5.3, 01/31/2001, Michael Wang (xw73@columbia.edu). ## * Added date before "tail -1". ## * Change [[ -z $Perl && -x $i ]] && Perl=$i to ## [[ -x $i ]] && { Perl=$i; break; } for efficiency. ## ## version 5.2, 01/26/2001, Michael Wang (xw73@columbia.edu). ## * Added ftime= option for start/stop. ## ## version 5.11, 01/19/2001, Michael Wang (xw73@columbia.edu). ## * Replace sed with ksh built-in: ## THE_UDUMP_DEST=$ORACLE_HOME${THE_UDUMP_DEST#?} ## * condition rm to eliminate fork when file does not exist: ## [[ -f $i_aud ]] && rm -f $i_aud ## ## version 5.1, 01/05/2000, Michael Wang (xw73@columbia.edu). ## * change "exit 0" to "exit $?" in oracle-SID case. This affects backup. ## * change "FOREVER" to "1 DAY". ## ## version 5.0, 12/21/2000, Michael Wang (xw73@columbia.edu). ## To incorporate the modifications made by Raj Pande and Pradeep Malhotra: ## * Accepts sid=..., action=..., and other options when the program is ## named rc.oracle or any other names except the following: ## oracle-SID, [SK]oracle, online, offline, clean, monitor. ## * When the program is named oracle-SID, it will perform passed action ## for this SID. Program with this name is ready to be used as Solaris ## start/stop script for this SID without the need for a wrapper script. ## This is the old behavior. ## * When the program is named Soracle, or Koracle, ## it will perform passed start or stop action for ALL oracle SIDs in ## oratab with Y flag. This is to simulate dbstart/dbshut behavior. ## * When the program is named online, offline, clean, monitor, it will ## start, stop immediate, stop abort, and test oracle database for passwd ## SID. Programs with these names are ready to be used as VCS entry points ## without the need for wrapper scripts. ## * Flag check. If the lifetime (in number of minutes) of N flag is specified ## (9th field in oratab) and Perl is available (VCS has Perl), then it will ## check if N flag is older than specified minutes, otherwise it will check ## if N flag is older than 1 day. ## * VERBOSE is defaulted to N instead of Y. ## Other changes: ## * FILTER=Y for action=stat to filter out oerrs, specified as the 8th field ## in oratab in the format of oerr1|oerr2|... Example: ## ora-12345|ora-23456|... ## * Streamline the option processing. ## * Added exit code 255 for "catch-all" errors. ## * Some change in error message for consistency. ## * "echo" is replaced by "print/print -r --" for robustness and compatibility. ## ## version 4.0, 10/10/2000, Michael Wang (xw73@columbia.edu). ## * version number advanced beyond pi. Tested on the following platforms: ## - ksh Version M 1993-12-28 j ## - ksh Version M-12/28/93d on Sun Solaris 2.6, 7 (dtksh). ## - ksh Version M-11/16/88i on Sun Solaris 2.6, 7. ## - ksh Version M-11/16/88f on IBM AIX 4.3.3. ## - PD KSH v5.2.14 99/07/13.2 on Red Hat Linux 6.2. ## * Exit code changed from 0 to 4 when Oracle executable can not be found. ## * Added start option ARCHIVELOG=([YN0][YN0]|Y|N|NULL|R) per discussion ## with Joe Ng. ## * Array can not be reset on Version M-11/16/88f on AIX 4.3.3 ## i[0]=; typeset -u i; i=; unset i; i=b; echo $i => B ## Changed to i to ix to avoid conflict. ## * "==" in [[ string == pattern ]] is replaced by "=" for compatibility ## with older Korn Shell (eg Version M-11/16/88f). ## * Added " *" in i=$(ps -eaf | egrep "[0-9] ora_.*_$ORACLE_SID *$") ## AIX 4.3 ps output has blank at end of line. ## * Get rid of the_space_holder. ## * Unset name for name=value pair. Example, TEST=. ## * changed _echo "$ ..."_ to _echo "\$ ..."_. The former expression ## exhibits different behaviour under differnet ksh versions. ## ## version 3.14159, 08/18/2000, Michael Wang (xw73@columbia.edu). ## * The test method for primary database is rolled back to version 2.0: ## SELECT global_name from global_name, and compare the global_name ## before the "." with ORACLE_SID instead of creating tables per discussion ## with Rana Chander, Matthew Soloman, Susan Gruebel, and Sheck Cho. ## Yuriy Leyzerovskiy of Oracle Corp provided grant statements on v$tables. ## Prerequisite: ## - /var/opt/oracle/oratab.SID: ## SID:ORACLE_HOME:Y/N:PFILE:OWNER:DBTYPE:UPASS ## - create user oracle_probe identified by oracle_probe ## default tablespace temp temporary tablespace temp; ## - grant create session to oracle_probe; ## - grant select on SYS.V_$PARAMETER to oracle_probe; ## - grant select on SYS.V_$SESSION to oracle_probe; ## - grant select on SYS.V_$MYSTAT to oracle_probe; ## - grant select on SYS.V_$PROCESS to oracle_probe; ## IF global_name is not already set to ORACLE_SID, ## - alter database rename global_name to ; ## On a box with multiple oracle users (oracle, oracle01, oracle02, ...): ## - chown oracle:dba /var/opt/oracle # on all nodes of cluster ## - chmod 775 /var/opt/oracle # on all nodes of cluster ## * Added $ anchor in i=$(ps -eaf | egrep "[0-9] ora_.*_$ORACLE_SID$") ## to cover the case that databases "foo" and "foobar" reside on same box. ## * Rewrite "[[ -z $(eval echo \$$i) ]]" as "eval [[ -z \$$i ]]". ## per suggestion from Dan A. Mercer on the internet. This avoids ## unnecessary fork(), and reduces cpu time. ## Tested on Sun E250 with 2x400MHz cpu, 2GB RAM, A1000 storage: ## $ time sh oracle-mysid stat verbose=n ## THE DATABASE mysid IS UP. ## real 0m0.43s ## user 0m0.28s ## sys 0m0.21s ## ## version 3.1415, 07/22/2000, Michael Wang (xw73@columbia.edu). ## * Expanded oratab to include pfile, owner, and dbtype (PRIMARY, STANDBY, ## STANDBY/MANAGED ) to support the new functionalities: ## - Support running as different $OWNER. ## - Support "startup pfile=<...>" option. ## - Support standby database. ## * Added archive option to archive log current. ## * Enhanced SHOW=Y option to display SQL statement. ## * FLAG=NULL option for start/stop to leave FLAG alone. ## * Changed svrmgrl to sqlplus in testing PRIMARY (versus STANDBY) database. ## * Eliminated TABLESPACE clause, instead using the test user's default one. ## * Change on PATH and RUN_USER for Linux compatibility. ## * unset LD_LIBRARY_PATH. ## Properly linked oracle executables do not need LD_LIBRARY_PATH. ## In Oracle 8i, set LD_LIBRARY_PATH causes listener problem, Ref: ## TAR 12953862.600, Doc ID 1023333.1, Bug ID 1147434. ## * "startup restrict open" and "shutdown" only runs after ## "shutdown abort" but not "shutdown immediate". ## * MASSIVE code clean up to support above functionalities and for ## programming purity and efficiency. ## ## version 3.141, 07/15/2000, Michael Wang (xw73@columbia.edu). ## * Fixed the race condition when multiple processes test the database. ## The bug was found by Janet Zhu and Susan Gruebel in an environment where ## the script is used for backup as well as for QualixHA+. ## The fix is to replace the fixed table_name "oracle_probe" with ## variable name T, and slightly changed test sequence as shown ## below. The old test sequence is indicated by () at end of line. ## (1) drop table T without verification (N/A) ## (2) create table T with verification (2) ## (3) insert table T with verification (3) ## (4) update table T with verification (4) ## (5) drop table T with verification (1) ## This fix covers the situation when table is inadvertently left behind. ## ## version 3.14, 03/17/2000, Michael Wang (xw73@columbia.edu). ## * More reliable method of updating oratab. ## ## version 3.1, 01/20/2000, Michael Wang (xw73@columbia.edu). ## * Minor midifications in Oracle env variable determination and verification. ## ## version 3.0, 12/27/1999, Michael Wang (xw73@columbia.edu). ## * Enhancement and cleanup. exp style user interface: exp help=Y ## The line: [ "$RANDOM" = "$RANDOM" ] && exec ksh "$0" "$@" ## is provided by David Korn. ## ## version 2.0, 05/27/1999, Michael Wang (xw73@columbia.edu). ## * Susan Gruebel provided fix for failover during hot backup. ## * Susan Gruebel suggested test if database is open. ## * ORATAB search order: oratab.$ORACLE_SID, oratab ## * Fixed the order of FLAG and database state change. ## start: START DATABASE, FLAG -> Y ## stop: FLAG -> N, STOP DATABASE ## ## version 1.0, 07/29/1998, Michael Wang (xw73@columbia.edu). ## * IPO. ## * Mikhail Rasol provided code for finding svrmgrl PID. ## POD_STOP ## ## MAN_START ## .\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 ## .\" ## .\" Standard preamble: ## .\" ======================================================================== ## .de Sh \" Subsection heading ## .br ## .if t .Sp ## .ne 5 ## .PP ## \fB\\$1\fR ## .PP ## .. ## .de Sp \" Vertical space (when we can't use .PP) ## .if t .sp .5v ## .if n .sp ## .. ## .de Vb \" Begin verbatim text ## .ft CW ## .nf ## .ne \\$1 ## .. ## .de Ve \" End verbatim text ## .ft R ## .fi ## .. ## .\" Set up some character translations and predefined strings. \*(-- will ## .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left ## .\" double quote, and \*(R" will give a right double quote. | will give a ## .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to ## .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' ## .\" expand to `' in nroff, nothing in troff, for use with C<>. ## .tr \(*W-|\(bv\*(Tr ## .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' ## .ie n \{\ ## . ds -- \(*W- ## . ds PI pi ## . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch ## . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch ## . ds L" "" ## . ds R" "" ## . ds C` "" ## . ds C' "" ## 'br\} ## .el\{\ ## . ds -- \|\(em\| ## . ds PI \(*p ## . ds L" `` ## . ds R" '' ## 'br\} ## .\" ## .\" If the F register is turned on, we'll generate index entries on stderr for ## .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index ## .\" entries marked with X<> in POD. Of course, you'll have to process the ## .\" output yourself in some meaningful fashion. ## .if \nF \{\ ## . de IX ## . tm Index:\\$1\t\\n%\t"\\$2" ## .. ## . nr % 0 ## . rr F ## .\} ## .\" ## .\" For nroff, turn off justification. Always turn off hyphenation; it makes ## .\" way too many mistakes in technical documents. ## .hy 0 ## .if n .na ## .\" ## .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). ## .\" Fear. Run. Save yourself. No user-serviceable parts. ## . \" fudge factors for nroff and troff ## .if n \{\ ## . ds #H 0 ## . ds #V .8m ## . ds #F .3m ## . ds #[ \f1 ## . ds #] \fP ## .\} ## .if t \{\ ## . ds #H ((1u-(\\\\n(.fu%2u))*.13m) ## . ds #V .6m ## . ds #F 0 ## . ds #[ \& ## . ds #] \& ## .\} ## . \" simple accents for nroff and troff ## .if n \{\ ## . ds ' \& ## . ds ` \& ## . ds ^ \& ## . ds , \& ## . ds ~ ~ ## . ds / ## .\} ## .if t \{\ ## . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" ## . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' ## . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' ## . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' ## . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' ## . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' ## .\} ## . \" troff and (daisy-wheel) nroff accents ## .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' ## .ds 8 \h'\*(#H'\(*b\h'-\*(#H' ## .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] ## .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' ## .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' ## .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] ## .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] ## .ds ae a\h'-(\w'a'u*4/10)'e ## .ds Ae A\h'-(\w'A'u*4/10)'E ## . \" corrections for vroff ## .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' ## .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' ## . \" for low resolution devices (crt and lpr) ## .if \n(.H>23 .if \n(.V>19 \ ## \{\ ## . ds : e ## . ds 8 ss ## . ds o a ## . ds d- d\h'-1'\(ga ## . ds D- D\h'-1'\(hy ## . ds th \o'bp' ## . ds Th \o'LP' ## . ds ae ae ## . ds Ae AE ## .\} ## .rm #[ #] #H #V #F C ## .\" ======================================================================== ## .\" ## .IX Title "RC.ORACLE 1" ## .TH RC.ORACLE 1 "2008-05-29" "perl v5.8.8" "User Contributed Perl Documentation" ## .SH "NAME" ## rc.oracle \- General purpose maintenance utilities for Oracle database, ## System V (Solaris, HP, AIX, Linux) start/stop scripts, and VCS Oracle agents. ## .SH "SYNOPSIS" ## .IX Header "SYNOPSIS" ## \&\fBrc.oracle\fR ## sid=\fI\s-1SID\s0\fR ## action=start ## flag=\fIY|N|NO_CHANGE|NC\fR (Default Y) ## state=\fINOMOUNT|MOUNT|OPEN\fR ## \fIALTER_MOUNT|ALTER_OPEN\fR ## \fI\s-1ALTER_MOUNT_OPEN\s0\fR (Default \s-1OPEN\s0) ## dbtype=\fIPRIMARY|STANDBY\fR (Default \s-1PRIMARY\s0) ## managed=\fIY|N\fR (Default N) ## archivelog=\fIY|N|NO_CHANGE|NC\fR (Default \s-1NO_CHANGE\s0) ## verbose=\fIY|N\fR (Default N) ## .PP ## \&\fBrc.oracle\fR ## sid=\fI\s-1SID\s0\fR ## action=stop ## flag=\fIY|N|NO_CHANGE|NC\fR (Default N) ## method=\fIIMMEDIATE|ABORT|ROLLOVER\fR (Default \s-1ROLLOVER\s0) ## rolltime=\fInumber in seconds\fR (Default 300) ## verbose=\fIY|N\fR (Default N) ## .PP ## \&\fBrc.oracle\fR ## sid=\fISID:psonly|nomonitor\fR ## action=\fISTAT|STATUS\fR ## flag=\fIY|N\fR (Default N) ## dtime=\fInumber\fR (Default 999999) ## verbose=\fIY|N\fR (Default N) ## .PP ## \&\fBrc.oracle\fR ## sid=\fI\s-1SID\s0\fR ## action=\fI\s-1RESTART\s0\fR ## verbose=\fIY|N\fR (Default N) ## .PP ## \&\fBrc.oracle\fR ## sid=\fI\s-1SID\s0\fR ## action=\fI\s-1FLAG\s0\fR ## flag=\fIY|N|SHOW\fR (Default \s-1SHOW\s0) ## .PP ## \&\fBS|K\fR\fInumber\fR\fBoracle\fR \fIstart|stop|restart|status|stat\fR ## .PP ## \&\fBS|K\fR\fInumber\fR\fBoracle\fR\-\fI\s-1SID\s0\fR \fIstart|stop|restart|status|stat\fR ## .PP ## \&\fBonline\fR \fISID[:psonly|nomonitor]\fR ## .PP ## \&\fBonline\fR \fB.\fR \fISID[:psonly|nomonitor]\fR ## .PP ## \&\fBoffline\fR \fISID[:psonly|nomonitor]\fR ## .PP ## \&\fBoffline\fR \fB.\fR \fISID[:psonly|nomonitor]\fR ## .PP ## \&\fBclean\fR \fISID[:psonly|nomonitor]\fR ## .PP ## \&\fBclean\fR \fB.\fR \fB0|1|2|3|4\fR \fISID[:psonly|nomonitor]\fR ## .PP ## \&\fBmonitor\fR \fISID[:psonly|nomonitor]\fR ## .PP ## \&\fBmonitor\fR \fB.\fR \fISID[:psonly|nomonitor]\fR ## .PP ## \&\fB*\fR \fBhelp=y\fR ## .PP ## \&\fB*\fR \fBversion=y\fR ## .SH "DESCRIPTION" ## .IX Header "DESCRIPTION" ## \&\fIrc.oracle\fR is a single shell program to start, stop, test oracle ## database (primary and standby); check and update the flag; and send ## notifications, if configured, for abnormal database conditions, and ## when the N flag becomes too old. ## .PP ## \&\fIrc.oracle\fR is 3\-in\-1, multifunctional program serving different ## purposes when installed with different names. When named \fIrc.oracle\fR, ## its canonical name, it is a general purpose program; when linked as ## \&\fBS|K\fR\fInumber\fR\fBoracle\fR or \fBS|K\fR\fInumber\fR\fBoracle\fR\-\fI\s-1SID\s0\fR, ## it is used as System V start / stop script; when linked as ## \&\fBonline\fR, \fBoffline\fR, \fBclean\fR, and \fBmonitor\fR, it is \s-1VCS\s0 ## (Veritas Cluster Server) Oracle agent. ## .PP ## ( This is like Atlantic Coast Airlines. When flying for United ## it is United Express; when flying for Delta, it is Delta connection; ## when flying on its own, it is Independence Air. All shares the same ## management structure, same support channel, and payroll system. ) ## .PP ## In order to describe each functionalities, a few concepts need to ## be cleared first. ## .Sh "\s-1ORATAB\s0" ## .IX Subsection "ORATAB" ## Each database needs to be listed in oratab. This is not \fIrc.oracle\fR ## requirement, but part of standard installation procedure. ## .PP ## The complication comes that oratab is located in /var/opt/oracle on ## Solaris, in /etc on \s-1AIX\s0 and Linux. On systems that use /etc/oratab, ## it is better to make the following changes once: ## .PP ## .Vb 7 ## \& mkdir -p /var/opt/oracle ## \& cp /etc/oratab /var/opt/oracle/oratab ## \& chown oracle:dba /var/opt/oracle /var/opt/oracle/oratab ## \& chmod 775 /var/opt/oracle ## \& chmod 664 /var/opt/oracle/oratab ## \& rm /etc/oratab ## \& ln -s ../var/opt/oracle/oratab /etc/oratab ## .Ve ## .PP ## and don't think about it. However, if you want to think about it ## please read \s-1MISCELLANEOUS\s0 \s-1INFORMATION\s0 section. ## .Sh "\s-1FLAG\s0" ## .IX Subsection "FLAG" ## Each database has a flag in oratab. As documented in Oracle \fIdbstart\fR ## program, the Y flag means to start the database when server reboots. ## As a corollary, this flag is an indication the database is up, and can ## be monitored. ## .PP ## The \s-1VCS\s0 agent uses the flag to determine whether to monitor the database ## or not. If you shutdown the database for maintenance, or cold backup, ## you should change the flag to N so that the agent won't start it up. ## Change the flag to Y if you want to the agent to monitor it. ## .PP ## \&\fBrc.oracle\fR combines the two steps \- database start/stop and flag change \- ## for you. ## .Sh "\s-1GENERAL\s0 \s-1PURPOSE\s0 \s-1UTILITY\s0" ## .IX Subsection "GENERAL PURPOSE UTILITY" ## When used as a general purpose utility for most common use, ## you specify two parameters, the Sid you are operate on, and the ## action which is either start, stop, restart, status, flag (show or ## change flag. The \fIverbose=y\fR option allows you to see what happens ## behind the scene. ## .PP ## For the \s-1START\s0 action, the default behavior is to startup an idle instance ## of a primary database, and change the flag to Y (Please see the \s-1FLAG\s0 ## section). However you can specify the flag to be either Y or N, or ## \&\s-1NO_CHANGE\s0. ## .PP ## The default is to open the primary database, you can specify the ## state you want to alter database to, \fInomount\fR, \fImount\fR, \fIopen\fR; ## or if the database was already in a \fInomount\fR or \fImount\fR state, ## you can specify the state change to \fIalter_mount\fR, \fIalter_open\fR, ## or \fIalter_mount_open\fR (first alter database mount, then alter ## database open). ## .PP ## If the database is an standby database, you need to tell \fIrc.oracle\fR ## either using the configuration file (see \s-1CONFIGURATION\s0), or ## command line options (\s-1DBTYPE\s0, \s-1MANAGED\s0, \s-1LOGFILE\s0) that: ## .PP ## .Vb 3 ## \& DBTYPE=STANDBY : it is a standby database. ## \& MANAGED=Y : it is a managed standby. ## \& LOGFILE=Y : it is a managed standby using current logfile. ## .Ve ## .PP ## The command line options have higher precedence over configuration file. ## .PP ## The archivelog option allows you to change archivelog mode. ## .PP ## For the \s-1STOP\s0 action, the default behavior is to shutdown the instance ## and change the flag to N. Again you can specify the flag to be either ## Y or N, or \s-1NO_CHANGE\s0. ## .PP ## The method option lets you specify how you want to shutdown. The default ## is \s-1ROLLOVER\s0. \fBrc.oracle\fR first tries to shutdown \s-1IMMEDIATE\s0. If it was ## not successful after \s-1ROLLTIME\s0 seconds (default 300), it executes shutdown \s-1ABORT\s0 ## and kill the \*(L"shutdown immediate\*(R" process. \*(L"shutdown \s-1ABORT\s0\*(R" is followed ## by \*(L"startup restrict open\*(R" for immediate recovery, and then a clean ## \&\*(L"shutdown\*(R". ## .PP ## The \s-1FLAG\s0 action shows you the current flag, or change it to what you ## asked for. ## .PP ## The \s-1STATUS\s0 or \s-1STAT\s0 action checks the health of the database. ## If the \s-1FLAG\s0 option is Y, it checks the flag for the database in ## oratab and only test the database when the flag is Y. The \s-1DTIME\s0 ## only applies to \s-1STANDBY\s0 database. It checks if the elapsed time since ## the last log application exceeds the \s-1DTIME\s0 you specified. ## .PP ## The \fBrc.oracle\fR utility can used manually, or in other programs ## such as Oracle cold backup, database monitoring. ## .PP ## For example, in a Oracle rman cold backup, put in pre\-script: ## .PP ## .Vb 2 ## \& rc.oracle sid= action=stop ## \& rc.oracle sid= action=start state=mount ## .Ve ## .PP ## and in post script, put in post\-script: ## .PP ## .Vb 1 ## \& rc.oracle sid= action=start state=alter_open ## .Ve ## .PP ## This is better than putting ## .PP ## .Vb 4 ## \& shutdown immediate ## \& startup mount ## \& ... ## \& alter database open ## .Ve ## .PP ## in rman script, because the default shutdown method for \fIrc.oracle\fR ## is \s-1ROLLOVER\s0; and the post-script will startup the database even when ## the rman backup fails. ## .Sh "\s-1SYSTEM\s0 V \s-1START/STOP\s0 \s-1SCRIPT\s0" ## .IX Subsection "SYSTEM V START/STOP SCRIPT" ## When the program is named as \fBS|K\fR\fInumber\fR\fBoracle\-\f(BI\s-1SID\s0\fB\fR, or ## \&\fBS|K\fR\fInumber\fR\fBoracle\fR, it can be used as ## system V start/stop scripts. The former is to start/stop ## the particular \fI\s-1SID\s0\fR regardless the flag. The latter is to ## start/stop \s-1ALL\s0 Sids whoes flag is Y. ## .PP ## For example: ## .PP ## To start / stop Sids with Y flag on Solaris: ## .PP ## .Vb 3 ## \& cp rc.oracle /etc/init.d/rc.oracle ## \& ln /etc/init.d/rc.oracle /etc/rc2.d/S90oracle ## \& ln /etc/init.d/rc.oracle /etc/rc0.d/K10oracle ## .Ve ## .PP ## The location and naming conventions are slightly different ## on other Sys V derived systems: ## .PP ## On \s-1AIX\s0 5.2: ## .PP ## .Vb 3 ## \& cp rc.oracle /etc/rc.d/init.d/rc.oracle ## \& ln /etc/rc.d/init.d/rc.oracle /etc/rc.d/rc2.d/S90oracle ## \& ln /etc/rc.d/init.d/rc.oracle /etc/rc.d/rc2.d/K10oracle ## .Ve ## .PP ## On SuSE Linux (2.4.7): ## .PP ## .Vb 3 ## \& cp rc.oracle /etc/init.d/rc.oracle ## \& ln /etc/init.d/rc.oracle /etc/init.d/rc3.d/S90oracle ## \& ln /etc/init.d/rc.oracle /etc/init.d/rc3.d/K90oracle ## .Ve ## .PP ## \&\fBrc.oracle\fR supports chkconfig. On redhat based systems, you ## can use chkconfig to add and delete the service: ## .PP ## .Vb 4 ## \& # chkconfig --add rc.oracle ## \& # chkconfig --list rc.oracle ## \& rc.oracle 0:off 1:off 2:on 3:on 4:on 5:on 6:off ## \& # chkconfig --del rc.oracle ## .Ve ## .Sh "\s-1VCS\s0 \s-1ORACLE\s0 \s-1AGENT\s0" ## .IX Subsection "VCS ORACLE AGENT" ## When the program is named \fBonline\fR, \fBoffline\fR, \fBclean\fR, and ## \&\fBmonitor\fR, it can be used as \s-1VCS\s0 (Veritas Cluster Server) ## Oracle agent. ## .PP ## This is done by installing the Solaris package MERotas provided ## in rc.oracle distribution. The following procedure is for ## \&\fIillustration\fR purpose only. ## .PP ## .Vb 1 ## \& #* For illustration purpose only, please use package for your platform. *# ## .Ve ## .PP ## .Vb 7 ## \& mkdir -p /opt/VRTSvcs/bin/Oracle ## \& cp rc.oracle /opt/VRTSvcs/bin/Oracle/rc.oracle ## \& cd /opt/VRTSvcs/bin/Oracle ## \& for i in online offline clean monitor; do ## \& ln rc.oracle $i ## \& done ## \& ln -s ../ScriptAgent OracleAgent # VCS provided ## .Ve ## .PP ## Please also see \fIadd_oracle_to_vcs.ksh\fR in the distribution ## on how to add the service to \s-1VCS\s0. Sid is the sole parameter ## that needs to register in \s-1VCS\s0. Basically, ## .PP ## .Vb 4 ## \& online SID = rc.oracle sid= action=start flag=Y ## \& offline SID = rc.oracle sid= action=stop method=immediate flag=Y ## \& clean SID = rc.oracle sid= action=stop method=abort flag=Y ## \& monitor SID = rc.oracle sid= action=stat flag=Y ## .Ve ## .PP ## We can run the commands on the left side manually before ## testing \s-1VCS\s0. ## .Sh "\s-1PSONLY\s0 \s-1AND\s0 \s-1NOMONITOR\s0" ## .IX Subsection "PSONLY AND NOMONITOR" ## The \fIextended\fR Sid can be used in the format SID:psonly|nomonitor. ## The qualifiers \fIpsonly\fR and \fInomonitor\fR, which are case inSENsiTIVE, ## are only applicable how the Sid is tested. ## .PP ## \&\fIpsonly\fR, as the name suggests, is used to test only the shadow processes, ## pmon and smon. If the two processes exist, the instance is considered ## up even when it is in nomount state. ## .PP ## \&\fInomonitor\fR, as the name suggests, is used not to test the the ## database, but considers it to be up. ## .PP ## These two qualifiers are used mainly for \s-1VCS\s0, to prevent it from ## automatically restart the database. It does not affect the failover. ## .PP ## A monitor program should be in place when used these two qualifiers. ## .Sh "\s-1CONFIGURABLE\s0 \s-1PARAMETERS\s0 \s-1AND\s0 \s-1VCS\s0 \s-1NOTIFICATION\s0" ## .IX Subsection "CONFIGURABLE PARAMETERS AND VCS NOTIFICATION" ## \&\fI\s-1ZERO\s0\fR configuration is required for normal use of \fIrc.oracle\fR. ## .PP ## However, following the philosophy of \*(L"simple things should be easy ## but complicated things should be possible\*(R", the configuration ## file in \f(CW$ORACLE_BASE\fR/.ora_\fI\s-1SID\s0\fR_env.ksh can be used for these ## parameters: ## .PP ## .Vb 6 ## \& DBTYPE ## \& MANAGED ## \& MAILLIST ## \& PAGELIST ## \& FTIME ## \& UMASK ## .Ve ## .PP ## The format of specification is \*(L"key = value\*(R". The left side should ## \&\fIcontains\fR the key as one word; ## the right side should contain the value and possibly spaces. ## The key is case INsenSItive. ## .PP ## So the following format all valid, and equivalent: ## .PP ## .Vb 2 ## \& # MailList = dba_list@foo.com ## \& MAILlist=dba_list@foo.com ## .Ve ## .PP ## \&\fI\s-1DBTYPE\s0\fR and \fI\s-1MANAGED\s0\fR are introduced before. ## .PP ## \&\fI\s-1MAILLIST\s0\fR and \fI\s-1PAGELIST\s0\fR are used for \s-1VCS\s0 agent notification. ## The agent sends page to \fI\s-1PAGELIST\s0\fR when (a) monitor failed; (b) ## monitor produced an unexpected status; (c) database start and stop. ## Unfortunately, monitor can not send page when the it times ## out. But hopefully, the notification will be sent by clean and ## online. The agent sends mail to \fI\s-1MAILLIST\s0\fR when the N flag for the ## database becomes too old (older than \fI\s-1FTIME\s0\fR if set, or 1 day). ## .PP ## The \s-1FTIME\s0 is a number in minutes, which provides a way for you to tell ## \&\fIrc.oracle\fR that you the flag is changed to N for x minutes. \fIrc.oracle\fR ## will send email to \fI\s-1MAILLIST\s0\fR if this limit is exceeded, once per day ## between 08:00 and 08:15 hours. ## .PP ## \&\fI\s-1UMASK\s0\fR is the umask value under which to start Oracle. ## .Sh "\s-1RETURN\s0 \s-1CODE\s0 \s-1AND\s0 \s-1ERROR\s0 \s-1MESSAGES\s0" ## .IX Subsection "RETURN CODE AND ERROR MESSAGES" ## The \s-1VCS\s0 monitor spits the following informational messages ## which can be used for log monitor. The \*(L"110\*(R" and \*(L"100\*(R" are ## return code required by \s-1VCS\s0. They are \fInot\fR part of the message. ## .PP ## .Vb 6 ## \& 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was up. ## \& 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] needed attention. Details in . ## \& 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was not tested with recent N flag. ## \& 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was not tested with old N flag. ## \& 110 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] had unexpected status. Details in . ## \& 100 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was down. Details in . ## .Ve ## .PP ## The return codes for system V start / stop script are not used. ## The brief message informs the \s-1SA\s0 what is going on: ## .PP ## .Vb 5 ## \& YYYY-MM-DD HH24:MI:SS Running S|Koracle with start|stop option. ## \& This may take a few minutes. ## \& When in doubt, please check . ## \& Working on ... ## \& YYYY-MM-DD HH24:MI:SS was up|down. ## .Ve ## .PP ## The return codes for start/stop should not be trusted. Either check the specific ## messages produced by \fIsqlplus\fR, or follow up start/stop with stat. The return ## code and informational messages for \fBrc.oracle\fR status option are: ## .PP ## .Vb 3 ## \& 0 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was up. ## \& 1 YYYY-MM-DD HH24:MI:SS [:psonly|nomonitor] was down. ## \& !0 YYYY-MM-DD HH24:MI:SS ## .Ve ## .PP ## For example, you can say: ## .PP ## .Vb 1 ## \& rc.oracle sid= action=stat || print " did not come up." ## .Ve ## .PP ## For flag change, it is better to check directly, for example: ## .PP ## .Vb 1 ## \& [[ $(rc.oracle sid= action=flag) == "Y" ]] || exit 1 ## .Ve ## .SH "PHILOSOPHY" ## .IX Header "PHILOSOPHY" ## The overriding philosophy used in developing this utility is ## \&\s-1KISS\s0 (Keep It Simple Stupid). ## .PP ## This philosophy is reflected in one script zero configuration ## (for normal usage), and one parameter to pass to \s-1VCS\s0 ## (unfortunately, the one's can not be changed to zero's). ## .PP ## The simplicity helps in following areas: ## .PP ## Maintenance. It is easier to maintain one script than N scripts. ## It eliminates the confusion what script is used for what purposes. ## .PP ## Deployment. Just copy the file to the right place, link with right ## names. (pkgadd and chkconfig for \s-1VCS\s0 and on Linux makes things easier). ## Zero coding is needed. Only one parameter \fISid\fR is communicated ## to the \s-1SA\s0's for \s-1VCS\s0. ## .PP ## Operation. Due to a simple interface with \s-1VCS\s0 (one parameter), ## during Oracle upgrade, all we need to do is change the flag N, ## upgrade, and change the flag back to Y. And \s-1SA\s0 does not need ## get involved the database is shutdown for maintenance, or cold ## backup. ## .SH "MISCELLANEOUS INFORMATION" ## .IX Header "MISCELLANEOUS INFORMATION" ## M1. \s-1ORATAB\s0 \s-1LOCATION\s0 ## .PP ## If \fIrc.oracle\fR only reads the file, it does not matter whether it is ## located in a Oracle owned directory /var/opt/oracle, or a system directory ## /etc. It can detect the location and and use it. ## .PP ## \&\fIrc.oracle\fR changes the the flag in certain operations, and in order to ## guarantee the read consistency, mv is used: ## .PP ## .Vb 1 ## \& mv oratab.tmp oratab ## .Ve ## .PP ## If copy is used, the oratab is not usable during the operation, producing ## unpredictable errors. \fImv\fR unlinks the old file, which is not possible ## if the executor does not own the directory. This also explains why link ## in reverse direction (/var/opt/oracle/oratab \-> /etc/oratab) will not work. ## .PP ## The read consistency is guaranteed by the \s-1POSIX\s0 standard ## \&\fIhttp://www.opengroup.org/onlinepubs/009695399/\fR: ## .PP ## .Vb 7 ## \& If the link named by the new argument exists and the file's link count ## \& becomes 0 when it is removed and no process has the file open, the ## \& space occupied by the file shall be freed and the file shall no longer ## \& be accessible. If one or more processes have the file open when the ## \& last link is removed, the link shall be removed before rename() ## \& returns, but the removal of the file contents shall be postponed until ## \& all references to the file are closed. ## .Ve ## .PP ## M2. NON-MEANINGFUL \s-1RETURN\s0 \s-1CODE\s0 ## .PP ## Return values for start/stop is not meaningful as shown below, ## therefore one should always follow start/stop with stat. ## .PP ## .Vb 8 ## \& $ svrmgrl ## \& SVRMGR> connect internal ## \& Connected. ## \& SVRMGR> shutdown ## \& ORA-01149: cannot shutdown - file 1 has online backup set ## \& ORA-01110: data file 1: '/ora01/oradata/IBKSAD1/system01.dbf' ## \& SVRMGR> ^D ## \& Server Manager complete. ## .Ve ## .PP ## .Vb 2 ## \& $ echo $? ## \& 0 ## .Ve ## .PP ## This is where the Oracle supplied dbstart and dbshut erred. The ## following is excerpted from dbshut, ## .PP ## .Vb 4 ## \& ... ## \& connect internal ## \& shutdown ## \& EOF ## .Ve ## .PP ## .Vb 5 ## \& if test $? -eq 0 ; then ## \& echo "Database \e"${ORACLE_SID}\e" shut down." ## \& else ## \& echo "Database \e"${ORACLE_SID}\e" not shut down." ## \& fi ## .Ve ## .SH "AUTHOR AND ACKNOWLEDGMENT" ## .IX Header "AUTHOR AND ACKNOWLEDGMENT" ## Michael Wang <\fIxw73@columbia.edu\fR> with help from many people. ## Contributions are acknowledged in the version history within ## the programs. ## .SH "VERSION HISTORY" ## .IX Header "VERSION HISTORY" ## .Vb 4 ## \& version 10.6, 2008-05-26, Michael Wang . ## \& * Port to ksh 88 requested and sponsored by ## \& + DataBase Intelligence Group (http://dbigusa.com). ## \& * Various fixes and clean up. ## .Ve ## .PP ## .Vb 4 ## \& version 10.5, 2004-10-18, Michael Wang . ## \& * Added UMASK configuration parameter. ## \& * Enhanced get_var function. ## \& * Fixed test relic in restarting RAC ocmstart. ## .Ve ## .PP ## .Vb 2 ## \& version 10.4, 2004-08-29, Michael Wang . ## \& * Tested on standalone AIX 5.2 with reboot. ## .Ve ## .PP ## .Vb 4 ## \& version 10.3, 2004-08-23, Michael Wang . ## \& * revert to changing flag to Y after online|offline|clean ## \& + per discovery of VCS behavior by Jose Bacalla. ## \& * Added flat_opt function. ## .Ve ## .PP ## .Vb 2 ## \& version 10.2, 2004-08-21, Michael Wang . ## \& * Tested Linux RAC (Oracle 9.2.0.4 on RHEL 3.0 compatible) with reboot. ## .Ve ## .PP ## .Vb 2 ## \& version 10.1, 2004-08-20, Michael Wang . ## \& * Tested on AIX 5.2 VCS with Roy Morton. ## .Ve ## .PP ## .Vb 11 ## \& version 10.0, 2004-08-10, Michael Wang . ## \& * Rewrite to address the following issues: ## \& + PSONLY and NOMONITOR options. ## \& + Optional notification for monitor failure and state change. ## \& + Self maintained logs: clean user experience and capability to debug. ## \& + ROLLOVER shutdown method as default: IMMEDIATE -> ABORT. ## \& + STARTUP state, eg: ALTER_MOUNT, ALTER_OPEN. ## \& + Linux (redhat) support: chkconfig and subsys lock. ## \& + RAC support: startup oracm. ## \& + STANDBY database support. ## \& + modularity attempt for futher development: rc_oracle function. ## .Ve ## .PP ## .Vb 3 ## \& version 9.5, 2003-03-04, Michael Wang . ## \& * Changed "ksh $0" to "$0" so that what in #! line will be used. ## \& * Set UNIX95 for HP-UX to get SUSv2 bahavior for ps command (-o option). ## .Ve ## .PP ## .Vb 4 ## \& version 9.4b, 2002-12-25, Michael Wang . ## \& * Changed _grep "[o]ra_.*_$ORACLE_SID *$")_ ## \& to _grep "[0-9] ora_.*_$ORACLE_SID *$")_ ## \& Otherwise, it will grep "grep ora_pmon_SID". ## .Ve ## .PP ## .Vb 2 ## \& version 9.4a, 2002-11-20, Michael Wang . ## \& * Default method=smart; "sleep 1" => "sleep 5". ## .Ve ## .PP ## .Vb 5 ## \& version 9.4, 2002-06-17, Michael Wang . ## \& * Changed "first_time = (SELECT MAX(first_time) FROM v\e$log_history)" ## \& to "sequence# = (SELECT MAX(sequence#) FROM v\e$log_history)" ## \& to ensure single row. ## \& * Initialize SMARTIME. ## .Ve ## .PP ## .Vb 3 ## \& version 9.3, 2002-04-25, Michael Wang . ## \& * Added method=smart. ## \& * Added version=y. ## .Ve ## .PP ## .Vb 3 ## \& version 9.2, 2002-01-14, Michael Wang . ## \& * Fixed the problem that "help=y" leaves an empty dir in /tmp. ## \& * Changed "exit -- $?" to "exit $?": (exit -- 1); print $? => 0 in ksh88. ## .Ve ## .PP ## .Vb 16 ## \& version 9.1, 2001-12-01, Michael Wang (xw73@columbia.edu). ## \& * New way of getting SID_LINE: ## \& (1) $ORACLE_BASE/.rc.oracle.cf: #_ORACLE_SID:* ## \& (2) /var/opt/oracle/oratab: #_ORACLE_SID:* ## \& (3) /var/opt/oracle/oratab: ORACLE_SID:* ## \& * Relaxed GLOBAL_NAME test. ## \& * Derive owner from $ORACLE_HOME/bin/oracle. ## \& * Default UPASS is "/ as sysdba". Oracle 7 needs to specify different UPASS. ## \& * Depress output for action=stat verbose=n. ## \& * Fix FTIME issue: ## \& j=; unset j; j=011; print "$j" => 9 ## \& typeset -Z6 j; j=; print "$j" => "" ## \& - Bourne shell detection simplification. "PATH= print" and (print) forks, ## \& and only forked stderr can be redirected in Bourne shell. ## \& - Spool to a tempfile in /tmp instead of /var/opt/oracle. ## \& - Changed "exit -- -1" to "exit 127". (exit -- -1); print $? => 0 in ksh88. ## .Ve ## .PP ## .Vb 24 ## \& version 9.0, 05/26/2001, Michael Wang (xw73@columbia.edu). ## \& * Eliminate "svrmgrl" and "connect internal" for Oracle 9i+ where these ## \& are no longer supported. ## \& * Creating an Oracle user is optional (put "/ as sysdba" in UPASS field). ## \& This is not new feature but never documented, never found and used. ## \& * Added pager/email notification, and action=page|mail, message=... options ## \& with help from Andrew Blatt, Janet Zhu on CVS. "A nasty solution for a ## \& nasty problem in a nasty world"(TM). ## \& * Check FLAG before lsnrctl to ease the upgrade per Raj Pande. ## \& * "help=y" now uses "real man"(TM) page. Eliminated less helpful online help. ## \& * More generic and safer removal of .aud and .trc files: ## \& Solaris: ${lower_case_sid}_ora_$spid.trc, Linux: ora_spid.trc, ## \& AIX: ora_$spid_${lower_case_sid}.trc. Oracle Enhancement #: 1665035. ## \& * FLAG/FTIME update fix. ## \& - used POSIX PATH. ## \& - Use of POSIX "id -u" and "id -un" command. ## \& - Added "print" in additon to "$RANDOM" for ksh test to exclude bash. ## \& - Change "exit -1" to "exit -- -1" to make it work with PD KSH ## \& (PD KSH v5.2.14 99/07/13.2 on Red Hat Linux 7.1, Kernel 2.4.4). ## \& - Workaround different behaviors on "Ctrl-C" on trap between PD KSH and ## \& AT&T KSH: PD KSH does not run exit trap upon "Ctrl-C", AT&T KSH does. ## \& - uses cp -p $ORATAB $ORATAB.tmp to create a temp file with same permission. ## \& - Eliminate fork (grep) in processing SID_LINE. ## \& - More concise KSH construct for startup with and without $PFILE. ## .Ve ## .PP ## .Vb 12 ## \& version 5.4, 02/21/2001, Michael Wang (xw73@columbia.edu). ## \& * Tightened up the locking code. ## \& * Added restart option for convenience only per Raj Pande. It stop and start ## \& the database with default options. ## \& * Added identifier "$ORACLE_SID: " for flag change message. ## \& * exit 255 => exit -1 ## \& * Change [[ -z $ORATAB && -r $i ]] && ORATAB=$i to ## \& [[ -r $i ]] && { ORATAB=$i; break; } ## \& * Last line of start/stop options was: [[ $SHOW = Y ]] && exit -1. ## \& [[ $SHOW = Y ]] would be the last command if it is false and hence its ## \& status becomes the status of the script. The last line is changed to: ## \& (( status == 0 && fstatus == 0 )). ## .Ve ## .PP ## .Vb 4 ## \& version 5.3, 01/31/2001, Michael Wang (xw73@columbia.edu). ## \& * Added date before "tail -1". ## \& * Change [[ -z $Perl && -x $i ]] && Perl=$i to ## \& [[ -x $i ]] && { Perl=$i; break; } for efficiency. ## .Ve ## .PP ## .Vb 2 ## \& version 5.2, 01/26/2001, Michael Wang (xw73@columbia.edu). ## \& * Added ftime= option for start/stop. ## .Ve ## .PP ## .Vb 5 ## \& version 5.11, 01/19/2001, Michael Wang (xw73@columbia.edu). ## \& * Replace sed with ksh built-in: ## \& THE_UDUMP_DEST=$ORACLE_HOME${THE_UDUMP_DEST#?} ## \& * condition rm to eliminate fork when file does not exist: ## \& [[ -f $i_aud ]] && rm -f $i_aud ## .Ve ## .PP ## .Vb 3 ## \& version 5.1, 01/05/2000, Michael Wang (xw73@columbia.edu). ## \& * change "exit 0" to "exit $?" in oracle-SID case. This affects backup. ## \& * change "FOREVER" to "1 DAY". ## .Ve ## .PP ## .Vb 29 ## \& version 5.0, 12/21/2000, Michael Wang (xw73@columbia.edu). ## \& To incorporate the modifications made by Raj Pande and Pradeep Malhotra: ## \& * Accepts sid=..., action=..., and other options when the program is ## \& named rc.oracle or any other names except the following: ## \& oracle-SID, [SK]oracle, online, offline, clean, monitor. ## \& * When the program is named oracle-SID, it will perform passed action ## \& for this SID. Program with this name is ready to be used as Solaris ## \& start/stop script for this SID without the need for a wrapper script. ## \& This is the old behavior. ## \& * When the program is named Soracle, or Koracle, ## \& it will perform passed start or stop action for ALL oracle SIDs in ## \& oratab with Y flag. This is to simulate dbstart/dbshut behavior. ## \& * When the program is named online, offline, clean, monitor, it will ## \& start, stop immediate, stop abort, and test oracle database for passwd ## \& SID. Programs with these names are ready to be used as VCS entry points ## \& without the need for wrapper scripts. ## \& * Flag check. If the lifetime (in number of minutes) of N flag is specified ## \& (9th field in oratab) and Perl is available (VCS has Perl), then it will ## \& check if N flag is older than specified minutes, otherwise it will check ## \& if N flag is older than 1 day. ## \& * VERBOSE is defaulted to N instead of Y. ## \& Other changes: ## \& * FILTER=Y for action=stat to filter out oerrs, specified as the 8th field ## \& in oratab in the format of oerr1|oerr2|... Example: ## \& ora-12345|ora-23456|... ## \& * Streamline the option processing. ## \& * Added exit code 255 for "catch-all" errors. ## \& * Some change in error message for consistency. ## \& * "echo" is replaced by "print/print -r --" for robustness and compatibility. ## .Ve ## .PP ## .Vb 21 ## \& version 4.0, 10/10/2000, Michael Wang (xw73@columbia.edu). ## \& * version number advanced beyond pi. Tested on the following platforms: ## \& - ksh Version M 1993-12-28 j ## \& - ksh Version M-12/28/93d on Sun Solaris 2.6, 7 (dtksh). ## \& - ksh Version M-11/16/88i on Sun Solaris 2.6, 7. ## \& - ksh Version M-11/16/88f on IBM AIX 4.3.3. ## \& - PD KSH v5.2.14 99/07/13.2 on Red Hat Linux 6.2. ## \& * Exit code changed from 0 to 4 when Oracle executable can not be found. ## \& * Added start option ARCHIVELOG=([YN0][YN0]|Y|N|NULL|R) per discussion ## \& with Joe Ng. ## \& * Array can not be reset on Version M-11/16/88f on AIX 4.3.3 ## \& i[0]=; typeset -u i; i=; unset i; i=b; echo $i => B ## \& Changed to i to ix to avoid conflict. ## \& * "==" in [[ string == pattern ]] is replaced by "=" for compatibility ## \& with older Korn Shell (eg Version M-11/16/88f). ## \& * Added " *" in i=$(ps -eaf | egrep "[0-9] ora_.*_$ORACLE_SID *$") ## \& AIX 4.3 ps output has blank at end of line. ## \& * Get rid of the_space_holder. ## \& * Unset name for name=value pair. Example, TEST=. ## \& * changed _echo "$ ..."_ to _echo "\e$ ..."_. The former expression ## \& exhibits different behaviour under differnet ksh versions. ## .Ve ## .PP ## .Vb 32 ## \& version 3.14159, 08/18/2000, Michael Wang (xw73@columbia.edu). ## \& * The test method for primary database is rolled back to version 2.0: ## \& SELECT global_name from global_name, and compare the global_name ## \& before the "." with ORACLE_SID instead of creating tables per discussion ## \& with Rana Chander, Matthew Soloman, Susan Gruebel, and Sheck Cho. ## \& Yuriy Leyzerovskiy of Oracle Corp provided grant statements on v$tables. ## \& Prerequisite: ## \& - /var/opt/oracle/oratab.SID: ## \& SID:ORACLE_HOME:Y/N:PFILE:OWNER:DBTYPE:UPASS ## \& - create user oracle_probe identified by oracle_probe ## \& default tablespace temp temporary tablespace temp; ## \& - grant create session to oracle_probe; ## \& - grant select on SYS.V_$PARAMETER to oracle_probe; ## \& - grant select on SYS.V_$SESSION to oracle_probe; ## \& - grant select on SYS.V_$MYSTAT to oracle_probe; ## \& - grant select on SYS.V_$PROCESS to oracle_probe; ## \& IF global_name is not already set to ORACLE_SID, ## \& - alter database rename global_name to ; ## \& On a box with multiple oracle users (oracle, oracle01, oracle02, ...): ## \& - chown oracle:dba /var/opt/oracle # on all nodes of cluster ## \& - chmod 775 /var/opt/oracle # on all nodes of cluster ## \& * Added $ anchor in i=$(ps -eaf | egrep "[0-9] ora_.*_$ORACLE_SID$") ## \& to cover the case that databases "foo" and "foobar" reside on same box. ## \& * Rewrite "[[ -z $(eval echo \e$$i) ]]" as "eval [[ -z \e$$i ]]". ## \& per suggestion from Dan A. Mercer on the internet. This avoids ## \& unnecessary fork(), and reduces cpu time. ## \& Tested on Sun E250 with 2x400MHz cpu, 2GB RAM, A1000 storage: ## \& $ time sh oracle-mysid stat verbose=n ## \& THE DATABASE mysid IS UP. ## \& real 0m0.43s ## \& user 0m0.28s ## \& sys 0m0.21s ## .Ve ## .PP ## .Vb 20 ## \& version 3.1415, 07/22/2000, Michael Wang (xw73@columbia.edu). ## \& * Expanded oratab to include pfile, owner, and dbtype (PRIMARY, STANDBY, ## \& STANDBY/MANAGED ) to support the new functionalities: ## \& - Support running as different $OWNER. ## \& - Support "startup pfile=<...>" option. ## \& - Support standby database. ## \& * Added archive option to archive log current. ## \& * Enhanced SHOW=Y option to display SQL statement. ## \& * FLAG=NULL option for start/stop to leave FLAG alone. ## \& * Changed svrmgrl to sqlplus in testing PRIMARY (versus STANDBY) database. ## \& * Eliminated TABLESPACE clause, instead using the test user's default one. ## \& * Change on PATH and RUN_USER for Linux compatibility. ## \& * unset LD_LIBRARY_PATH. ## \& Properly linked oracle executables do not need LD_LIBRARY_PATH. ## \& In Oracle 8i, set LD_LIBRARY_PATH causes listener problem, Ref: ## \& TAR 12953862.600, Doc ID 1023333.1, Bug ID 1147434. ## \& * "startup restrict open" and "shutdown" only runs after ## \& "shutdown abort" but not "shutdown immediate". ## \& * MASSIVE code clean up to support above functionalities and for ## \& programming purity and efficiency. ## .Ve ## .PP ## .Vb 13 ## \& version 3.141, 07/15/2000, Michael Wang (xw73@columbia.edu). ## \& * Fixed the race condition when multiple processes test the database. ## \& The bug was found by Janet Zhu and Susan Gruebel in an environment where ## \& the script is used for backup as well as for QualixHA+. ## \& The fix is to replace the fixed table_name "oracle_probe" with ## \& variable name T, and slightly changed test sequence as shown ## \& below. The old test sequence is indicated by () at end of line. ## \& (1) drop table T without verification (N/A) ## \& (2) create table T with verification (2) ## \& (3) insert table T with verification (3) ## \& (4) update table T with verification (4) ## \& (5) drop table T with verification (1) ## \& This fix covers the situation when table is inadvertently left behind. ## .Ve ## .PP ## .Vb 2 ## \& version 3.14, 03/17/2000, Michael Wang (xw73@columbia.edu). ## \& * More reliable method of updating oratab. ## .Ve ## .PP ## .Vb 2 ## \& version 3.1, 01/20/2000, Michael Wang (xw73@columbia.edu). ## \& * Minor midifications in Oracle env variable determination and verification. ## .Ve ## .PP ## .Vb 4 ## \& version 3.0, 12/27/1999, Michael Wang (xw73@columbia.edu). ## \& * Enhancement and cleanup. exp style user interface: exp help=Y ## \& The line: [ "$RANDOM" = "$RANDOM" ] && exec ksh "$0" "$@" ## \& is provided by David Korn. ## .Ve ## .PP ## .Vb 7 ## \& version 2.0, 05/27/1999, Michael Wang (xw73@columbia.edu). ## \& * Susan Gruebel provided fix for failover during hot backup. ## \& * Susan Gruebel suggested test if database is open. ## \& * ORATAB search order: oratab.$ORACLE_SID, oratab ## \& * Fixed the order of FLAG and database state change. ## \& start: START DATABASE, FLAG -> Y ## \& stop: FLAG -> N, STOP DATABASE ## .Ve ## .PP ## .Vb 3 ## \& version 1.0, 07/29/1998, Michael Wang (xw73@columbia.edu). ## \& * IPO. ## \& * Mikhail Rasol provided code for finding svrmgrl PID. ## .Ve ## MAN_STOP