第十五章:Oracle12c 数据库 警告日志

一:查看警告日志文件的位置

Oracle 12c环境下查询,alert日志并不在bdump目录下,看到网上和书上都写着可以通过初始化参数background_dump_dest来查看alter日志路径,还说警告日志文件的缺省位置是%Oracle_base%\admin\orcl\bdump,其实12c中,上述路径都不是真正存放警告日志的路径。

真是路径是要需要通过v$diag_info视图来查询,为什么呢?

因为在ORACLE 12c中,引入了ADR(Automatic Diagnostic Repository(自动诊断仓库):一个存放数据库诊断日志、跟踪文件的目录,关于ADR对应的目录位置可以通过查看v$diag_info系统视图。其实11g中也有v$diag_inifo,说是可以直接通过show parameter background_dump_dest来查看警告日志路径,但我没有测试过。

下面我是我本机测试结果,数据库版本的是12.2.0.1

SQL> set linesize 1000;

SQL> col name for  a40;
SQL> col value for a100;
SQL> select name ,value from v$diag_info; NAME VALUE
---------------------------------------- ----------------------------------------------------------------------------------------------------
Diag Enabled TRUE
ADR Base /u01/app/oracle
ADR Home /u01/app/oracle/diag/rdbms/orcl/orcl
Diag Trace /u01/app/oracle/diag/rdbms/orcl/orcl/trace
Diag Alert /u01/app/oracle/diag/rdbms/orcl/orcl/alert
Diag Incident /u01/app/oracle/diag/rdbms/orcl/orcl/incident
Diag Cdump /u01/app/oracle/diag/rdbms/orcl/orcl/cdump
Health Monitor /u01/app/oracle/diag/rdbms/orcl/orcl/hm
Default Trace File /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_28952.trc
Active Problem Count 1
Active Incident Count 1 11 rows selected. SQL>

二:警告日志内容

那么告警日志非常关键与重要,那么告警日志里面包含了那些内容信息呢?告警日志包含了下面一些内容的信息。像一些ORA错误,对于监控数据库有极其重要的作用。

1:所有的内部错误(ORA-600)信息,块损坏错误(ORA-1578)信息,以及死锁错误(ORA-60)信息等。

2:管理操作,例如CREATE、ALTER、DROP语句等,以及数据库启动、关闭以及日志归档的一些信息。

2.1 涉及物理结构的所有操作:例如创建、删除、重命名数据文件与联机重做日志文件的ALTER DATABASE命令,此外还涉及重新分配数据文件大小以及将数据文件联机与脱机的操作。

2.2 表空间操作,例如DROP与CREATE命令,此外还包括为了进行用户管理的备份而将表空间置入和取出热备份模式的操作

3:与共享服务器或调度进程相关功能的消息和错误信息。

4:物化视图的自动刷新过程中出现的错误。

5:动态参数的修改信息。

三:告警日志监控:

既然告警日志如此重要,而我们也不可能随时手工去查看告警日志文件,那么我们就必须监控告警日志,那么监控告警日志有哪些方案呢?下面归纳一下

方案1:

Tom大师给出的一个方案(仅适用于ORACLE 10g),将告警日志文件信息读入全局临时表,然后我们就可以定制一些SQL语句查询告警日志的信息。

create global temporary table alert_log
( line int primary key, text varchar2(4000)
)
on commit preserve rows
/ create or replace procedure load_alert
as l_background_dump_dest v$parameter.value%type; l_filename varchar2(255); l_bfile bfile; l_last number; l_current number; l_start number := dbms_utility.get_time;
begin select a.value, 'alert_' || b.instance || '.log' into l_background_dump_dest, l_filename from v$parameter a, v$thread b where a.name = 'background_dump_dest'; execute immediate 'create or replace directory x$alert_log$x as ''' || l_background_dump_dest || ''''; dbms_output.put_line( l_background_dump_dest ); dbms_output.put_line( l_filename ); delete from alert_log; l_bfile := bfilename( 'X$ALERT_LOG$X', l_filename ); dbms_lob.fileopen( l_bfile ); l_last := 1; for l_line in 1 .. 50000 loop dbms_application_info.set_client_info( l_line || ', ' || to_char(round((dbms_utility.get_time-l_start)/100, 2 ) ) || ', '|| to_char((dbms_utility.get_time-l_start)/l_line) ); l_current := dbms_lob.instr( l_bfile, '0A', l_last, 1 ); exit when (nvl(l_current,0) = 0); insert into alert_log ( line, text ) values ( l_line, utl_raw.cast_to_varchar2( dbms_lob.substr( l_bfile, l_current-l_last+1, l_last ) ) ); l_last := l_current+1; end loop; dbms_lob.fileclose(l_bfile); end;
/

但是这又一个问题,如果数据库宕机了的情况下,是无法获取这些错误信息,比方案3(从操作系统监控告警日志)对比,有些特定场景不适用。另外有一定不足之处,就是日志文件比较大的时候,监控告警日志信息比较频繁的时候,会产生不必要的IO操作。

方案2:

通过外部表来查看告警日志文件的内容。相当的方便。然后也是使用定制SQL语句来查询错误信息。

SQL> create or replace directory bdump as '/u01/app/oracle/admin/GSP/bdump';

Directory created.

SQL> create table alert_logs
2 (
3 text varchar2(2000)
4 )
5 organization external
6 (
7 type oracle_loader
8 default directory bdump
9 access parameters
10 (
11 records delimited by newline
12 fields
13 reject rows with all null fields
14 )
15 location
16 (
17 'alert_GSP.log'
18 )
19 )
20 reject limit unlimited; Table created. SQL> select * from alert_logs; TEXT
--------------------------------------------------------------------------------
Thu Aug 7 14:50:28 2014
Thread 1 advanced to log sequence 14
Current log# 1 seq# 14 mem# 0: /u01/app/oracle/oradata/GSP/redo01.log SQL>

方案3:

查看此文:http://www.cnblogs.com/kerrycode/p/3168662.html

归档告警日志文件

告警日志文件如果不加管理的话,那么文件会持续增长,有时候文件会变得非常大,不利于读写。一般建议将告警日志按天归档,归档文件保留三个月(视情况而定),下面来看看将告警日志文件归档的两个Shell脚本:

---alert_log_archive.sh version 1

#*************************************************************************
# FileName :alert_log_archive.sh
#*************************************************************************
# Author :Kerry
# CreateDate :2013-07-02
# blogs   :www.cnblogs.com/kerrycode
# Description :this script is made the alert log archived every day
#************************************************************************* #! /bin/bash date=`date +%Y%m%d` alert_log_path="$ORACLE_BASE/admin/$ORACLE_SID/bdump" alert_log_file="alert_$ORACLE_SID.log" alert_arc_file="alert_$ORACLE_SID.log""."${date} cd ${alert_log_path}; if [ ! -e "${alert_log_file}" ]; then
echo "the alert log didn't exits, please check file path is correct!";
exit;
fi if [ -e ${alert_arc_file} ];then echo "the alert log file have been archived!" else cat ${alert_log_file} >> ${alert_arc_file} cat /dev/null > ${alert_log_file} fi

其实脚本1和脚本差别不大,仅仅是mv与cat >>的区别

alert_log_archive.sh version 2

#*************************************************************************
# FileName :alert_log_archive.sh
#*************************************************************************
# Author :Kerry
# CreateDate :2013-07-02
# blogs   :www.cnblogs.com/kerrycode
# Description :this script is made the alert log archived every day
#************************************************************************* #! /bin/bash date=`date +%Y%m%d` alert_log_path="$ORACLE_BASE/admin/$ORACLE_SID/bdump" alert_log_file="alert_$ORACLE_SID.log" alert_arc_file="alert_$ORACLE_SID.log""."${date} cd ${alert_log_path}; if [ ! -e "${alert_log_file}" ]; then
echo "the alert log didn't exits, please check file path is correct!";
exit;
fi if [ -e ${alert_arc_file} ];then echo "the alert log file have been archived!" else mv ${alert_log_file} ${alert_arc_file} cat /dev/null > ${alert_log_file} fi

然后在crontab定时任务里面加上下面语句,每天23点59对告警日志进行归档。

[oracle@DB-Server scripts]$ crontab -l

# the alert log archived every day                    Add by kerry 2013-07-02

59 23 * * * /home/oracle/scripts/alert_log_archive.sh >/dev/null 2>$1

细心的朋友可能已经发现上面的脚本、配置错误了,我在部署测试的过程中,是指定二十分钟执行一次,但是等了四十分钟,发现定时任务一次都没有执行,手工执行上面脚本是完全没有问题的,最后仔细的检查一遍,居然发现悲剧的发现时自己一时粗心将&符号写成了$,真是很二的一个错误

59 23 * * * /home/oracle/scripts/alert_log_archive.sh >/dev/null 2>$1

59 23 * * * /home/oracle/scripts/alert_log_archive.sh >/dev/null 2>&1

接下来测试发现脚本执行有问题,在crontab 里执行该shell脚本时,获取不到ORACLE的环境变量,这是因为crontab环境变量问题,Crontab的环境默认情况下并不包含系统中当前用户的环境。所以,你需要在shell脚本中添加必要的环境变量的设置,修改的脚本如下:

上一篇:Session和Cookie深度剖析


下一篇:《Javascript高级程序设计》阅读记录(三):第五章 上