今天用户投诉系统慢,查DB,出现大量的log file switch (checkpoint incomplete) event的进程.
查redo log的status:
SQL> select * from v$log;
GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARCHIV STATUS FIRST_CHANGE# FIRST_TI
---------- ---------- ---------- ---------- ---------- ------ -------------------------------- -----
1 1 97783 524288000 2 YES ACTIVE 7.9606E+10 2013-07-23 14:13
2 1 97782 524288000 2 YES ACTIVE 7.9606E+10 2013-07-23 14:05
3 1 97784 524288000 2 NO CURRENT 7.9606E+10 2013-07-23 14:19
原因为大量IO,DBWn未能及时将dirty cache data写入datafile,而造成redo log未能正常切换.解决方法,在现有的硬件的状态下,增加redo log file或增大redo log的size即可.
该下不探讨解决方法,而是提出一个疑问:
我们知道,当redo log switch时发触发一个完全检查点,checkpoint将完成以下动作:
1. LGWR清空日志缓存,将重做记录写入redo log.
2.DBWn将脏数据写入datafile
3.CKPT将最新SCN及RBA写入数据文件头部及控制文件.
我们再来了解一下redo log active状态下是一个什么的情况.当日志写满或alter system switch logfile时,LGWR会触发切换日志,新产生的日志的status就是Current,旧的日志会是Inactive或Active,Inactive是指可以被覆盖了,Active呢?Active和Current一样,是实例恢复所需要的,不能覆盖,那Active时,该redo log在玩些什么呢?Active时,代表datafile最近一次rba(scn)小于该日志最后一条重做记录的rba(scn),
如此,就有一问题 :
当下current的redo3,之前由redo2 switch来的,但switch log file时发生检查点应将redo log所有重做记录涉及的脏数据已写入datafile了,那又何来datafile的scn少于该日志的scn呢?
原因应为,LGWR和DBWn是并行工作的,switch log file是触发的检查点只是将脏数据写入datafile的任务分给DBWn,然后LGWR就自己去产生新的日志继续写了,而不是等checkpoint完成后才生出新的日志继续干活.当脏数据比较多的时候,DBWn忙不过来,就只能一直active住日志文件了.