Recently I created a new virtual machine for the Oracle Database Admin, Install and Upgrade class that I teach at ACC. Previously I’d used Oracle Virtual Box on my local machine and then uploaded the image to Oracle Cloud and used Ravello to give each of my students their own server.
It was actually pretty straight forward:
- Upload the latest Oracle Linux (7.6) ISO that I got from eDelivery.oracle.com.
- Create a new blank machine with the following:
- 4 CPUs
- 24 GB of RAM
- 200 GB of disk
- Mout the uploaded ISO as a CD-ROM
- An elastic IP
- Services as follows:
- SSH (port 22)
- HTTPS (port 443)
- VNC (port 5901)
- HTTPS (port 7803 for Cloud Control)
- Start the image, configuring Oracle Linux 7 with the following:
- Server with GUI for software
- A static IP address (I used 10.0.0.15, but you could use anything).
- IP filtering so my ACC students could access the servers while they are in the labs at ACC and I could access the machines from home
- Partition the disk into a 16 GB swap partition, a 10 GB /home partition and then the rest of the disk as the root partition.
- When it came time to reboot the server, remove the CD-ROM image and update the configuration before rebooting so the image boots up using the disk.
- Install Oracle 12c and create an emrep repository database for OEM 13.3.
- Install OEM 13.3.
- Install Oracle 11g and create a database that will be upgraded during the course.
At this point everything was great, but since I teach 3-hour classes on Mondays and Wednesdays and shut the servers down between classes, my databases and OEM need to come up cleanly. Oracle has documentation on creating services to automatically start up databases on Linux/Unix, but it uses the old System V method for starting services (which, to be fair does still work on Linux 7). Since this was a Linux 7 server, I wanted to use the new systemd method. Tim’s rather fantastic site had the basic framework, but where he used scripts that he called from the service, I wanted to use dbstart and dbshut so that we could maintain startup and shutdown from a single file (/etc/oratab) rather than modifying a script.
I created the following file:
[root@dba ~]# vim /usr/lib/systemd/system/oracle-database.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 Type=oneshot RemainAfterExit=yes User=oracle Group=oinstall Restart=no ExecStart=/usr/bin/echo 'Starting Oracle Databases with Y in /etc/oratab' ExecStart=/u01/app/oracle/product/12.2.0/dbhome_1/bin/dbstart /u01/app/oracle/product/12.2.0/dbhome_1 ExecStart=/usr/bin/echo 'dbstart has completed' ExecStop=/usr/bin/echo 'Stopping Oracle Databases' ExecStop=/u01/app/oracle/product/12.2.0/dbhome_1/bin/dbshut /u01/app/oracle/product/12.2.0/dbhome_1 ExecStop=/usr/bin/echo 'dbshut has completed' [Install] WantedBy=multi-user.target
I then enabled the service using the following:
[root@dba ~]# systemctl daemon-reload [root@dba ~]# systemctl enable oracle-database
While the above worked great to start the database (tested with a reboot of the server), it didn’t address another issue. Unlike the database, Oracle Enterprise Manager comes with ‘out of the box’ scripts to start and stop OEM. They are the old style System V scripts that run out of /etc/init.d, and it didn’t really seem worth going through the trouble of converting them to the new systemd format. Unfortunately, the OEM scripts always assume that the database is already up and running. If your repository database is running on the same server as your OMS (which isn’t really that big of a deal if your hardware can handle it) that can be fixed by modifying the OEM startup script and adding in a ‘check to make sure your database is up and running before you start OEM’ section. The content in bold below was added to the out of the box OEM script after the initial comments in the file.
[root@dba ~]# vim /etc/init.d/gcstartup
# 2019-03-05 Rich Soule # OEM should only startup if the emrep database is already up and running # on the local machine so the below was added to make sure that happens. #################### Begin Rich Soule Added Lines ####################### if [ "$1" = "start" ] then counter=0 while [ $counter -le 24 ] do ((counter++)) if ! /usr/bin/ps -e | /usr/bin/grep -q ora_pmon_emrep then echo 'OEM is waiting on Oracle database to start' sleep 10 else break fi done if [ $counter -ge 24 ] then echo 'Oracle database did not start in time, exiting OEM startup' exit 1 fi echo 'Oracle database started, waiting 20 more seconds for database to open' sleep 20 echo 'OMS will now attempt to start as per remainer of the /etc/init.d/gcstartup script' fi #################### End Rich Soule Added Lines ########################
The above first checks to make sure that gcstartup was called with the start argument. If so then we’ll check if there is an ora_pmon_emrep process running (emrep is the name of my OEM repository database). If it isn’t running, we’ll wait 10 seconds and check again, but only for 240 seconds total. Once that process is found, we break out of our while do loop. If we did hit our 240-second limit, then we exit out of the gcstartup script totally, otherwise, we wait 20 seconds for the database to open and then continue along with the rest of the gcstartup script.
So far this has been working like a charm.
Note that you could do the same type of thing with OEM and instead have the script make a connection to a remote server every 10 seconds to make sure that the remote OEM repository was up before attempting to start OEM.
Happy Linux-ing and Oracle-ing!
March 23rd, 2020 at 5:10 am
Thanks for a great idea 🙂
I’ve modified your script to take advantage of systemd to check if the DB is started, by using systemctl is-active rather than checking for a specific process
if [ “$1” = “start” ]
while [ $counter -le 24 ]
systemctl is-active –quiet oracle-database && break
echo ‘OEM is waiting on Oracle database to start’
[ $counter -ge 24 ] && echo ‘Oracle database did not start in time, exiting OEM startup’ && exit 1
echo ‘Oracle database started, waiting 20 more seconds for database to open’
echo ‘OMS will now attempt to start as per remainer of the /etc/init.d/gcstartup script’
March 23rd, 2020 at 8:06 am
Does the is-active return true only when all the databases are started up? During the class we have up to three running at the same time (dbupgrd – 11g DB to upgrade, emrep for the EM repository, and orcl as the student created database to manage).
April 24th, 2020 at 9:07 am
This is a great idea for controlling the start up phase. I am wondering how did control for the shutdown phase? Was there an enforcement to make sure that OMS had been brought down before shutdown repository database?
April 26th, 2020 at 10:00 pm
I’ve just depended on the normal shutdown process and have never had issues. Not that we bounce the servers two times a week, every week for 12 weeks (far more than you ever would in real life).