监控Oracle数据库的常用shell脚本

本帖最后由 sniper 于 2012-5-10 20:13 编辑

一.脚本来监控Oracle数据库:
1.检查实例的可用性
2.检查监听器的可用性
3.检查alert日志文件中的错误信息
4.在存放log文件的地方满以前清空旧的log文件
5.分析table和index以获得更好的性能
6.检查表空间的使用情况
7.找出无效的对象
8.监控用户和事务

二.DBA需要的Unix基本知识
基本的UNIX命令,以下是一些常用的Unix命令:
ps--显示进程
grep--搜索文件中的某种文本模式
mailx--读取或者发送mail
cat--连接文件或者显示它们
cut--选择显示的列
awk--模式匹配语言
df--显示剩余的磁盘空间

以下是DBA如何使用这些命令的一些例子:

1. 显示服务器上的可用实例:
  1. $ ps –ef | grep smon
  2.   oracle 22086     1  0 02:32:24 ?        0:04 ora_smon_PPRD10
  3. oracle  5215 28972  0 08:10:19 pts/4    0:00 grep smon
复制代码
2. 显示服务器上的可用监听器:
  1. $ ps -ef | grep listener grep -v grep
复制代码
(grep命令应该加上-i参数,即grep -i listener,该参数的作用是忽略大小写,因为有些时候listener是大写的,这时就会看不到结果)
  1. $ ps –ef |grep -i listener
  2.   oracle  9655     1  0   Mar 12 ?        0:01 /data/app/oracle/9.2.0/bin/tnslsnr LISTENER -inherit
  3.   oracle 22610     1  0 02:45:02 ?        0:02 /data/app/oracle/10.2.0/bin/tnslsnr LISTENER -inherit
  4. oracle  5268 28972  0 08:13:02 pts/4    0:00 grep -i listener
复制代码
3. 查看Oracle存档目录的文件系统使用情况
  1. $ df -k | grep /data
  2. /dev/md/dsk/d50      104977675 88610542 15317357    86%    /data
复制代码
4. 统计alter.log文件中的行数:
  1. $ cat alert_PPRD10.log | wc -l
  2.    13124
  3. $ more alert_PPRD10.log | wc -l
  4.    13124
复制代码
5. 列出alert.log文件中的全部Oracle错误信息:
  1. $ grep ORA-* alert.log
  2. ORA-00600: internal error code, arguments: [kcrrrfswda.1], [], [], [], [], []
  3. ORA-00600: internal error code, arguments: [1881], [25860496], [25857716], []
复制代码
6. CRONTAB基本
一个crontab文件中包含有六个字段:
分钟 0-59
小时 0-23
月中的第几天 1-31
月份 1 - 12
星期几 0 - 6, with 0 = Sunday

7. Unix命令或者Shell脚本
要编辑一个crontab文件,输入: Crontab -e
要查看一个crontab文件,输入: Crontab -l
0 4 * * 5 /dba/admin/analyze_table.ksh
30 3 * * 3,6 /dba/admin/hotbackup.ksh /dev/null 2>&1
在上面的例子中,第一行显示了一个分析表的脚本在每个星期5的4:00am运行。第二行显示了一个执行热备份的脚本在每个周三和周六的3:00a.m.运行。

三.监控数据库的常用Shell脚本
以下提供的8个shell脚本覆盖了DBA每日监控工作的90%,你可能还需要修改UNIX的环境变量。

1. 检查Oracle实例的可用性
oratab文件中列出了服务器上的所有数据库
  1. $ cat /var/opt/oracle/oratab
  2. #

  3. # This file is used by ORACLE utilities.  It is created by root.sh
  4. # and updated by the Database Configuration Assistant when creating
  5. # a database.

  6. # A colon, ':', is used as the field terminator.  A new line terminates
  7. # the entry.  Lines beginning with a pound sign, '#', are comments.
  8. #
  9. # Entries are of the form:
  10. #   $ORACLE_SID:$ORACLE_HOME:<N|Y>:
  11. #
  12. # The first and second fields are the system identifier and home
  13. # directory of the database respectively.  The third filed indicates
  14. # to the dbstart utility that the database should , "Y", or should not,
  15. # "N", be brought up at system boot time.
  16. #
  17. # Multiple entries with the same $ORACLE_SID are not allowed.
  18. #
  19. #
  20. # *:/data/app/oracle/9.2.0:N
  21. TRNG:/data/app/oracle/9.2.0:Y
  22. *:/data/app/oracle/9.2.0:N
  23. PPRD:/data/app/oracle/10.2.0:Y
  24. PPRD10:/data/app/oracle/10.2.0:N
复制代码
以下的脚本检查oratab文件中列出的所有数据库,并且找出该数据库的状态(启动还是关闭)
  1. ###################################################################
  2. ## ckinstance.ksh ##
  3. ###################################################################
  4. ORATAB=/var/opt/oracle/oratab
  5. echo "`date` "
  6. echo "Oracle Database(s) Status `hostname` :/n"
  7. db=`egrep -i ":Y|:N" $ORATAB | cut -d":" -f1 | grep -v "/#" | grep -v "/*"`
  8. pslist="`ps -ef | grep pmon`"
  9. for i in $db ; do
  10. echo "$pslist" | grep "ora_pmon_$i" > /dev/null 2>$1
  11. if (( $? )); then
  12. echo "Oracle Instance - $i: Down"
  13. else
  14. echo "Oracle Instance - $i: Up"
  15. fi
  16. done
复制代码
使用以下的命令来确认该脚本是可以执行的:
  1. $ chmod 744 ckinstance.ksh
  2. $ ls -l ckinstance.ksh
  3. -rwxr--r-- 1 oracle dba 657 Mar 5 22:59 ckinstance.ksh
复制代码
以下是实例可用性的报表:
  1. $ sh ckinstance.ksh
  2. Wed May 13 12:51:20 PDT 2009
  3. Oracle Database(s) Status gambels :
  4. Oracle Instance - PPRD: Up
  5. Oracle Instance - PPRD10: Up
复制代码
2. 检查Oracle监听器的可用性
以下有一个类似的脚本检查Oracle监听器。假如监听器停了,该脚本将会重新启动监听器:
  1. #####################################################################
  2. ## cklsnr.sh ##
  3. #####################################################################
  4. #!/bin/ksh
  5. TNS_ADMIN=/var/opt/oracle; export TNS_ADMIN
  6. ORACLE_SID= PPRD10; export ORACLE_SID
  7. ORAENV_ASK=NO; export ORAENV_ASK
  8. PATH=$PATH:/bin:/usr/local/bin; export PATH
  9. . oraenv
  10. DBALIST="tianlesoftware@vip.qq.com,[email]tianlesoftware@hotmail.com[/email]";export DBALIST
  11. cd /var/opt/oracle
  12. rm -f lsnr.exist
  13. ps -ef | grep PPRD10 | grep -v grep > lsnr.exist
  14. if [ -s lsnr.exist ]
  15. then
  16. echo
  17. else
  18. echo "Alert" | mailx -s "Listener 'PPRD10' on `hostname` is down" $DBALIST
  19. lsnrctl start PPRD10
  20. fi
复制代码
3. 检查Alert日志(ORA-XXXXX)
  1. ####################################################################
  2. ## ckalertlog.sh ##
  3. ####################################################################
  4. #!/bin/ksh

  5. EDITOR=vi; export EDITOR
  6. ORACLE_SID=PPRD10; export ORACLE_SID
  7. ORACLE_BASE=/data/app/oracle; export ORACLE_BASE
  8. ORACLE_HOME=$ORACLE_BASE/10.2.0; export ORACLE_HOME
  9. LD_LIBRARY_PATH=$ORACLE_HOME/lib; export LD_LIBRARY_PATH
  10. TNS_ADMIN=/var/opt/oracle;export TNS_ADMIN
  11. NLS_LANG=american; export NLS_LANG
  12. NLS_DATE_FORMAT='Mon DD YYYY HH24:MI:SS'; export NLS_DATE_FORMAT
  13. ORATAB=/var/opt/oracle/oratab;export ORATAB
  14. PATH=$PATH:$ORACLE_HOME:$ORACLE_HOME/bin:/usr/ccs/bin:/bin:/usr/bin:/usr/sbin:/sbin:/usr/openwin/bin:/opt/bin:.; export PATH
  15. DBALIST="tianlesoftware@vip.qq.com,[email]tianlesoftware@hotmail.com[/email]";export DBALIST

  16. cd $ORACLE_BASE/admin/PPRD10/bdump
  17. if [ -f alert_PPRD10.log ]
  18. then
  19. mv alert_PPRD10.log alert_work.log
  20. touch alert_PPRD10.log
  21. cat alert_work.log >> alert_PPRD10.hist
  22. grep ORA- alert_work.log > alert.err
  23. fi
  24. if [ `cat alert.err | wc -l` -gt 0 ]
  25. then
  26. mailx -s " PPRD10  ORACLE  ALERT  ERRORS" $DBALIST < alert.err
  27. fi
  28. rm -f alert.err
  29. rm -f alert_work.log
复制代码
4. 清除旧的归档文件
以下的脚本将会在log文件达到90%容量的时候清空旧的归档文件:
  1. $ df -k | grep arch
  2. Filesystem kbytes used avail capacity Mounted on
  3. /dev/vx/dsk/proddg/archive 71123968 30210248 40594232 43% /u08/archive

  4. #######################################################################
  5. ## clean_arch.ksh ##
  6. #######################################################################
  7. #!/bin/ksh
  8. df -k | grep arch > dfk.result
  9. archive_filesystem=`awk -F" " '{ print $6 }' dfk.result`
  10. archive_capacity=`awk -F" " '{ print $5 }' dfk.result`

  11. if [ $archive_capacity > 90% ]
  12. then
  13. echo "Filesystem ${archive_filesystem} is ${archive_capacity} filled"
  14. # try one of the following option depend on your need
  15. find $archive_filesystem -type f -mtime +2 -exec rm -r {} ;
  16. tar
  17. rman
  18. fi
复制代码
5. 分析表和索引(以得到更好的性能)
以下我将展示假如传送参数到一个脚本中:
  1. ####################################################################
  2. ## analyze_table.sh ##
  3. ####################################################################
  4. #!/bin/ksh
  5. # input parameter: 1: passWord # 2: SID
  6. if (($#<1)) then echo "Please enter 'oracle' user password as the first parameter !" exit 0
  7. fi
  8. if (($#<2)) then echo "Please enter instance name as the second parameter!" exit 0
  9. fi
  10. 要传入参数以执行该脚本,输入:
  11. $ analyze_table.sh manager oradb1
  12. 脚本的第一部分产生了一个analyze.sql文件,里面包含了分析表用的语句。脚本的第二部分分析全部的表:
  13. #################################################################
  14. ## analyze_table.sh ##
  15. #################################################################
  16. sqlplus -s '/ as sysdba' <<EOF
  17. set heading off
  18. set feed off
  19. set pagesize 200
  20. set linesize 100
  21. spool analyze_table.sql
  22. select 'ANALYZE TABLE ' || owner || '.' || segment_name ||
  23. ' ESTIMATE STATISTICS SAMPLE 10 PERCENT;'
  24. from dba_segments
  25. where segment_type = 'TABLE'
  26. and owner not in ('SYS', 'SYSTEM');
  27. spool off
  28. exit
  29. EOF
  30. sqlplus -s '/ as sysdba' <<EOF
  31. @./analyze_table.sql
  32. exit
  33. EOF
复制代码
以下是analyze.sql的一个例子:
  1. $ cat analyze.sql
  2. ANALYZE TABLE HIRWIN.JANUSAGE_SUMMARY ESTIMATE STATISTICS SAMPLE 10 PERCENT;
  3. ANALYZE TABLE HIRWIN.JANUSER_PROFILE ESTIMATE STATISTICS SAMPLE 10 PERCENT;
  4. ANALYZE TABLE APPSSYS.HIST_SYSTEM_ACTIVITY ESTIMATE STATISTICS SAMPLE 10 PERCENT;
  5. ANALYZE TABLE HTOMEH.QUEST_IM_VERSION ESTIMATE STATISTICS SAMPLE 10 PERCENT;
  6. ANALYZE TABLE JSTENZEL.HIST_SYS_ACT_0615 ESTIMATE STATISTICS SAMPLE 10 PERCENT;
复制代码
6. 检查表空间的使用
以下的脚本检测表空间的使用。假如表空间只剩下10%,它将会发送一个警告email。
  1. #####################################################################
  2. ## ck_tbsp.sh ##
  3. #####################################################################
  4. #!/bin/ksh

  5. EDITOR=vi; export EDITOR
  6. ORACLE_SID=PPRD10; export ORACLE_SID
  7. ORACLE_BASE=/data/app/oracle; export ORACLE_BASE
  8. ORACLE_HOME=$ORACLE_BASE/10.2.0; export ORACLE_HOME
  9. LD_LIBRARY_PATH=$ORACLE_HOME/lib; export LD_LIBRARY_PATH
  10. TNS_ADMIN=/var/opt/oracle;export TNS_ADMIN
  11. NLS_LANG=american; export NLS_LANG
  12. NLS_DATE_FORMAT='Mon DD YYYY HH24:MI:SS'; export NLS_DATE_FORMAT
  13. ORATAB=/var/opt/oracle/oratab;export ORATAB
  14. PATH=$PATH:$ORACLE_HOME:$ORACLE_HOME/bin:/usr/ccs/bin:/bin:/usr/bin:/usr/sbin:/sbin:/usr/openwin/bin:/opt/bin:.; export PATH
  15. DBALIST="tianlesoftware@vip.qq.com,[email]tianlesoftware@hotmail.com[/email]";export DBALIST
复制代码
  1. sqlplus -s '/ as sysdba' <<EOF
  2. set feed off
  3. set linesize 100
  4. set pagesize 200
  5. column "USED (MB)" format a10
  6. column "FREE (MB)" format a10
  7. column "TOTAL (MB)" format a10
  8. column PER_FREE format a10
  9. spool tablespace.alert
  10. SELECT F.TABLESPACE_NAME,
  11. TO_CHAR ((T.TOTAL_SPACE - F.FREE_SPACE),'999,999') "USED (MB)",
  12. TO_CHAR (F.FREE_SPACE, '999,999') "FREE (MB)",
  13. TO_CHAR (T.TOTAL_SPACE, '999,999') "TOTAL (MB)",
  14. TO_CHAR ((ROUND ((F.FREE_SPACE/T.TOTAL_SPACE)*100)),'999')||' %' PER_FREE
  15. FROM (
  16. SELECT TABLESPACE_NAME,
  17. ROUND (SUM (BLOCKS*(SELECT VALUE/1024
  18. FROM V/$PARAMETER
  19. WHERE NAME = 'db_block_size')/1024)
  20. ) FREE_SPACE
  21. FROM DBA_FREE_SPACE
  22. GROUP BY TABLESPACE_NAME
  23. ) F,
  24. (
  25. SELECT TABLESPACE_NAME,
  26. ROUND (SUM (BYTES/1048576)) TOTAL_SPACE
  27. FROM DBA_DATA_FILES
  28. GROUP BY TABLESPACE_NAME
  29. ) T
  30. WHERE F.TABLESPACE_NAME = T.TABLESPACE_NAME
  31. AND (ROUND ((F.FREE_SPACE/T.TOTAL_SPACE)*100)) < 80;
  32. spool off
  33. exit
  34. EOF
  35. if [ `cat tablespace.alert|wc -l` -gt 0 ]
  36. then
  37. cat tablespace.alert > tablespace.tmp
  38. mailx -s "TABLESPACE  ALERT  for  PPRD10" $DBALIST < tablespace.tmp
  39. fi
复制代码
警告email输出的例子如下:
  1. TABLESPACE_NAME                USED (MB)  FREE (MB)  TOTAL (MB) PER_FREE                             
  2. ------------------------------ ---------- ---------- ---------- ----------                           
  3. SYSTEM                              519        401        920     44 %                              
  4. MILLDATA                            559        441      1,000     44 %                              
  5. SYSAUX                              331        609        940     65 %                              
  6. MILLREPORTS                         146        254        400     64 %
复制代码
7. 查找出无效的数据库对象
以下查找出无效的数据库对象:
  1. #####################################################################
  2. ##invalid_object_alert.sh
  3. #####################################################################
  4. #!/bin/ksh
  5. EDITOR=vi; export EDITOR
  6. ORACLE_SID=PPRD10; export ORACLE_SID
  7. ORACLE_BASE=/data/app/oracle; export ORACLE_BASE
  8. ORACLE_HOME=$ORACLE_BASE/10.2.0; export ORACLE_HOME
  9. LD_LIBRARY_PATH=$ORACLE_HOME/lib; export LD_LIBRARY_PATH
  10. TNS_ADMIN=/var/opt/oracle;export TNS_ADMIN
  11. NLS_LANG=american; export NLS_LANG
  12. NLS_DATE_FORMAT='Mon DD YYYY HH24:MI:SS'; export NLS_DATE_FORMAT
  13. ORATAB=/var/opt/oracle/oratab;export ORATAB
  14. PATH=$PATH:$ORACLE_HOME:$ORACLE_HOME/bin:/usr/ccs/bin:/bin:/usr/bin:/usr/sbin:/sbin:/usr/openwin/bin:/opt/bin:.; export PATH
  15. DBALIST="tianlesoftware@vip.qq.com,[email]tianlesoftware@hotmail.com[/email]";export DBALIST

  16. sqlplus -s '/ as sysdba' <<EOF
  17. set feed off
  18. set heading off
  19. column OWNER format a10
  20. column OBJECT_NAME format a35
  21. column OBJECT_TYPE format a10
  22. column STATUS format a10
  23. spool invalid_object.alert
  24. SELECT OWNER, OBJECT_NAME, OBJECT_TYPE, STATUS FROM DBA_OBJECTS WHERE STATUS = 'INVALID' ORDER BY OWNER, OBJECT_TYPE, OBJECT_NAME;
  25. spool off
  26. exit
  27. EOF
  28. if [ `cat invalid_object.alert | wc -l` -gt 0 ] then
  29. mailx -s "INVALID OBJECTS for PPRD10" $DBALIST < invalid_object.alert
  30. fi

  31. $ more invalid_object.alert

  32. PUBLIC     ALL_WM_LOCKED_TABLES                SYNONYM    INVALID
  33. PUBLIC     ALL_WM_VERSIONED_TABLES             SYNONYM    INVALID
  34. PUBLIC     DBA_WM_VERSIONED_TABLES             SYNONYM    INVALID
  35. PUBLIC     SDO_CART_TEXT                       SYNONYM    INVALID
  36. PUBLIC     SDO_GEOMETRY                        SYNONYM    INVALID
  37. PUBLIC     SDO_REGAGGR                         SYNONYM    INVALID
  38. PUBLIC     SDO_REGAGGRSET                      SYNONYM    INVALID
  39. PUBLIC     SDO_REGION                          SYNONYM    INVALID
  40. PUBLIC     SDO_REGIONSET                       SYNONYM    INVALID
  41. PUBLIC     USER_WM_LOCKED_TABLES               SYNONYM    INVALID
  42. PUBLIC     USER_WM_VERSIONED_TABLES            SYNONYM    INVALID
  43. PUBLIC     WM_COMPRESS_BATCH_SIZES             SYNONYM    INVALID
复制代码
8. 监视用户和事务(死锁等)
以下的脚本在死锁发生的时候发送一个警告e-mail:
  1. ###################################################################
  2. ## deadlock_alert.sh ##
  3. ###################################################################
  4. #!/bin/ksh

  5. EDITOR=vi; export EDITOR
  6. ORACLE_SID=PPRD10; export ORACLE_SID
  7. ORACLE_BASE=/data/app/oracle; export ORACLE_BASE
  8. ORACLE_HOME=$ORACLE_BASE/10.2.0; export ORACLE_HOME
  9. LD_LIBRARY_PATH=$ORACLE_HOME/lib; export LD_LIBRARY_PATH
  10. TNS_ADMIN=/var/opt/oracle;export TNS_ADMIN
  11. NLS_LANG=american; export NLS_LANG
  12. NLS_DATE_FORMAT='Mon DD YYYY HH24:MI:SS'; export NLS_DATE_FORMAT
  13. ORATAB=/var/opt/oracle/oratab;export ORATAB
  14. PATH=$PATH:$ORACLE_HOME:$ORACLE_HOME/bin:/usr/ccs/bin:/bin:/usr/bin:/usr/sbin:/sbin:/usr/openwin/bin:/opt/bin:.; export PATH
  15. DBALIST="tianlesoftware@vip.qq.com,[email]tianlesoftware@hotmail.com[/email]";export DBALIST

  16. sqlplus -s '/ as sysdba' <<EOF
  17. set feed off
  18. set heading off
  19. spool deadlock.alert
  20. SELECT SID, DECODE(BLOCK, 0, 'NO', 'YES' ) BLOCKER,
  21. DECODE(REQUEST, 0, 'NO','YES' ) WAITER
  22. FROM V/$LOCK
  23. WHERE REQUEST > 0 OR BLOCK > 0
  24. ORDER BY block DESC;
  25. spool off
  26. exit
  27. EOF
  28. if [ `cat deadlock.alert | wc -l` -gt 0 ]
  29. then
  30. mailx -s "DEADLOCK ALERT for PPRD10" $DBALIST < deadlock.alert
  31. fi
复制代码
四. 结论
  1. 0,20,40 7-17 * * 1-5 /dba/scripts/ckinstance.sh > /dev/null 2>&1
  2. 0,20,40 7-17 * * 1-5 /dba/scripts/cklsnr.sh > /dev/null 2>&1
  3. 0,20,40 7-17 * * 1-5 /dba/scripts/ckalertlog.sh > /dev/null 2>&1
  4. 30 * * * 0-6 /dba/scripts/clean_arch.sh > /dev/null 2>&1
  5. * 5 * * 1,3 /dba/scripts/analyze_table.sh > /dev/null 2>&1
  6. * 5 * * 0-6 /dba/scripts/ck_tbsp.sh > /dev/null 2>&1
  7. * 5 * * 0-6 /dba/scripts/invalid_object_alert.sh > /dev/null 2>&1
  8. 0,20,40 7-17 * * 1-5 /dba/scripts/deadlock_alert.sh > /dev/null 2>&1
复制代码
通过以上的脚本,可大大减轻你的工作。你可以使用这些是来做更重要的工作,例如性能调整。
标签: 暂无标签
sniper

写了 18 篇文章,拥有财富 157,被 11 人关注

转播转播 分享分享 分享淘帖
回复

使用道具

P4 | 发表于 2012-5-11 10:58:29
果然好东西呀
回复

使用道具

P4 | 发表于 2012-7-12 18:32:41
受教了,谢谢分享!
回复

使用道具

P3 | 发表于 2012-8-29 15:45:49
受教了,谢谢分享
回复

使用道具

P4 | 发表于 2012-8-30 18:16:24
very good!
回复

使用道具

P4 | 发表于 2014-1-12 22:24:44
回复

使用道具

P5 | 发表于 2014-1-13 01:35:38
受教了,谢谢分享
回复

使用道具

P3 | 发表于 2014-1-14 11:01:09
谢谢分享,脚本在运维过程中的作用是巨大的
回复

使用道具

您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

意见
反馈