找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 6389|回复: 0

Linux Shell经典实例解析--Oracle启动脚本(下)

[复制链接]
发表于 2012-4-23 13:56:13 | 显示全部楼层 |阅读模式
  1.       经过2个多月的努力,该系列博文到这里已经即将结束,希望该系列的文章能够给诸位今后的工作带来些许帮助,也希望能有机会与大家在技术上多多交流,互相取长补短,同时也敬请大家能够继续关注我在后面给出的关于其他技术主题的系列博文。最后在这里感谢诸位网友的支持。
  2.       言归正传,该篇博客将承接上一篇博客,进入oracle启动脚本的主体逻辑部分。
  3. #1. /etc/oratab脚本的格式如下:
  4. #    MyOrcl1:/opt/oracle/product/OraHome:Y
  5. #    MyOrcl2:/opt/oracle/product/OraHome:N
  6. #该文件的开头处有很多的注释说明,都是以#开头,这些注释需要在后面的处理中被忽略。在有用部分中,每行表示一个oracle实例,在同一行中,包含3个字段,他们之间用#冒号分隔,第一个字段为oracle的sid,第二个字段为oracle实例的主目录,最后一个字段表示本次启动是否拉起该实例,如果为Y则拉起,N则忽略。
  7. #2. cat以管道的形式,将每行的都输出给while循环,作为其输入并赋值给LINE变量,如果到了$ORATAB文件的末尾,while循环将退出。
  8. cat $ORATAB | while read LINE; do
  9.     #3. 如果当前行以#开头后面跟随任意字符,则为注释说明,直接忽略即可。
  10.     #4. 如果合法的数据行,用awk命令进行切分,并提取第一个域字段,即oracle的sid值,赋值给变量ORACLE_SID。如果该变量为空,则直接忽略,continue命令将回到循环的开头处。
  11.     case $LINE in
  12.         \#*)  ;;
  13.         *)
  14.         ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
  15.         if [ "$ORACLE_SID" = '*' ] ; then
  16.             ORACLE_SID=""
  17.             continue
  18.         fi
  19.         #5. 这里提取$LINE变量的最后一个字段,其中NF表示awk的输入行的字段数量,在本例中NF的值为3,$LINE的第三个域为状态字段,只有当该值为Y时才拉起该sid。
  20.         if [ "`echo $LINE | awk -F: '{print $NF}' -`" = "Y" ] ; then
  21.             #6. 通过cut命令截取ORACLE_SID的第一个字符,如果其值为加号(+),则视其为asm instance。
  22.             #7. 这里的cut命令可以替换为${ORACLE_SID:0:1},0表示从变量$ORACLE_SID的第一个字符开始,取1个字符。
  23.             if [ `echo $ORACLE_SID | cut -b 1` = '+' ]; then
  24.                 INST="ASM instance"
  25.                 ORACLE_HOME=`echo $LINE | awk -F: '{print $2}' -`
  26.                 export ORACLE_HOME
  27.                 LOG=$ORACLE_HOME/startup.log
  28.                 #8. 通过touch命令创建一个日志文件,同时赋予读权限。
  29.                 touch $LOG
  30.                 chmod a+r $LOG
  31.                 echo "Processing $INST "$ORACLE_SID": log file $ORACLE_HOME/startup.log"
  32.                 #9. 调用启动asm实例的函数,并将标准输出重定向到刚刚创建的日志文件,同时也将标准错误输出也重定向到该文件。
  33.                 startasminst >> $LOG 2>&1
  34.             fi
  35.         fi
  36.         ;;
  37.     esac
  38. done
  39. #10. 如果执行之上的操作失败,则直接退出脚本,退出值为2。
  40. if [ "$?" != "0" ] ; then
  41.     exit 2
  42. fi
  43. #11. 该部分将重新遍历/etc/oratab文件,并启动数据库实例。该段逻辑中的shell技巧和上面的逻辑基本相同,这里仅给出差异部分。
  44. cat $ORATAB | while read LINE; do
  45.     case $LINE in
  46.         \#*) ;;
  47.         *)
  48.         ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
  49.         if [ "$ORACLE_SID" = '*' ] ; then
  50.             ORACLE_SID=""
  51.             continue
  52.         fi
  53.         # Proceed only if last field is 'Y'.
  54.         if [ "`echo $LINE | awk -F: '{print $NF}' -`" = "Y" ] ; then
  55.             #12. 这里和上面不同是,是判断ORACLE_SID的第一个字符不为加号(+),这表示该实例为正常的数据库实例。
  56.             if [ `echo $ORACLE_SID | cut -b 1` != '+' ]; then
  57.                 INST="Database instance"
  58.                 ORACLE_HOME=`echo $LINE | awk -F: '{print $2}' -`
  59.                 export ORACLE_HOME
  60.                 LOG=$ORACLE_HOME/startup.log
  61.                 touch $LOG
  62.                 chmod a+r $LOG
  63.                 echo "Processing $INST "$ORACLE_SID": log file $ORACLE_HOME/startup.log"
  64.                 startinst >> $LOG 2>&1
  65.             fi
  66.         fi
  67.         ;;
  68.     esac
  69. done
  70. #13. 该段代码逻辑的shell应用技巧和之前几段的基本雷同,这里我只是给出技巧上的差异部分。
  71. cat $ORATAB | while read LINE;do
  72.     case $LINE in
  73.         \#*) ;;
  74.         *)
  75.         ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
  76.         if [ "$ORACLE_SID" = '*' ] ; then
  77.             ORACLE_SID=""
  78.             continue
  79.         fi
  80.         if [ "`echo $LINE | awk -F: '{print $NF}' -`" = "W" ] ; then
  81.             W_ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
  82.             cat $ORATAB | while read LINE; do
  83.                 case $LINE in
  84.                     \#*) ;;
  85.                     *)
  86.                     ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
  87.                     if [ "$ORACLE_SID" = '*' ] ; then
  88.                         ORACLE_SID=""
  89.                         continue
  90.                     fi
  91.                     if [ `echo $ORACLE_SID | cut -b 1` = '+' ]; then
  92.                         INST="ASM instance"
  93.                         ORACLE_HOME=`echo $LINE | awk -F: '{print $2}' -`
  94.                         if [ -x $ORACLE_HOME/bin/srvctl ] ; then
  95.                             COUNT=0
  96.                             NODE=`olsnodes -l`
  97.                             #14. 执行下面的命令,并将其结果用grep命令过滤,只保留包含$ORACLE_SID is running的行,这里$ORACLE_SID将完成变量替换。
  98.                             RNODE=`srvctl status asm -n $NODE | grep "$ORACLE_SID is running"`
  99.                             RC=$?
  100.                             #15. 如果执行失败,将继续执行。
  101.                             while [ "$RC" != "0" ]; do
  102.                                 #16. COUNT=$((COUNT+1))是另外一种进行数值型变量计算的表示方式。
  103.                                 COUNT=$((COUNT+1))
  104.                                 #17. -eq表示等于$COUNT等于5。
  105.                                 if [ $COUNT -eq 5 ] ; then
  106.                                     $LOGMSG "Error: Timed out waiting on CRS to start ASM instance $ORACLE_SID"
  107.                                     exit $COUNT
  108.                                 fi
  109.                                 $LOGMSG "Waiting for Oracle CRS service to start ASM instance $ORACLE_SID"
  110.                                 $LOGMSG "Wait $COUNT."
  111.                                 sleep 60
  112.                                 RNODE=`srvctl status asm -n $NODE | grep "$ORACLE_SID is running"`
  113.                                 RC=$?
  114.                             done
  115.                         else
  116.                             $LOGMSG "Error: "${W_ORACLE_SID}" has dependency on ASM instance "${ORACLE_SID}""
  117.                             $LOGMSG "Error: Need $ORACLE_HOME/bin/srvctl to check this dependency"
  118.                         fi
  119.                     fi
  120.                     ;;
  121.                 esac
  122.             done # innner while
  123.         fi
  124.         ;;
  125.     esac
  126. done # outer while
  127. #18. 在该段代码逻辑中,主要是用于处理/etc/oratab文件中最后一个字段的值为W的情况,它表示所有的asm实例均已启动完毕,进入等待状态,此时将只能启动数据库实例。从Shell的应用技巧视角看,该段逻辑和之前的shell技巧没有太多差别,这里就不再一一给出注释说明了。
  128. cat $ORATAB | while read LINE; do
  129.     case $LINE in
  130.         \#*) ;;
  131.         *)
  132.         ORACLE_SID=`echo $LINE | awk -F: '{print $1}' -`
  133.         if [ "$ORACLE_SID" = '*' ] ; then
  134.             ORACLE_SID=""
  135.             continue
  136.         fi
  137.         if [ "`echo $LINE | awk -F: '{print $NF}' -`" = "W" ] ; then
  138.             INST="Database instance"
  139.             if [ `echo $ORACLE_SID | cut -b 1` = '+' ]; then
  140.                 $LOGMSG "Error: ${INST} "${ORACLE_SID}" NOT started"
  141.                 $LOGMSG "Error: incorrect usage: 'W' not allowed for ASM instances"
  142.                 continue
  143.             fi
  144.             ORACLE_HOME=`echo $LINE | awk -F: '{print $2}' -`
  145.             export ORACLE_HOME
  146.             LOG=$ORACLE_HOME/startup.log
  147.             touch $LOG
  148.             chmod a+r $LOG
  149.             echo "Processing $INST "$ORACLE_SID": log file $ORACLE_HOME/startup.log"
  150.             startinst >> $LOG 2>&1
  151.         fi
  152.         ;;
  153.     esac
  154. done
  155.       最后需要说明的是,有兴趣的读者可以继续自行研究$ORACLE_HOME/bin目录下的另外一个Shell脚本(dbshut),该脚本主要用于关闭Oracle数据库服务器,其代码结构和Shell技巧与该脚本(dbstart)极为相似。
复制代码

目录:
Linux Shell高级技巧(一)
http://www.acejoy.com/thread-4326-1-1.html
一、将输入信息转换为大写字符后再进行条件判断
二、为调试信息设置输出级别
三、判断参数是否为数字
四、判断整数变量的奇偶性
五、将Shell命令赋值给指定变量,以保证脚本的移植性
六、获取当前时间距纪元时间(1970年1月1日)所经过的天数
Linux Shell高级技巧(二)
http://www.acejoy.com/thread-4327-1-1.html
七、非直接引用变量
八、在循环中使用管道的技巧
九、自链接脚本
十、Here文档的使用技巧
十一、获取进程的运行时长(单位: 分钟)
十二、模拟简单的top命令
Linux Shell高级技巧(三)
http://www.acejoy.com/thread-4328-1-1.html
十三、格式化输出指定用户的当前运行进程
十四、用脚本完成which命令的基本功能
十五、验证输入信息是否合法
十六、整数验证
十七、判断指定的年份是否为闰年
十八、将单列显示转换为多列显示
Linux Shell高级技巧(四)
http://www.acejoy.com/thread-4329-1-1.html
十九、将文件的输出格式化为指定的宽度
二十、监控指定目录下磁盘使用空间过大的用户
二十一、编写一个更具可读性的df命令输出脚本
二十二、编写一个用于添加新用户的脚本
二十三、kill指定用户或指定终端的用户进程
二十四、判断用户输入(是/否)的便捷方法
Linux Shell高级技巧(五)
http://www.acejoy.com/thread-4330-1-1.html
二十五、通过FTP下载指定的文件
二十六、文件锁定
二十七、用小文件覆盖整个磁盘
二十八、统计当前系统中不同运行状态的进程数量
二十九、浮点数验证
三十、统计英文文章中每个单词出现的频率

Linux Shell经典实例解析--Oracle启动脚本(上)
http://www.acejoy.com/thread-4331-1-1.html

Linux Shell经典实例解析--Oracle启动脚本(下)
http://www.acejoy.com/thread-4332-1-1.html


您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-4-23 16:49 , Processed in 0.013655 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表