首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 11g on RHEL 5 自動啟動/關閉完美配置:解決 dbshut 不生效的核心機制

     編輯:Oracle 資料庫相關知識

問題背景

網路上流傳的配置教程多為抄襲,導致「開機啟動正常,關機不關閉資料庫」的普遍現象。根因在於忽略 Linux 服務管理機制:/var/lock/subsys/ 下的鎖檔案決定服務是否被視為「運行中」,關機腳本僅停止有鎖檔的服務。

完整配置步驟

步驟 1:啟用 oratab 自動啟動標記

# vi /etc/oratab
# 修改實例行尾部 N -> Y
orcl=/u01/app/oracle/product/11.2.0/dbhome_1:Y

步驟 2:修正 dbstart/dbshut 環境變數

# su - oracle
$ cd $ORACLE_HOME/bin
$ cp dbstart dbstart.bak && cp dbshut dbshut.bak

# 修改 dbstart:找到 ORACLE_HOME_LISTNER=$1 改為
ORACLE_HOME_LISTNER=$ORACLE_HOME

# 修改 dbshut:同理修改
ORACLE_HOME_LISTNER=$ORACLE_HOME

原因:安裝時腳本不知道具體 ORACLE_HOME,執行時會報「未指定」錯誤。10g+ 已整合監聽器啟停,無需單獨配置。

步驟 3:建立系統服務腳本(關鍵:鎖檔管理)

# vi /etc/init.d/oracle11
#!/bin/bash
# chkconfig: 2345 99 10
# description: Oracle 11g Auto Start/Stop Service

export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/dbhome_1
export ORACLE_SID=orcl
export PATH=$PATH:$ORACLE_HOME/bin

case "$1" in
start)
    echo "`date` -----startup oracle-----" >> /var/log/oracle11.log
    su oracle -c "$ORACLE_HOME/bin/dbstart"
    touch /var/lock/subsys/oracle11   # 【核心】建立鎖檔,標記服務已啟動
    echo "`date` -----startup successful-----" >> /var/log/oracle11.log
    ;;
stop)
    echo "`date` -----shutdown oracle-----" >> /var/log/oracle11.log
    su oracle -c "$ORACLE_HOME/bin/dbshut"
    rm -f /var/lock/subsys/oracle11   # 【核心】移除鎖檔,標記服務已停止
    echo "`date` -----shutdown successful-----" >> /var/log/oracle11.log
    ;;
*)
    echo "Usage: $0 {start|stop}"
    exit 1
    ;;
esac
exit 0

步驟 4:註冊服務並設定開機自啟

chown oracle:oinstall /etc/init.d/oracle11
chmod 755 /etc/init.d/oracle11
chkconfig --add oracle11
chkconfig oracle11 on

# 驗證
chkconfig --list oracle11
# 輸出應包含 2:on 3:on 4:on 5:on

原理解析:為什麼這樣做有效?

  • Linux 關機流程(/etc/rc.d/rc0.d/K*)遍歷 /var/lock/subsys/,僅對存在鎖檔的服務發送 stop 參數。
  • 無鎖檔 → 系統認為服務未啟動 → 不執行停止腳本 → 資料庫進程被 SIGKILL 強制終止 → 可能導致實例恢復時間延長甚至數據不一致。
  • touch/rm -f /var/lock/subsys/oracle11 是連接 Oracle 生命週期與 Linux 服務管理的橋樑。

手動建立符號連結(不使用 chkconfig 時)

ln -s /etc/init.d/oracle11 /etc/rc.d/rc2.d/S99oracle11
ln -s /etc/init.d/oracle11 /etc/rc.d/rc3.d/S99oracle11
ln -s /etc/init.d/oracle11 /etc/rc.d/rc4.d/S99oracle11
ln -s /etc/init.d/oracle11 /etc/rc.d/rc5.d/S99oracle11
ln -s /etc/init.d/oracle11 /etc/rc.d/rc0.d/K10oracle11
ln -s /etc/init.d/oracle11 /etc/rc.d/rc1.d/K10oracle11
ln -s /etc/init.d/oracle11 /etc/rc.d/rc6.d/K10oracle11

S99 = 啟動優先級 99(晚啟動,依賴網路/存儲);K10 = 關閉優先級 10(早關閉,釋放資源)。

驗證測試

# 手動測試啟動
/etc/init.d/oracle11 start
tail -f /var/log/oracle11.log

# 手動測試關閉
/etc/init.d/oracle11 stop
tail -f /var/log/oracle11.log

# 檢查鎖檔
ls -l /var/lock/subsys/oracle11

常見坑點

  • 腳本首行必須 #!/bin/bash,且 # chkconfig: 註解不可省略。
  • su oracle -c "command" 雙引號不可少,否則變數不展開。
  • ORACLE_SID 需與 oratab 一致,多實例需建立多服務腳本(oracle11_sid1, oracle11_sid2...)。
  • RHEL 6/7+ 使用 systemd,需改寫 .service Unit 檔案,本文方案適用 RHEL 5/6 SysVinit。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved