Linux Shell經典執行個體解析–Oracle啟動指令碼(下)

來源:互聯網
上載者:User

      經過2個多月的努力,該系列博文到這裡已經即將結束,希望該系列的文章能夠給諸位今後的工作帶來些許協助,也希望能有機會與大家在技術上多多交流,互相取長補短,同時也敬請大家能夠繼續關注我在後面給出的關於其他技術主題的系列博文。最後在這裡感謝諸位網友的支援。
      言歸正傳,該篇部落格將承接上一篇部落格,進入oracle啟動指令碼的主體邏輯部分。

#1. /etc/oratab指令碼的格式如下:
#    MyOrcl1:/opt/oracle/product/OraHome:Y
#    MyOrcl2:/opt/oracle/product/OraHome:N
#該檔案的開頭處有很多的注釋說明,都是以#開頭,這些注釋需要在後面的處理中被忽略。在有用部分中,每行表示一個oracle執行個體,在同一行中,包含3個欄位,他們之間用#冒號分隔,第一個欄位為oracle的sid,第二個欄位為oracle執行個體的主目錄,最後一個欄位表示本次啟動是否拉起該執行個體,如果為Y則拉起,N則忽略。
#2. cat以管道的形式,將每行的都輸出給while迴圈,作為其輸入並賦值給LINE變數,如果到了$ORATAB檔案的末尾,while迴圈將退出。
cat $ORATAB | while read LINE; do
    #3. 如果當前行以#開頭後面跟隨任一字元,則為注釋說明,直接忽略即可。
    #4. 如果合法的資料行,用awk命令進行切分,並提取第一個域欄位,即oracle的sid值,賦值給變數ORACLE_SID。如果該變數為空白,則直接忽略,continue命令將回到迴圈的開頭處。
    case $LINE in
        \#*)  ;;
        *)
        ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
        if [ "$ORACLE_SID" = '*' ] ; then
            ORACLE_SID=""
            continue
        fi
        #5. 這裡提取$LINE變數的最後一個欄位,其中NF表示awk的輸入行的欄位數量,在本例中NF的值為3,$LINE的第三個域為狀態欄位,只有當該值為Y時才拉起該sid。
        if [ "`echo $LINE | awk -F: '{print $NF}' -`" = "Y" ] ; then
            #6. 通過cut命令截取ORACLE_SID的第一個字元,如果其值為加號(+),則視其為asm instance。
            #7. 這裡的cut命令可以替換為${ORACLE_SID:0:1},0表示從變數$ORACLE_SID的第一個字元開始,取1個字元。
            if [ `echo $ORACLE_SID | cut -b 1` = '+' ]; then
                INST="ASM instance"
                ORACLE_HOME=`echo $LINE | awk -F: '{print $2}' -`
                export ORACLE_HOME
                LOG=$ORACLE_HOME/startup.log
                #8. 通過touch命令建立一個記錄檔,同時賦予讀許可權。
                touch $LOG
                chmod a+r $LOG
                echo "Processing $INST \"$ORACLE_SID\": log file $ORACLE_HOME/startup.log"
                #9. 調用啟動asm執行個體的函數,並將標準輸出重新導向到剛剛建立的記錄檔,同時也將標準錯誤輸出也重新導向到該檔案。
                startasminst >> $LOG 2>&1
            fi
        fi
        ;;
    esac
done

#10. 如果執行之上的操作失敗,則直接退出指令碼,退出值為2。
if [ "$?" != "0" ] ; then
    exit 2
fi
#11. 該部分將重新遍曆/etc/oratab檔案,並啟動資料庫執行個體。該段邏輯中的shell技巧和上面的邏輯基本相同,這裡僅給出差異部分。
cat $ORATAB | while read LINE; do
    case $LINE in
        \#*) ;;
        *)
        ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
        if [ "$ORACLE_SID" = '*' ] ; then
            ORACLE_SID=""
            continue
        fi
        # Proceed only if last field is 'Y'.
        if [ "`echo $LINE | awk -F: '{print $NF}' -`" = "Y" ] ; then
            #12. 這裡和上面不同是,是判斷ORACLE_SID的第一個字元不為加號(+),這表示該執行個體為正常的資料庫執行個體。
            if [ `echo $ORACLE_SID | cut -b 1` != '+' ]; then
                INST="Database instance"
                ORACLE_HOME=`echo $LINE | awk -F: '{print $2}' -`
                export ORACLE_HOME
                LOG=$ORACLE_HOME/startup.log
                touch $LOG
                chmod a+r $LOG
                echo "Processing $INST \"$ORACLE_SID\": log file $ORACLE_HOME/startup.log"
                startinst >> $LOG 2>&1
            fi
        fi
        ;;
    esac
done

#13. 該段代碼邏輯的shell應用技巧和之前幾段的基本雷同,這裡我只是給出技巧上的差異部分。
cat $ORATAB | while read LINE;do
    case $LINE in
        \#*) ;;
        *)
        ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
        if [ "$ORACLE_SID" = '*' ] ; then
            ORACLE_SID=""
            continue
        fi
        if [ "`echo $LINE | awk -F: '{print $NF}' -`" = "W" ] ; then
            W_ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
            cat $ORATAB | while read LINE; do
                case $LINE in
                    \#*) ;;
                    *)
                    ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
                    if [ "$ORACLE_SID" = '*' ] ; then
                        ORACLE_SID=""
                        continue
                    fi
                    if [ `echo $ORACLE_SID | cut -b 1` = '+' ]; then
                        INST="ASM instance"
                        ORACLE_HOME=`echo $LINE | awk -F: '{print $2}' -`
                        if [ -x $ORACLE_HOME/bin/srvctl ] ; then
                            COUNT=0
                            NODE=`olsnodes -l`
                            #14. 執行下面的命令,並將其結果用grep命令過濾,只保留包含$ORACLE_SID is running的行,這裡$ORACLE_SID將完成變數替換。
                            RNODE=`srvctl status asm -n $NODE | grep "$ORACLE_SID is running"`
                            RC=$?
                            #15. 如果執行失敗,將繼續執行。
                            while [ "$RC" != "0" ]; do
                                #16. COUNT=$((COUNT+1))是另外一種進行數值型變數計算的表示方式。
                                COUNT=$((COUNT+1))
                                #17. -eq表示等於$COUNT等於5。
                                if [ $COUNT -eq 5 ] ; then
                                    $LOGMSG "Error: Timed out waiting on CRS to start ASM instance $ORACLE_SID"
                                    exit $COUNT
                                fi
                                $LOGMSG "Waiting for Oracle CRS service to start ASM instance $ORACLE_SID"
                                $LOGMSG "Wait $COUNT."
                                sleep 60
                                RNODE=`srvctl status asm -n $NODE | grep "$ORACLE_SID is running"`
                                RC=$?
                            done
                        else
                            $LOGMSG "Error: \"${W_ORACLE_SID}\" has dependency on ASM instance \"${ORACLE_SID}\""
                            $LOGMSG "Error: Need $ORACLE_HOME/bin/srvctl to check this dependency"
                        fi
                    fi
                    ;;
                esac
            done # innner while
        fi
        ;;
    esac
done # outer while

#18. 在該段代碼邏輯中,主要是用於處理/etc/oratab檔案中最後一個欄位的值為W的情況,它表示所有的asm執行個體均已啟動完畢,進入等待狀態,此時將只能啟動資料庫執行個體。從Shell的應用技巧視角看,該段邏輯和之前的shell技巧沒有太多差別,這裡就不再一一給出注釋說明了。
cat $ORATAB | while read LINE; do
    case $LINE in
        \#*) ;;
        *)
        ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
        if [ "$ORACLE_SID" = '*' ] ; then
            ORACLE_SID=""
            continue
        fi
        if [ "`echo $LINE | awk -F: '{print $NF}' -`" = "W" ] ; then
            INST="Database instance"
            if [ `echo $ORACLE_SID | cut -b 1` = '+' ]; then
                $LOGMSG "Error: ${INST} \"${ORACLE_SID}\" NOT started"
                $LOGMSG "Error: incorrect usage: 'W' not allowed for ASM instances"
                continue
            fi
            ORACLE_HOME=`echo $LINE | awk -F: '{print $2}' -`
            export ORACLE_HOME
            LOG=$ORACLE_HOME/startup.log
            touch $LOG
            chmod a+r $LOG
            echo "Processing $INST \"$ORACLE_SID\": log file $ORACLE_HOME/startup.log"
            startinst >> $LOG 2>&1
        fi
        ;;
    esac
done
      最後需要說明的是,有興趣的讀者可以繼續自行研究$ORACLE_HOME/bin目錄下的另外一個Shell指令碼(dbshut),該指令碼主要用於關閉Oracle資料庫伺服器,其代碼結構和Shell技巧與該指令碼(dbstart)極為相似。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.