Automatic DB Startup: The Linux Part (OEL 6 and 7)

This is part 2 of the automatic startup article. In the previous part, we talked about the basic building blocks for the automatic Oracle database and listener startup. We talked about the orastart and orashut scripts and the /etc/oratab that control which instances are automatically started.

In this part, we will put everything together and see how to configure Linux to use the scripts for automatic start. I will demonstrate two version of Linux here. I used Oracle Enterprise Linux 6 and 7 – which are similar to RedHat Enterprise Linux 6 and 7 (but free). These startup procedures are similar to most of the other distributions including CentOS and Ubuntu.

Linux startup crush course

Most *NIX based systems based on System V-style initiation (with the exception of systemd-based which we will talk about later). When booting the kernel or user decide which runlevel should be used and that executes only the scripts based in the /etc/rc?.d directory. There are runlevels for halt (shutdown) and reboot too.

# Default runlevel in Fedora core/generic systems. The runlevels used are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)

In the /etc/rc?.d we can find “files” starting with S?? and K??. The S scripts are scripts that will run on startup, and the numbers which will indicate the order the scripts will be run (lower is earlier, 99 is the last that will run). The K scripts will run on shutdown.

If we look more closely at the /etc/rc?.d/ directory we will see that the scripts aren’t actually scripts – these are soft links (symlinks) to scripts in the central init script directory – /etc/init.d.

Oracle Enterprise Linux 6

In OEL 6 (and even before that), the best way to setup the automatic startup is using the service mechanism. The service mechanism is an automation for the runinit method. In this method, we create a basic script (I usually go with dbora) that can accept two parameters: “start” for starting, and “stop” for stopping the service.

In that script, we also setup the information for the runlevel in which we want the script to run. In this example, we will run the script on level 3, 4, and 5. We will be the last script to run (99) on startup, and one of the first to run on shutdown (10).

# chkconfig: 345 99 10

Our full script will now look like this:

#!/bin/sh
# chkconfig: 345 99 10
# description: Oracle auto start-stop script.
#
# Set ORA_OWNER to the user id of the owner of the 
# Oracle database software.

ORA_HOME= /u01/app/oracle/product/11.2.0/dbhome_11204
ORA_OWNER=oracle

case "$1" in
    'start')
        # Start the Oracle databases:
        # The following command assumes that the oracle login 
        # will not prompt the user for any values
        # Remove "&" if you don't want startup as a background process.  	
        su $ORA_OWNER -c    "$ORA_HOME/bin/dbstart $ORA_HOME" &

        touch /var/lock/subsys/dbora
        ;;
    'stop')
        # Stop the Oracle databases:
        # The following command assumes that the oracle login 
        # will not prompt the user for any values
        su $ORA_OWNER -c "$ORA_HOME/bin/dbshut $ORA_HOME"
        rm -f /var/lock/subsys/dbora
        ;;
esac

 

Please note that the initialization runs from root so we need to change our user to the Oracle owner in order to start the database under the proper owner. Make sure root can use the su command to change to the database owner without any prompts.

Once we place our script and place the script in /etc/init.d, we need to give permissions for the script to be used:

[[email protected] ~]# chmod 750 /etc/init.d/dbora 

Everything is ready – we can now use the chkconfig command to put everything in place. This will create soft likes for S and K scripts in the right runlevel directories:

[[email protected] ~]# chkconfig --add dbora
[[email protected] ~]# ls /etc/rc3.d/*db*
/etc/rc3.d/S99dbora
 [[email protected] ~]# ls /etc/rc0.d/*db*
/etc/rc0.d/K10dbora
[[email protected] ~]# ls /etc/rc6.d/*db*
/etc/rc6.d/K10dbora

Now we can test the script to see if everything is working as expected:

[[email protected] ~]# service dbora start
[[email protected] ~]# Processing Database instance "orcl": log file /u01/app/oracle/product/11.2.0/dbhome_11204/startup.log
[[email protected] ~]# service dbora stop
Processing Database instance "orcl": log file /u01/app/oracle/product/11.2.0/dbhome_11204/shutdown.log 

Oracle Enterprise Linux 7

Fedora 15 has introduced a change in the initialization of Linux servers. Instead of using the old sysvinit (we already talked about), with a new systemd service management. Since RHEL 7 and OEL 7 are based off Fedora 19, the switch from sysvinit to systemd is now part of these distributions.

With this new method, systemctl command is used to stop, start, restart and check the status of a specified service:

[[email protected] ~]# systemctl status sshd
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2016-03-13 10:25:02 IST; 5min ago
     Docs: man:sshd(8)
           man:sshd_config(5)
 Main PID: 1377 (sshd)
   CGroup: /system.slice/sshd.service
           └─1377 /usr/sbin/sshd -D

Mar 13 10:25:02 lnx7-oracle-1 systemd[1]: Started OpenSSH server daemon.
Mar 13 10:25:02 lnx7-oracle-1 systemd[1]: Starting OpenSSH server daemon...
Mar 13 10:25:02 lnx7-oracle-1 sshd[1377]: Server listening on 0.0.0.0 port 22.
Mar 13 10:25:02 lnx7-oracle-1 sshd[1377]: Server listening on :: port 22.
Mar 13 10:26:32 lnx7-oracle-1 sshd[2932]: Accepted password for root from 192.168.56.1 port 53536 ssh2
Mar 13 10:26:47 lnx7-oracle-1 sshd[2936]: Accepted password for root from 192.168.56.1 port 53538 ssh2

We can also get a list of services and their statuses:

# # All loaded and active services.
# systemctl list-units --type service

# # All loaded services
# systemctl list-units --type service --all

# # All available services
# systemctl list-unit-files --type service 

Important: Even though there is a new method of doing things, some of the old commands (chkconfig, service) will sometime work for backwards compatibility. I suggest learning the new commands and use them – they are easy and even have intellisense (complete words on tab).

Configuring Oracle automatic startup on OEL 7

Now, we understand the basics of systemd  and systemctl, lets configure two services – a one for the database listener and one for the database startup.

First, we’ll create an environment file – we will use it in our services:

[[email protected] sysconfig]# vi /etc/sysconfig/env.oracledb
[[email protected] sysconfig]# cat /etc/sysconfig/env.oracledb
# define environment variables
ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=/u01/app/oracle/product/12.1.0/dbhome_12102
ORACLE_SID=orcl

Now, we create a service for the listener (we don’t have to do it since the dbstart will start it anyway, but it’s nice to see and control them separately):

[[email protected] system]# vi /usr/lib/systemd/system/oracle_network.service
[[email protected] system]# cat /usr/lib/systemd/system/oracle_network.service
[Unit]
Description=Oracle listener
After=network.target

[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/env.oracledb
ExecStart=/u01/app/oracle/product/12.1.0/dbhome_12102/bin/lsnrctl start
ExecStop=/u01/app/oracle/product/12.1.0/dbhome_12102/bin/lsnrctl stop
User=oracle

[Install]
WantedBy=multi-user.target

Now we can set up the database startup, which will be dependent of the listener service start:

[[email protected] system]# vi /usr/lib/systemd/system/oracledb.service
[[email protected] system]# cat /usr/lib/systemd/system/oracledb.service
[Unit]
Description=Oracle databases service
After=network.target oracle_network.service

[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/env.oracledb
ExecStart=/u01/app/oracle/product/12.1.0/dbhome_12102/bin/dbstart /u01/app/oracle/product/12.1.0/dbhome_12102
ExecStop=/u01/app/oracle/product/12.1.0/dbhome_12102/bin/dbshut /u01/app/oracle/product/12.1.0/dbhome_12102
User=oracle

[Install]
WantedBy=multi-user.target

Now that we configured everything, we reload the services configuration into the memory:

[[email protected] system]# systemctl daemon-reload
[[email protected] system]# systemctl list-unit-files --type service|grep oracle
oracle_network.service                      disabled
oracledb.service                            disabled

We can enable the services:

[[email protected] system]# systemctl enable oracle_network.service oracledb.service
Created symlink from /etc/systemd/system/multi-user.target.wants/oracle_network.service to /usr/lib/systemd/system/oracle_network.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/oracledb.service to /usr/lib/systemd/system/oracledb.service.

Start the services:

[[email protected] system]# systemctl start oracle_network.service 
[[email protected] system]# systemctl start oracledb

And check status:

[[email protected] system]# systemctl status oracledb
● oracledb.service - Oracle databases service
   Loaded: loaded (/usr/lib/systemd/system/oracledb.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2016-03-13 11:12:42 IST; 41s ago
  Process: 6876 ExecStop=/u01/app/oracle/product/12.1.0/dbhome_12102/bin/dbshut /u01/app/oracle/product/12.1.0/dbhome_12102 (code=exited, status=0/SUCCESS)
  Process: 7465 ExecStart=/u01/app/oracle/product/12.1.0/dbhome_12102/bin/dbstart /u01/app/oracle/product/12.1.0/dbhome_12102 (code=exited, status=0/SUCCESS)
 Main PID: 5758 (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/oracledb.service
           ├─7608 ora_pmon_orcl
           ├─7610 ora_psp0_orcl
           ├─7612 ora_vktm_orcl
           ├─7616 ora_gen0_orcl
           ├─7618 ora_mman_orcl
           ├─7622 ora_diag_orcl
           ├─7624 ora_dbrm_orcl
           ├─7626 ora_vkrm_orcl
           ├─7628 ora_dia0_orcl
           ├─7630 ora_dbw0_orcl
           ├─7632 ora_lgwr_orcl
           ├─7634 ora_ckpt_orcl
           ├─7636 ora_smon_orcl
           ├─7638 ora_reco_orcl
           ├─7640 ora_lreg_orcl
           ├─7642 ora_pxmn_orcl
           ├─7644 ora_mmon_orcl
           ├─7646 ora_mmnl_orcl
           ├─7648 ora_d000_orcl
           ├─7650 ora_s000_orcl
           ├─7662 ora_tmon_orcl
           ├─7664 ora_tt00_orcl
           ├─7666 ora_smco_orcl
           ├─7668 ora_w000_orcl
           ├─7670 ora_w001_orcl
           ├─7672 ora_aqpc_orcl
           ├─7676 ora_p000_orcl
           ├─7678 ora_p001_orcl
           ├─7680 ora_p002_orcl
           ├─7682 ora_p003_orcl
           ├─7684 ora_cjq0_orcl
           ├─7922 ora_p004_orcl
           ├─7924 ora_p005_orcl
           ├─7926 ora_p006_orcl
           ├─7928 ora_p007_orcl
           ├─7932 ora_qm02_orcl
           ├─7934 ora_qm03_orcl
           ├─7936 ora_q002_orcl
           └─7938 ora_q003_orcl

Mar 13 11:12:32 lnx7-oracle-1 systemd[1]: Starting Oracle databases service...
Mar 13 11:12:33 lnx7-oracle-1 dbstart[7465]: Processing Database instance "orcl": log file /u01/app/oracle/product/12.1.0/dbhome_12102/startup.log
Mar 13 11:12:42 lnx7-oracle-1 systemd[1]: Started Oracle databases service.

Oracle 12c with PDB setup

One thing we might want to consider is that when using Oracle 12c (12.1.0.2 and later) and CDB/PDB setup, our scripts will only start the CDB container. In order to have all the PDB start as well, we will need to set their state (start them up, for example) and run the save state command:

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 SINGLE                         MOUNTED
SQL>
SQL> alter pluggable database single open;

Pluggable database altered.

SQL> alter pluggable database single save state;

Pluggable database altered.

SQL>  show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 SINGLE                         READ WRITE NO
SQL> 

Summary

In this article, we learned how to configure Linux OS to automatically start our Oracle database. I used OEL 6 and 7, because these are the operating systems I see the most (CentOS that uses the same methods).

I didn’t cover the automatic startup of standby nodes of dataguard, or the startup of a RAC environment – maybe in another time.

If you have any questions (or corrections) – feel free to post them in the comment section down below.

5 replies
  1. Hans Brenner
    Hans Brenner says:

    Many thanks for this article.
    It works perfectly.
    This is the right method to start oracle 12c.

    Reply
  2. Gustavo
    Gustavo says:

    Hi, on RH7 this works fine for startup, but on reboot database is not stopping normally..is crashing…no message for shutdown in alert log file of the database…This scripts works for you on RH7?. The Database Alert log file show shutdown commands on reboot?.

    Reply
    • Zohar Elkayam
      Zohar Elkayam says:

      it should show a standard shutdown command in the alert log. try stopping the service manually and check the alert log to see if it actually runs the shutdown script.

      Reply

Trackbacks & Pingbacks

  1. […] this article I will describe the building blocks for automatic startup, and in my next post I will show the Linux commands needed to put everything […]

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply