If we are using chkconfig / init.d for the automate Oracle database shutdown, it will be failed in RHEL7

check the $ORACLE_HOME/shutdown.log, we can find that there is an error for database shutdown by service.

SQL*Plus: Release 12.1.0.2.0 Production on Wed Feb 6 10:29:15 2019

Copyright (c) 1982, 2014, Oracle.  All rights reserved.

SQL> Connected to an idle instance.
SQL> ERROR:
ORA-01034: ORACLE not available
ORA-27101: shared memory realm does not exist
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3651
Additional information: -1916159033
Process ID: 0
Session ID: 0 Serial number: 0


SQL> Disconnected
Database instance "PPRD3" shut down.

Also check the Alert log, we can see there was no action of database shutdown.

Wed Feb 06 04:15:03 2019
Thread 1 cannot allocate new log, sequence 4438
Private strand flush not complete
  Current log# 8 seq# 4437 mem# 0: /t03/app/oracle/oradata/PPRD3/redo_AIR_8a.rdo
  Current log# 8 seq# 4437 mem# 1: /t03/app/oracle/oradata/PPRD3/redo_AIR_8b.rdo
Wed Feb 06 04:15:06 2019
Thread 1 advanced to log sequence 4438 (LGWR switch)
  Current log# 9 seq# 4438 mem# 0: /t03/app/oracle/oradata/PPRD3/redo_AIR_9a.rdo
  Current log# 9 seq# 4438 mem# 1: /t03/app/oracle/oradata/PPRD3/redo_AIR_9b.rdo
Wed Feb 06 10:32:59 2019
Starting ORACLE instance (normal) (OS id: 2266)
Wed Feb 06 10:32:59 2019
CLI notifier numLatches:29 maxDescs:2393
Wed Feb 06 10:32:59 2019
**********************************************************************
Wed Feb 06 10:32:59 2019
Dump of system resources acquired for SHARED GLOBAL AREA (SGA)

Wed Feb 06 10:32:59 2019
 Per process system memlock (soft) limit = 35G
Wed Feb 06 10:32:59 2019
 Expected per process system memlock (soft) limit to lock
 SHARED GLOBAL AREA (SGA) into memory: 35G

That means the database is not shutdown gracefully during the machine reboot.

We were using chkconfig to configure service, and in RHEL7, it is converted to systemd internally.

[root@zoro ~]# cat /run/systemd/generator.late/dbora.service
# Automatically generated by systemd-sysv-generator

[Unit]
Documentation=man:systemd-sysv-generator(8)
SourcePath=/etc/rc.d/init.d/dbora
Description=LSB: Starts the databases on system reboot
Before=runlevel3.target
Before=runlevel4.target
Before=runlevel5.target
Before=shutdown.target
Before=gcstartup.service
Before=lockgcstartup.service
After=network-online.target
Conflicts=shutdown.target

[Service]
Type=forking
Restart=no
TimeoutSec=5min
IgnoreSIGPIPE=no
KillMode=process
GuessMainPID=no
RemainAfterExit=yes
ExecStart=/etc/rc.d/init.d/dbora start
ExecStop=/etc/rc.d/init.d/dbora stop

And in /etc/rc.d/init.d/dbora. it is use “su - oracle -c” to shutdown database.

    su - $ORA_OWNER -c "$ORA_HOME/bin/dbshut" 

Follow this article:

Automatic Stop of Database (dbshut) not working in OL 7 with systemd (Doc ID 2229679.1)

This is because in RHEL7, init.d is no longer used for the service startup, and it actually be replaced by systemctl. The service which we use chkconfig to create will convert to systemd internally. And dbora script uses su to oracle owner and systemd is not able to keep track of that process.

We can follow

Automate Startup/Shutdown Of Oracle Database 12.2.0.1 On RHEL 7 (Doc ID 2417429.1)

to set up

First, remove chkconfig

# chkconfig --del dbora
# systemctl stop dbora.service
# systemctl disable dbora.service
# systemctl daemon-reload
# systemctl reset-failed
# systemctl -l|grep dbora  
  <== no entry here

Next, create systemd service

# mkdir /l01/app/oracle/scripts
# touch /l01/app/oracle/scripts/start_all.sh

#!/bin/bash
export ORACLE_SID=12CR1
export ORAENV_ASK=NO
. oraenv
export ORAENV_ASK=YES
lsnrctl start TEST_LISTENER
lsnrctl start EXTPROC_LISTENER
dbstart

# touch /l01/app/oracle/scripts/stop_all.sh

#!/bin/bash
export ORACLE_SID=12CR1
export ORAENV_ASK=NO
. oraenv
export ORAENV_ASK=YES
lsnrctl stop TEST_LISTENER
lsnrctl stop EXTPROC_LISTENER
dbshut

# chown -R oracle.dba /l01/app/oracle/scripts
# chmod u+x /l01/app/oracle/scripts/*.sh

# use oracle for testing
$ /l01/app/oracle/scripts/start_all.sh
$ /l01/app/oracle/scripts/stop_all.sh

# touch /lib/systemd/system/dbora.service
[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
LimitNPROC=16384
LimitCORE=0

#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.
RemainAfterExit=yes
User=oracle
Group=dba
ExecStart=/l01/app/oracle/scripts/start_all.sh
ExecStop=/l01/app/oracle/scripts/stop_all.sh

[Install]
WantedBy=multi-user.target

before testing, record the setting of limit of SMON process

$ cat /proc/110456/limits 
Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            33554432             unlimited            bytes     
Max core file size        0                    0                    bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             16384                16384                processes 
Max open files            65536                65536                files     
Max locked memory         37316722688          37316722688          bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       2015514              2015514              signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us        
# systemctl daemon-reload
# systemctl start dbora.service
# systemctl enable dbora.service

after testing

  1. check $ORACLE_HOME/startup.log
  2. check $ORACLE_HOME/shutdown.log
  3. check alert log
  4. compare the ulimit setting.