作者:dbtan |【转载时请以超链接形式标明文章出处作者信息】


日志的状态:

可以通过v$log视图来查看日志文件的状态:

sys@NEI> select group#,status,first_change# from v$log;
    GROUP# STATUS           FIRST_CHANGE#
---------- ---------------- -------------
         1 CURRENT               59719840
         2 INACTIVE              59719832
         3 INACTIVE              59719835

最常见的日志状态有4种
CURRENT指当前的日志文件,该日志文件是活动的,当前正在被使用的,在进行崩溃恢复时Current的日志文件是必须的。

ACTIVE日志是活动的非当前日志,该日志可能已经完成归档也可能没有归档,活动的日志文件在Crash恢复时会被用到。Active状态意味着,检查点尚未完成,如果日志文件循环使用再次到达该文件,数据库将处于等待的停顿状态,此时在alter文件中,可以看到类似如下记录:

Thu Jun 18 05:34:42 2009
Thread 1 cannot allocate new log, sequence 4
Checkpoint not complete
  Current log# 3 seq# 3 mem# 0: /home/oracle/app/oracle/oradata/ccdb/redo03.log

当这种问题出现时,可以从数据库内部通过v$session_wait来观察,该视图会显示数据库当前哪些Sesssion正处于这种等待。Checkpoint not complete在数据库中体现为等待事件log file switch(checkpoint incomplete)

select sid,event,state from v$session_wait;

同时要注意DBWR进程正在执行db file parallel write,日志文件必须等待DBWR完成检查点触发的写操作之后才能被覆盖。如果设置了参数log_checkpoints_to_alterTrue的话,还可以在alert文件中清晰地看到检查点的增进和完成情况:

Wed Dec 16 17:15:54 2009
Beginning log switch checkpoint up to RBA [0x8f9.2.10], SCN: 59738301
Thread 1 advanced to log sequence 2297
  Current log# 3 seq# 2297 mem# 0: /home/oracle/oradata/ccdb/redo03.log
Beginning log switch checkpoint up to RBA [0x8fa.2.10], SCN: 59738303
Thread 1 advanced to log sequence 2298
  Current log# 1 seq# 2298 mem# 0: /home/oracle/oradata/ccdb/redo01.log
Thread 1 cannot allocate new log, sequence 2299
Checkpoint not complete
  Current log# 1 seq# 2298 mem# 0: /home/oracle/oradata/ccdb/redo01.log
Wed Dec 16 17:15:55 2009
Completed checkpoint up to RBA [0x8fa.2.10], SCN: 59738303
Completed checkpoint up to RBA [0x8f9.2.10], SCN: 59738301
Wed Dec 16 17:15:59 2009
Beginning log switch checkpoint up to RBA [0x8fb.2.10], SCN: 59738307
Thread 1 advanced to log sequence 2299
  Current log# 2 seq# 2299 mem# 0: /home/oracle/oradata/ccdb/redo02.log
Wed Dec 16 17:16:01 2009
Completed checkpoint up to RBA [0x8fb.2.10], SCN: 59738307

通过这些对比和观察,可以使我们更好地了解Oracle的运行机制。

可以对这个问题做一下简单的分析,Checkpoint incomplete有多种可能原因:

·日志文件过小,切换过于频繁;
·日志组太少,不能满足正常事务量的需要;
·日志文件所在磁盘I/O存在瓶颈,导致写出缓慢,阻塞数据库正常运行;
·由于数据文件磁盘I/O瓶颈,DBWR写出过于缓慢;
·由于事务量巨大,DBWR负荷过高,不堪重负。

针对不同的原因,又可以从不同角度着手解决问题:

·适当增加日志文件大小;
·适当增加日志组数;
·使用更快速磁盘存储日志文件(如:采用更高转速磁盘;使用RAID10而不是RAID5等方式);
·改善磁盘I/O性能;
·使用多个DBWR进程或使用异步I/O等。

总之,只要我没能够发现数据库的问题所在,就能够从各个角度分析问题并寻找恰当的解决方法。需要强调的是,这是一类严重的等待,它意味着数据库不能再产生日志,所有数据库修改操作将全部挂起。

INACTIVE是非活动日志,该日志在实例恢复时不再需要,但是在介质恢复时可能会用到。INACTIVE状态的日志也可能没有被归档。如果数据库启动在归档模式,在未完成归档之前,日志文件也不允许被覆盖,这时活动进程处于log file switch(archiving needed)等待之中。

日志是否完成归档,可以根据V$LOG.ARCHIVED字段进行判断,以下案例日志文件ARCHIVED状态为NO,也就是尚未归档:

sys@NEI> archive log list;
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            /home/oracle/archivelog2
Oldest online log sequence     2297
Next log sequence to archive   2299
Current log sequence           2299
sys@NEI> select * from v$log;
    GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARCHIVED   STATUS           FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- ---------- ---------------- ------------- ---------------
         1          1       2301  104857600          1 NO         ACTIVE                59739139 16-DEC-09
         2          1       2302  104857600          1 NO         ACTIVE                59739143 16-DEC-09
         3          1       2303  104857600          1 NO         CURRENT               59739145 16-DEC-09

注意此时所有日志组都没有完成归档,所有DML事务都将挂起,用户处于log file switch(archiving needed)等待:

select sid,event from v$sesssion_wait;

这种情况需要DBA介入进行紧急处理,否则普通用户将无法连接:

sys@NEI> conn dbtan/dbtan
ERROR:
ORA-00257: archiver error. Connect internal only, until freed.

这种情况通常是由数据库异常引起的,可能是因为I/O缓慢,也可能是因为事务量过大,在特殊情况下,有可能是因为日志损坏。对于本案例就属于前者,是由作者人为“疯狂”switch logfile 所至。

UNUSED 表示该日志从未被写入,这类日志可能是刚被添加到数据库或者在RESETLOGS之后被重置。被使用之后,该状态会被改变。

- The End -