تعریف سرویس در systemd برای استارت خودکار دیتابیس

با توجه فراگیر شدن systemd در توزیع های مختلف لینوکس، نیاز است تا با نحوه ایجاد و مدیریت سرویس در این محیط آشنا باشیم به همین منظور، در این متن قصد داریم مختصرا به این موضوع بپردازیم و در نهایت، سرویسی را برای استارت خودکار دیتابیس اوراکل تعریف کنیم.

برای ایجاد سرویس با systemd، باید فایلی را در یکی از مسیرهای زیر ایجاد کرد:

/usr/lib/systemd/system

/usr/lib/systemd/user

/etc/systemd/system

/etc/systemd/user

برای نمونه، تعدادی از فایلهایی که در مسیر etc/systemd/system/ قرار دارند را در قسمت زیر مشاهده می کنید:

[root@ol7 system]# ls -l

drwxr-xr-x. 2 root root   31 Jul 23  2018 basic.target.wants

drwxr-xr-x. 2 root root   31 Jul 24  2018 bluetooth.target.wants

drwxr-xr-x. 2 root root   87 Jul 23  2018 default.target.wants

drwxr-xr-x. 2 root root   32 Jul 23  2018 getty.target.wants

drwxr-xr-x. 2 root root 4096 Aug  1  2018 graphical.target.wants

drwxr-xr-x. 2 root root 4096 Feb  4 04:56 multi-user.target.wants

-rw-r–r–  1 root root  586 Aug  1  2018 oracle-ohasd.service

برای ایجاد فایل در هر کدام از این مسیرها، بدیهی است که باید با ساختار این نوع از فایلها آشنا باشیم. فایلهای که در این مسیر تعریف می شوند، می توانند شامل سه قسمت Unit، Service و Install باشند که به عنوان مثال، فایل مربوط به سرویس oracleasm.service، چنین ساختاری دارد:

[root@ol7 system]#  less oracleasm.service

[Unit]

Description=Load oracleasm Modules

[Service]

ExecStart=/usr/sbin/service  oracleasm start_sysctl

ExecStop=/usr/sbin/service   oracleasm stop_sysctl

ExecReload=/usr/sbin/service oracleasm restart_sysctl

[Install]

WantedBy=multi-user.target

در ادامه متن، با بعضی از پارامترهای مهم هر کدام از این قسمتها(Unit – Service – Install)، آشنا خواهیم شد.

 [Unit]

پارامتر Description: از طریق این پارامتر، توضیحاتی را در مورد سرویس مورد نظر تعیین می کنیم.

مثال:

Description=Start Oracle Database

Before: در زمان boot شدن سیستم و تا قبل از اجرای سرویس جاری، چه سرویسهایی امکان اجرا ندارند؟

مثال:

Before =auditd.service systemd-user-sessions.service time-sync.target

After: سرویس مورد نظر؛ بعد از اجرای چه سرویسی می تواند استارت شود؟

مثال:

After=auditd.service systemd-user-sessions.service time-sync.target

Conflicts: این پارامتر، لیست سرویسهایی که امکان اجرای همزمان را با سرویس جاری ندارند، مشخص خواهد کرد.

نکته: لیست سرویسها را می توان با دستور زیر مشاهده کرد:

[root@ol7 system]# systemctl list-units|less

  local-fs.target                   loaded active active    Local File Systems

  multi-user.target              loaded active active    Multi-User System

  network-online.target    loaded active active    Network is Online

  network.target                 loaded active active    Network

  nfs-client.target        loaded active active    NFS client services

  smb.service               loaded active running   Samba SMB Daemon

  sshd.service              loaded active running   OpenSSH server daemon

  sysstat.service          loaded active exited    Resets System Activity Logs

[Service]

در این قسمت تعیین می کنیم که با start، stop و restart شدن سرویس، درعمل چه اتفاقی باید رخ دهد به بیانی بهتر، چه اسکریپت و یا دستوری باید اجرا شود؟ در ادامه، تعدادی از پارامترهای این [Service] را مورد بررسی قرار داده ایم:

ExecStart: با استارت شدن سرویس، چه دستور و یا اسکریپتی اجرا شود؟

مثالهای زیر را ببینید:

ExecStart=/usr/sbin/service  oracleasm start_sysctl

ExecStart=/usr/sbin/firewalld –nofork –nopid $FIREWALLD_ARGS

ExecStart=/sbin/multipathd

ExecStart=/usr/bin/touch /root/mynewwwwwwfile

ExecStop: سرویسی که توسط پارامتر ExecStart استارت شده، با چه دستور و یا اسکریپتی متوقف خواهد شد؟

مثال:

ExecStop=/usr/sbin/service   oracleasm stop_sysctl

ExecReload: با restart شدن سرویس، چه دستور و یا اسکریپتی اجرا می شود؟

مثال:

ExecReload=/usr/sbin/service oracleasm restart_sysctl

 [Install]

زمانی که از دستور systemctl enable و systemctl disable استفاده می کنیم، به قسمت [Install] رجوع خواهد شد. پارامتر مهمی که در این بخش تعریف می شود، WantedBy می باشد.

WantedBy: با boot شدن مجدد سرور/ماشین، سرویس در چه runlevelای اجرا شود؟

توجه! برای استارت خودکار سرویس بعد از boot شدن سرور، علاوه بر پارامتر WantedBy، باید دستور systemctl enable را هم اجرا کرده باشیم.

نکته: لیست runlevelها را در قسمت زیر می بینید:

 [root@ol7 ~]# cd /usr/lib/systemd/system/

 [root@ol7 system]# ls -l runlevel*.target

lrwxrwxrwx. 1 root root 15 Jul 23  2018 runlevel0.target -> poweroff.target

lrwxrwxrwx. 1 root root 13 Jul 23  2018 runlevel1.target -> rescue.target

lrwxrwxrwx. 1 root root 17 Jul 23  2018 runlevel2.target -> multi-user.target

lrwxrwxrwx. 1 root root 17 Jul 23  2018 runlevel3.target -> multi-user.target

lrwxrwxrwx. 1 root root 17 Jul 23  2018 runlevel4.target -> multi-user.target

lrwxrwxrwx. 1 root root 16 Jul 23  2018 runlevel5.target -> graphical.target

lrwxrwxrwx. 1 root root 13 Jul 23  2018 runlevel6.target -> reboot.target

در ادامه با دو مثال، شیوه ایجاد سرویس را مورد بررسی قرار خواهیم داد.

مثال 1: در قسمت زیر، سرویسی تعریف شده است که استارت کردن آن سبب ایجاد فایلی در مسیر home/oracle/ خواهد شد:

[root@ol7 ~]# vi /root/myscript.sh

/usr/bin/touch /home/oracle/m_`date +%y%m%d_%H%M%S`

[root@ol7 ~]# chmod +x /root/myscript.sh

[root@ol7 ~]# vi /etc/systemd/system/test1.service

[Service]

ExecStart=/bin/bash /root/myscript.sh

 [root@ol7 ~]# systemctl daemon-reload

نکته: با هر بار تغییر در متن یک سرویس، باید دستور systemctl daemon-reload را هم اجرا کرد.

بعد از تعریف سرویس test1.service، این سرویس را استارت می کنیم:

[root@ol7 ~]#systemctl start test1.service

با اجرای این دستور، فایلی در مسیر home/oracle/ ایجاد خواهد شد:

 [root@ol7 ~]# ls -l /home/oracle/m_*

-rw-r–r– 1 root root 0 Feb  4 09:05 /home/oracle/m_190204_090501

مثال 2: در این مثال می خواهیم با هر بار reboot شدن سرور، سرویس test1.service هم به صورت خودکار اجرا شود.

برای این کار می توانیم متن سرویس test1.service را به شکل زیر اصلاح کنیم:

[root@ol7 ~]# vi /etc/system/system/test1.service

[Service]

ExecStart=/bin/bash /root/myscript.sh

 [Install]

WantedBy=multi-user.target

بعد از تغییر فایل test1.service، کافیست تا دستور systemctl enable را برای این سرویس اجرا کنیم:

 [root@ol7 ~]# systemctl enable test1.service

Created symlink from /etc/systemd/system/multi-user.target.wants/test1.service to /etc/systemd/system/test1.service.

برای تست درستی تعریف سرویس، ماشین را reboot می کنیم:

 [root@ol7 ~]# date

Mon Feb  4 09:06:38 EST 2019

[root@ol7 ~]# reboot

PolicyKit daemon disconnected from the bus.

We are no longer a registered authentication agent.

با استارت مجدد ماشین، خواهیم دید که فایل دیگری هم در مسیرhome/oracle/ ایجاد شده است:

[root@ol7 ~]# ls -l /home/oracle/m_*

-rw-r–r– 1 root root 0 Feb  4 09:05 /home/oracle/m_190204_090501

-rw-r–r– 1 root root 0 Feb  4 09:07 /home/oracle/m_190204_090701

تعریف سرویس برای استارت خودکار دیتابیس

در ادامه قصد داریم با کمک سه اسکریپت ساده زیر، سرویسی را برای stop، start و restart کردن دیتابیس تعریف کنیم:

 [root@hkm2 ~]$ vi start_database

#!/bin/sh

su – oracle <<EOF

sqlplus “/as sysdba”

startup ;

EOF

 [root@ol7 ~]$ vi restart_database

#!/bin/sh

su – oracle <<EOF

sqlplus “/as sysdba”

startup force;

EOF

 [root@ol7 ~]$ vi stop_database

#!/bin/sh

su – oracle <<EOF

sqlplus “/as sysdba”

shut abort

EOF

با دستور زیر، سرویسی با نام oracledb.service ایجاد خواهد شد که از سه اسکریپت بالا برای مدیریت(stop-start-restart) دیتابیس اوراکل استفاده خواهد کرد:

[root@ol7 ~]# vi /etc/systemd/system/oracledb.service

[Unit]

Description=Start Oracle Database

After=network.target

[Service]

RemainAfterExit=yes

ExecStart=/home/oracle/start_database

ExecStop=/home/oracle/stop_database

ExecReload=/home/oracle/restart_database

[Install]

WantedBy=multi-user.target

برای استارت خودکار سرویس oracledb.service، کافیست دستور زیر را اجرا کنیم:

[root@ol7 ~]# systemctl enable oracledb.service

Created symlink from /etc/systemd/system/multi-user.target.wants/oracledb.service to /etc/systemd/system/oracledb.service.

سرویس systemd در زمان استارت کردن سرویس oracledb.service، از تنظیمات فایل limit.conf صرف نظر خواهد کرد، به این جهت، برای اعمال تنظیماتی چون nproc،nofile و stack باید پارامترهای زیر را به متن سرویس oracledb.service اضافه کرد:

LimitMEMLOCK=infinity

LimitNOFILE=65535

LimitSTACK=10240

همچنین در صورت تنظیم Huge Page در سرور/ماشین، باید پارامتر معادل memlock را هم به این اسکریپت اضافه کرد:

LimitMEMLOCK=infinity

با این تغییرات، متن نهایی سرویس oracledb.service، به شکل زیر تغییر خواهد کرد:

[root@ol7 ~]# vi /etc/systemd/system/oracledb.service

[Unit]

Description=Start Oracle Database

After=network.target

[Service]

LimitMEMLOCK=infinity

LimitNOFILE=65535

LimitNPROC=1638400

LimitSTACK=10240

RemainAfterExit=yes

ExecStart=/home/oracle/start_database

ExecStop=/home/oracle/stop_database

ExecReload=/home/oracle/restart_database

[Install]

WantedBy=multi-user.target

با تنظیم این سرویس، با دستورات زیر هم می توان دیتابیس را stop و start کرد:

[root@ol7 ~]# systemctl stop oracledb.service

[root@ol7 ~]# systemctl start oracledb.service

[root@ol7 ~]# systemctl restart oracledb.service

ارتباط با نویسنده مطلب:vahidusefzadeh@ کانال تخصصی اوراکل و لینوکس: OracleDB@ www.linkedin.com/in/vahid-usefzadeh-918bb289

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد.