Re: systemd issues

  • From: "Radoulov, Dimitre" <cichomitiko@xxxxxxxxx>
  • To: mschmitt@xxxxxxxxxxxx, "oracle-l@xxxxxxxxxxxxx" <oracle-l@xxxxxxxxxxxxx>
  • Date: Thu, 2 May 2019 09:52:19 +0200

Hello,

I wrote a simple script that seems to work, it starts/stops multiple Oracle instances and listeners (it looks for entries with Y in oratab).
The content of the systemd service definition is reported in the header.
You could try to use it as a template and adapt it for your environment.


Dimitre


On 01/05/2019 22.00, Michael Schmitt wrote:


Hi Oracle-l

Has anyone had any luck getting systemd to play nicely with Oracle databases?  It seems like every document I have read offers different suggestions and each of those come with their own set of issues

The main issue we are having is systemd killing the oracle processes in different circumstances (when databases are manually restarted due to cold backups/patching/etc).  We really just want systemd to call our custom startup/shutdown scripts when the server reboots (and shutdown the database in advance of the network), instead of trying to manage the database processes

Thanks in advance

#!/bin/sh

# description: Oracle auto start-stop script.
# /lib/systemd/system/dbora.service
# systemctl daemon-reload
# [Unit]
# Description=The Oracle Database Service
# After=syslog.target network.target
#
# [Service]
# # systemd ignores PAM limits, so set any necessary limits in the service.
# # Not really a bug, but a feature.
# # https://bugzilla.redhat.com/show_bug.cgi?id=754285
# LimitMEMLOCK=infinity
# LimitNOFILE=65535
#
# #Type=simple
# # idle: similar to simple, the actual execution of the service binary is 
delayed
# #       until all jobs are finished, which avoids mixing the status output 
with shell output of services.
# # Type=idle
# Type=forking
# KillMode=none
# TimeoutStopSec=10min
# RemainAfterExit=yes
# User=oracle
# Group=oinstall
# Restart=no
# ExecStart=/usr/local/bin/dborasd start
# ExecStop=/usr/local/bin/dborasd stop
#
# [Install]
# WantedBy=multi-user.target



_progname=${0##*/}
_logdir=/var/log
_logfile=${_progname}.log
_oratab=/etc/oratab
_oraenv=/usr/local/bin/oraenv
_ora_owner=oracle
_lockfile=/tmp/$_progname.$$


[ -f "$_lockfile" ] && {
  printf >&2 'another instance of %s is running, exiting ...\n' "$_progname"
  exit 1
  }

trap 'rm -rf "$_lockfile"' EXIT INT TERM HUP

_usage() {
  cat << EOF >&2
usage: $_progname [stop|start|status]
EOF
  exit 1
}


(( $# != 1 )) && _usage

[ -f "$_oratab" ] || {
  printf >&2 '%s is missing!\n' "$_oratab"
  exit 1
  }
  
_dbs=( $( grep '^ *[^#].*:Y *$' "$_oratab" | cut -d: -f1,2 ) )

(( "${#_dbs[@]}" )) || exit

_ora_manage_db() {
  local _ora_sid=$1
  local _ora_owner=$2
  local _ora_action=$3
  local _ret

  local _sql_status='select null from dual;'
  local _sql_start='startup;'
  local _sql_stop='shutdown immediate;'
  local _sql_abort='shutdown abort;'

  case $_ora_action in
    ( stop )   _current_sql=$_sql_stop   ;;
    ( start )  _current_sql=$_sql_start  ;;
    ( status ) _current_sql=$_sql_status ;;
    ( abort )  _current_sql=$_sql_abort  ;;
    ( * )      return 1                  ;;
  esac

_sql="
whenever sqlerror exit failure
whenever oserror exit failure
$_current_sql
exit
"

#exec > /dev/null 2>&1
ORAENV_ASK=NO
ORACLE_SID="$_ora_sid"
PATH=$PATH:/usr/local/bin
export ORAENV_ASK ORACLE_SID PATH
. "$_oraenv" > /dev/null
"$ORACLE_HOME"/bin/sqlplus -sl / as sysdba <<< "$_sql" > /dev/null 2>&1 || 
return 1
  }



_ora_manage_listener() {
  local _ora_sid=$1
  local _ora_owner=$2
  local _ora_action=$3

  case $_ora_action in
    ( stop )   _cmd=stop   ;;
    ( start )  _cmd=start  ;;
    ( status ) _cmd=status ;;
    ( * )      return 1    ;;
  esac

  export _cmd

#exec > /dev/null 2>&1  

ORAENV_ASK=NO
ORACLE_SID="$_ora_sid"
PATH=$PATH:/usr/local/bin
export ORAENV_ASK ORACLE_SID PATH
. "$_oraenv" > /dev/null
if [ -f  "$ORACLE_HOME"/network/admin/listener.ora ]; then
  if grep -qi "^LISTENER_$_ora_sid" "$ORACLE_HOME"/network/admin/listener.ora; 
then
    _listener="$( tr '[:lower:]' '[:upper:]' <<< LISTENER_$_ora_sid )"
  elif grep -qiw "^LISTENER" "$ORACLE_HOME"/network/admin/listener.ora; then
    _listener=LISTENER
  else
    _listener=
  fi
fi

export _listener
[ -n "$_listener" ] &&
  "$ORACLE_HOME"/bin/lsnrctl "$_cmd" "$_listener" > /dev/null 2>&1 || return 1
  }

case $1 in
  ( start )
    unset _rc
    for _db in "${_dbs[@]}"; do
      _ora_sid="${_db%:*}"
      _ora_manage_db "$_ora_sid" "$_ora_owner" "status" && {
        printf '%s is already running!\n' "$_ora_sid"
        continue
          }

      _ora_manage_db "$_ora_sid" "$_ora_owner" "start" &&
        printf >&2 'start up succeeded for %s\n' "$_ora_sid" || {
          printf >&2 'start up failed for %s\n' "$_ora_sid"
          _rc+=( $? )
            }

      _ora_manage_listener "$_ora_sid" "$_ora_owner" "status" && {
        printf >&2 'listener %s is already running:\n' "listener_$_ora_sid"
        continue
          }

      _ora_manage_listener "$_ora_sid" "$_ora_owner" "start" &&
        printf >&2 'listener %s started\n' "listener_$_ora_sid" || {
        printf >&2 'listener %s failed to start\n' "listener_$_ora_sid"
        _rc+=( $? )
          }

      for _c in ${_rc[@]}; do
        (( _c )) || exit 1
        done
      done

        ;;
  ( status )
    unset _rc
    for _db in "${_dbs[@]}"; do
      _ora_sid="${_db%:*}"
      _ora_manage_db "$_ora_sid" "$_ora_owner" "status" && 
        printf >&2 'status succeeded for %s\n' "$_ora_sid" || {
          printf >&2 'status failed for %s\n' "$_ora_sid"
          _rc+=( $? )
            }

      _ora_manage_listener "$_ora_sid" "$_ora_owner" "status" &&
        printf >&2 'status succeeded for %s\n' "listener for $_ora_sid" || {
          printf >&2 'status failed for %s\n' "listener for $_ora_sid"
          _rc+=( $? )
            }
    done
                
        for _c in ${_rc[@]}; do
      (( _c )) || exit 1
    done
                ;;

  ( stop )
    unset _rc
    for _db in "${_dbs[@]}"; do
      _ora_sid="${_db%:*}"
      _ora_manage_db "$_ora_sid" "$_ora_owner" "status" || {
        printf >&2 'instance already down: %s\n' "$_ora_sid"
        continue
          }
      _ora_manage_db "$_ora_sid" "$_ora_owner" "stop" &&
        printf >&2 'stop succeeded for %s\n' "$_ora_sid" || {
          printf >&2 'stop failed for %s\n' "$_ora_sid"
          _rc+=( $? )
            }

      _ora_manage_listener "$_ora_sid" "$_ora_owner" "status" || {
        printf >&2 'listener is already down: \n'
        continue
          }

      _ora_manage_listener "$_ora_sid" "$_ora_owner" "stop" &&
        printf >&2 'listener %s stopped\n' listener_"$_ora_sid" || {
          printf >&2 'listener %s failed to start\n' listener_"$_ora_sid"
          _rc+=( $? )
            }

      for _c in ${_rc[@]}; do
        (( _c )) || exit 1
      done

  done
        ;;
  ( * ) _usage
        ;;
esac

Other related posts: