Oracle叢集技術 | 叢集的自啟動系列(一)

沃趣科技發表於2019-01-07

當Oracle叢集安裝部署完成後,叢集會處於一個啟動的狀態,預設情況下,當伺服器重啟之後叢集也會被自動啟動,那麼,Oracle叢集是如何來實現自啟動的呢?

我們先看如下部分:

Oracle 10G: 

cat /etc/inittab
h1:35:respawn:/etc/init.d/init.evmd run >/dev/null 2>&1 </dev/null
h2:35:respawn:/etc/init.d/init.cssd fatal >/dev/null 2>&1 </dev/null
h3:35:respawn:/etc/init.d/init.crsd run >/dev/null 2>&1 </dev/null

Oracle 11G:

cat /etc/inittab
h1:35:respawn:/etc/init.d/init.ohasd run >/dev/null 2>&1 </dev/null

在Oracle10g版本中,系統啟動時由init程式根據/etc/inittab配置檔案來派生出叢集的高可用守護程式,在Oracle 11g中,init僅派生出init.ohasd,然後由init.ohasd啟動ohasd.bin實現叢集的自啟動。

另外,由於RedHat Linux 6.x棄用了inittab檔案,目前配置init.ohasd程式的檔案由/etc/inittab變為/etc/init/oracle-ohasd.conf。

[root@rac1 init]# cat /etc/rc.d/init.d/oracle-ohasd.conf 
 # Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. 
 #
 # Oracle OHASD startup
 start on runlevel [35]
 stop  on runlevel [!35]
 respawn
 exec /etc/init.d/init.ohasd run >/dev/null 2>&1 </dev/null
 [root@rac1 ]#

在Red Hat 7.*以上版本中,init.ohasd指令碼配置又一次發生變化,init.ohasd以service形式配置在/etc/systemd/system下。

Red Hat Linux 7.*
#cat /etc/systemd/system/oracle-ohasd.service
# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
#
# Oracle OHASD startup
[Unit]
Description=Oracle High Availability Services
After=syslog.target network-online.target remote-fs.target
[Service]
ExecStart=/etc/init.d/init.ohasd run >/dev/null 2>&1 </dev/null
ExecStop=/etc/init.d/init.ohasd stop >/dev/null 2>&1 </dev/null
TimeoutStopSec=60min
Type=simple
Restart=always
# Do not kill any processes except init.ohasd after ExecStop, unless the
# stop command times out.
KillMode=process
SendSIGKILL=yes
[Install]
WantedBy=multi-user.target graphical.target

大部分資料在介紹叢集自啟動時,均是按照以上方式來介紹的,但這種描述方式並不準確,實際上Oracle叢集自啟動是由init.ohasd和ohasd兩個指令碼相互配合來完成叢集的自啟動,這兩個指令碼均位於/etc/rc.d/init.d目錄下。

如下:

Red Hat Linux 7.*
#cat /etc/systemd/system/oracle-ohasd.service
# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
#
# Oracle OHASD startup
[root@rac1 init.d]# pwd
/etc/rc.d/init.d
[root@rac1 init.d]# ls -ltr *ohasd*
-rwxr-xr-x. 1 root root 6835 Aug 29 09:57 ohasd
-rwxr-xr-x. 1 root root 9076 Aug 29 10:40 init.ohasd
[root@rac1 init.d]#

init.ohasd

透過對init.ohasd指令碼的分析,該指令碼主要有兩個作用,第一個作用為建立名為npohasd的命名管道檔案,並在init.ohasd執行過程中始終read該命名管道檔案,以此作為標記,該作用為init.ohasd最重要的作用,因為當命名管道檔案未被read標記時叢集無法啟動),第二個作用,init.ohasd作為ohasd.bin的高可用守護程式而存在,當ohasd.bin程式異常終止時,由init.ohasd再次啟動ohasd.bin,來實現ohasd.bin程式的高可用,而ohasd.bin程式是叢集的高可用程式,當叢集資源意外終止時由ohasd.bin所屬的agent程式負責重新啟動相應資源,同時ohasd.bin也是負責整個叢集啟動的程式。(叢集並非由init.ohasd指令碼啟動,init.ohasd做叢集啟動時的前期準備工作)

ohasd

ohasd指令碼是在系統啟動時,真正啟動叢集的指令碼,叢集安裝完畢後,ohasd指令碼被軟連線到/etc/rc.d下面的相關啟動級別目錄中(/etc/rc.d/rc[0-6].d/*),系統啟動時,執行不同級別的指令碼程式,啟動級別為3時/etc/rc.d/rc3.d/S96ohasd被執行,此時ohasd指令碼呼叫$ORACLE_HOME/bin/crsctl指令碼來啟動叢集。

ohasd指令碼在執行時會判斷/var/tmp/.oracle目錄是否存在,如果/var/tmp/.oracle不存在,將會建立/var/tmp/.oracle目錄,並將.oracle目錄許可權置為01777 ,/var/tmp/.oracle目錄中存放著叢集啟動及正常執行時所產生的套接字以及命名管道檔案。

如下為/etc/rc.d/rc[0-6]/*中ohasd指令碼的軟連線情況:

[root@rac1 ~]# ls -ltr /etc/rc.d/rc[0-6].d/*ohasd*
lrwxrwxrwx. 1 root root 17 Feb 21  2018 /etc/rc.d/rc5.d/S96ohasd -> /etc/init.d/ohasd
lrwxrwxrwx. 1 root root 17 Feb 21  2018 /etc/rc.d/rc6.d/K15ohasd -> /etc/init.d/ohasd
lrwxrwxrwx. 1 root root 17 Feb 21  2018 /etc/rc.d/rc4.d/K15ohasd -> /etc/init.d/ohasd
lrwxrwxrwx. 1 root root 17 Feb 21  2018 /etc/rc.d/rc2.d/K15ohasd -> /etc/init.d/ohasd
lrwxrwxrwx. 1 root root 17 Feb 21  2018 /etc/rc.d/rc1.d/K15ohasd -> /etc/init.d/ohasd
lrwxrwxrwx. 1 root root 17 Feb 21  2018 /etc/rc.d/rc0.d/K15ohasd -> /etc/init.d/ohasd
lrwxrwxrwx. 1 root root 17 Mar 26 01:40 /etc/rc.d/rc3.d/S96ohasd -> /etc/init.d/ohasd
[root@rac1 ~]#

init.ohasd/ohasd何時被呼叫

1)開機BIOS自檢,且根據BIOS中配置的啟動裝置讀取MBR並載入Bootloader程式。

2)載入並執行載入程式GRUB。

3)GRUB根據配置載入核心映像。

4)核心啟動(根檔案系統掛載,核心執行/sbin/init)。

5)Init依據/etc/inittab中配置執行級別進行系統的初始化(初始化指令碼: /etc/rc.d/rc.sysinit)。/etc/init/*內配置檔案生效是在該步進行

6)根據不同的執行級別,啟動相應服務 (服務程式指令碼位於/etc/rc.d/rc[0-6].d中)。


Linux系統在啟動時大概可以分為6步,init.ohasd和ohash是在第5步和第6步來被呼叫啟動叢集。

當系統啟動到第5步的時候,init程式會掃描/etc/init/下面的所有配置檔案,關於Oracle叢集,init程式會根據/etc/init/oracle-ohasd.conf中的內容派生init.ohasd程式(由init.ohasd發出read命名管道檔案npohasd的命令)。

系統啟動到第6步時,根據系統的不同啟動級別,/etc/rc.d/rc[0-6].d/*中的指令碼程式被執行,此時ohasd呼叫$ORACLE_HOME/bin/crsctl指令碼,由crsctl負責叢集的啟動。


| 禁用叢集自啟動

ohasdstr

在/etc/oracle/scls_scr/[SID]/root/目錄中有一個配置檔案ohasdstr,當ohasd指令碼被呼叫時會讀取ohasdstr檔案,根據ohasdstr檔案中記錄的enable/disable來判斷叢集是否隨系統啟動而自啟動。

如何避免叢集隨系統啟動而自啟動?正確的做法是透過"crsctl disable/enable crs"的方式來控制叢集是否隨系統啟動而自啟動,"crsctl disable/enable crs"實際上就是修改配置檔案ohasdstr。

如下:

#cat /etc/oracle/scls_scr/qdata1/root/ohasdstr 
enable
[root@qdata1 /root]
#crsctl disable crs
CRS-4621: Oracle High Availability Services autostart is disabled.
[root@qdata1 /root]
#cat /etc/oracle/scls_scr/qdata1/root/ohasdstr 
disable
[root@qdata1 /root]
#crsctl enable crs
CRS-4622: Oracle High Availability Services autostart is enabled.
[root@qdata1 /root]
#cat /etc/oracle/scls_scr/qdata1/root/ohasdstr 
enable
[root@qdata1 /root]
#

當然,我們也可以直接手工修改ohasdstr檔案。

另外,也有些資料在介紹禁止叢集自啟動時,採用註釋掉oracle-ohasd.conf中派生init.ohasd部分,此時系統啟動時init程式無法派生init.ohash指令碼,但這種方式為取巧方式,直接將init.ohasd的執行進行禁止,這種方式並不建議,如果init.ohasd指令碼未啟動,npohasd命名管道檔案不會被建立,並且不會被read,當需要使用’crsctl start crs’手工啟動叢集時,由於命名管道為被read,此時叢集無法啟動,這種情況下我們可以手工執行"exec /etc/init.d/init.ohasd run",然後再使用’crsctl start crs’命令來啟動叢集。


順便說一下,在/etc/oracle/scls_scr/[SID]/root/目錄中還有一個ohasdrun配置檔案,該檔案是控制init.ohasd是否實現ohasd.bin高可用的配置檔案,上面我們說過init.ohasd指令碼其中一個作用是實現ohasd.bin程式的高可用,init.ohasd就是透過ohasdrun這個配置檔案來判斷當ohasd.bin程式異常終止時,是否啟動ohasd.bin程式。


init.ohasd/ohasd丟失後如何處理

init.ohasd/ohasd兩個指令碼是在叢集安裝配置時執行root.sh過程中,由$GRID_HOME/crs/init/目錄中複製而來,當指令碼init.ohasd/ohasd丟失後可以從$GRID_HOME/crs/init中重新複製,並將/etc/init.d中的init.ohasd/ohasd許可權置為755即可。


| 作者簡介

楊禹航·沃趣科技高階資料庫技術專家

熟悉Oracle資料庫內部機制,豐富的資料庫及RAC叢集層故障診斷、效能調優、OWI、資料庫備份恢復及遷移經驗。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28218939/viewspace-2374641/,如需轉載,請註明出處,否則將追究法律責任。

相關文章