perjantai 26. lokakuuta 2012

starting Oracle DB automatically at server startup

Starting Oracle database automatically at server startup

Once we have a running SOA Suite installation (in my case it is running on a eucalyptus based cloud), the next step to do is to create Linux services for automatically staring the database and the SOA environment at system boot. You may also decide not to do this as it perfectly sensible to start the DB and SOA domains only when you need.

Generic Guideline for creating a service for starting the database
First there is a need to understand how Linux services are created:
  • Almost all applications come from separate startup and shutdown scripts that are located normally in the same bin directory as the application. If you are writing your own application you will write the scripts yourself. Give them execute rights with #chmod 755 <scriptname>
  • The linux service itself is also a script file that is placed in /etc/rc.d/init.d/. The name of the service is the name of the script without any extensions so if you want to have a service called ‘myservice’ you would have a script named also ‘myservice’. There is normally a symbolic link also from /etc/init.d to the directory where startups scripts exists as a shortcut.
  • Service scripts take standardized parameters like start, stop, restart and status. 
  • Create the service based on the script template given below. Add calls to your startups and stop scripts there
  • Give access and execute rights to the file you just created. E.g. chmod 775 /etc/init.d/myservice or in our case ‘oracle’ is the name of the service and the script file
  • It is customary to create lock files at/var/lock/subsys. When the service is started, the lock file is created and when it is shut down, the lock file is deleted. The name of the lock file should be the name of the service. I use the lock file only to track the status of the service since the DB itself checks that it cannot be started multiple times.
  • Run the following command to add service for chkconfig management #chkconfig  --add myservice
  • And now you have a service called myservice. If the service has the magic line stating with #chkconfig it will automatically started at next boot. See below for more explanation on it.
  • You might first want to test it. Use the commands:’ #service myservice start’ for starting.’ #service myservice restart’ for restrating and’ #service myservice stop for stopping it’
  • if you want your service to start at system start up run following command: ‘#chkconfig –level 35 myservice on’ if the #chkconfig line is missing from the script
  • finally: you can remove your service from start up with command: ‘#chkconfig myservice off
  • and also you can remove from chkconfig management your service with command’ #chkconfig  --del myservice’
Couple of notes about the script below.

The following line that looks like a comment is actually very meaningful
# chkconfig: 35 90 12

The first number tells what run levels the service automatically starts up. The number 35 means run levels 3 and 5. On the same run levels the service will be shut down when the server is shutting down also.

"Runlevel" defines the state of the machine after boot.Redhat has the following run level:
0    Halt
1    Single-User mode
2    Multi-user mode console logins only (without networking)
3    Multi-User mode, console logins only
4    Not used/User-definable
5    Multi-User mode, with display manager as well as console logins (X11)
6    Reboot
More on runlevels at: http://en.wikipedia.org/wiki/Runlevel

The second number tells at when to start the service in the startup sequence. This number is actually used for sorting scripts when the system moves from run level to another and the services are started in sorted order. So the numbers for different services do not need to be sequential.

The last number tells that when the server is shut down, in what priority order it is shut down relative to other services (similar to previous number).

If you want to know what numbers to assign, you can go to directory /etc/rc.d/rc<level>.d so that you can see what priorities are already assigned to which service. This directory contains symbolic links to the actual service scripts. Files starting with S are startups scripts and files starting with K are stop scripts.  The S-scripts are on the level where the service is started but the K-scripts on the level where they no longer are running.

In the script at near the top we source the script ‘functions’ from directory ‘/etc/init.d’. Sourcing is a way of executing scripts so that all environment variables and functions defined in the script will be available in the running shell. Normally when you execute a script, the shell starts a new process to run the script and when the script exists, the new process is terminated and all variables defined by it are deleted. There is a short-cut to source command ‘.’. The line . /etc/init.d/functions means that the shell reads in all commands from this file and executes them like a user had manually typed them in. The script defines a number of functions that are later used. The service script would run perfectly well without it but the functions there are needed to integrate the script to the bootup sequence that the new service will be shown nicely on the console when the machine boots (in other words you service will be visible and the console shows whether the service started fine or failed). The functions defined there are ‘success’ and ‘failure’.

When we start and stop the service, on the following line there is:
[ $? -eq 0 ] && success || failure
$? Is a variable referring to the exit code of the previously run command. If it 0, the command executed succssfully. The funny looking syntax on the line is actually an if-statement, you could equally well write it out as a normal if, but most service scripts use this alternate syntax. If it executed well, the function ‘success’ is next invoked and this outputs to the console OK message about the end result and if it failed, the function ‘failure’ is invoked.


#!/bin/bash
# chkconfig: 35 90 12
# description: myservice server
#
RETVAL=0;
LOCKD=/var/lock/subsys
LOCKF=$LOCKD/myservice

if [ -f /etc/init.d/functions ]; then
    . /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ]; then
    . /etc/rc.d/init.d/functions
else
    exit 0
fi

start() {
echo –n “Starting <My Service>”
if [ -d $LOCKD ]; then
   touch $LOCKF
fi 
# Commands to start the service go here…
[ $? -eq 0 ] && success || failure
}

stop() {
echo –n “Stopping <My Service>”
# Commands to stop the service go here…
[ $? -eq 0 ] && success || failure
if [ -e $LOCKF ]; then
    rm -f $LOCKF
fi
 
}

restart() {
stop
start
}

case “$1″ in
start)
  start
;;
stop)
  stop
;;
restart)
  restart
;;

status)
echo -n "<My Service> "
if [ -e $LOCKF ]; then
     echo "is running..."
 else
     echo "is stopped"
 fi
;;
*)
echo $”Usage: $0 {start|stop|status|restart}”
exit 1
esac

exit $RETVAL 



Oracle Database as Linux service

The script for running Oracle DB as a linux service is below. The main thing that you need to do to use this script, is to change the ORACLE_SID unless it is the default orcl. Also if the oracle user is anything different than oracle, then you’d have to change the environment variable OUSER but this would be quite rare. All the other environment variables should come from the oraenv-script.

One more thing to check is to make sure that there is a directory /var/lock/subsys. This should be by default but in the images I have been using in our eucalyptus cloud environment, there have been images that miss commonly available directories like /opt so it is always better to check in advance.

One final check is to look at /etc/oratab.  The command dbstart (in the script ‘oracle’) is meant to be used during boot time and it will check if the database instance is allowed to be started at boot up. In the /etc/oratab file there may be ‘N’ at the row for the ORCL instance. It needs to be changed to ‘Y’ to allow starting that instance during boot time. Dbstart will start all instances in the oratab with the ‘Y’ set.

#!/bin/bash
#
# Run level script to start Oracle 11g services on RedHat Enterprise Linux (RHAS 4)
# --------------------------------------------------------------------
# chkconfig: 345 91 18
# description: Oracle 11g server

if [ -f /etc/init.d/functions ]; then
    . /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ]; then
    . /etc/rc.d/init.d/functions
else
    exit 0
fi

OLD_PATH=$PATH
export ORACLE_SID=orcl
export ORACLE_UNQNAME=$ORACLE_SID
export ORAENV_ASK="NO"
export PATH=/usr/local/bin:$PATH
source /usr/local/bin/oraenv >/dev/null
export PATH=$OLD_PATH

OUSER="oracle"
OPATH=$ORACLE_HOME
SRVNM="Oracle 11g DB server"
LOCKD=/var/lock/subsys
LOCKF=$LOCKD/oracle

case "$1" in

        start)
          echo -n "$SRVNM:"
          if [ -d $LOCKD ]; then
            touch $LOCKF
          fi
          su - $OUSER -c "$OPATH/bin/dbstart $OPATH"
          [ $? -eq 0 ] && success || failure
          ;;

        stop)
          echo -n  "$SRVNM:"
          su - $OUSER -c "$OPATH/bin/dbshut $OPATH"
          [ $? -eq 0 ] && success || failure
          if [ -e $LOCKF ]; then
            rm -f $LOCKF
          fi
          ;;

        restart)
          $0 stop
          $0 start
          ;;

        status)
          echo -n "$SRVNM "
          if [ -e $LOCKF ]; then
              echo "is running..."
          else
              echo "is stopped"
          fi
          ;;

        *)
          echo $"Usage: $0 {start|stop|restart|status}"
          exit 1
esac
exit 0


When everything is ready (you have checked the parameters and copied the oracle script to /etc/init.d and given it access and execute permissions), you can start the database (service oracle start)  and shut it down with (service oracle stop). 

One more thing is starting of db console that you may find useful. The following scripts do it. You can also make these scripts into a service if you like in the similar manner as above.

#cat startDBConsole.sh
#!/bin/bash
ORAENV_ASK=NO
ORACLE_SID=orcl
source oraenv
emctl start dbconsole
emctl status dbconsole

# cat stopDBConsole.sh
#!/bin/bash
ORAENV_ASK=NO
ORACLE_SID=orcl
source oraenv
emctl stop dbconsole
emctl status dbconsole
#


What is not ideal in this solution is that only the root can start and stop the service.

What is still missing is a piece of code to automatically start the SOA Suite when the machine boots up or to shut it down when the machine is closed.  That code would be a little bit harder to develop as there are several stages. First you start weblogic server, which also starts the AdminServer. Only after that is up, you should start other parts like the bam_server1 etc.  Knowing when the WLS is fully up is the hard bit here. You can achieve this either by having the script use netstat and when netstat reports that there is a service listening to the port (normally 7001) then you known WLS has started and you can proceed to the next phase. Another approach is to use WLST (weblogic scripting tool). My understanding is that it will block until the server is started, but I’ve not personally used WLST so far.

In my test setup I am however perfectly fine starting and stopping services manually so this will have to wait for another day.

Ei kommentteja:

Lähetä kommentti