发生oracle宕机事故,alert文件中报告如下错误:


Fri Jan 12 04:07:49 2007
Thread 1 cannot allocate new log, sequence 187398
Checkpoint not complete

 

产生此问题的原因分析:

CKPT这个后台进程的就是做checkpoint这件事,checkpoint被触发的条件之一是就发生redo log switch,Checkpoint的具体工作包括:
• 触发DBWn向磁盘写入Dirty data。
• 把checkpoint信息更新到datafile header上。
• 把checkpoint信息更新到control file里。

Checkpoint做的事情之一是触发DBWn把buffer cache中的Dirty cache磁盘。另外就是把最近的系统的SCN更新到datafile header和control file(每一个事务都有一个SCN),做第一件事的目的是为了减少由于系统突然宕机而需要的恢复时间,做第二件事实为了保证数据库的一致性。   而redo log switch就是触发checkpoint的主要的事件(event) ,当第一组redo log被用完之后,Oracle就要停止使用当前的redo log,转而使用另一组redo log,这就叫做log switch。而log switch触发checkpoint。   Oracle要求的最少的redo group 的是2个,但我们一般都建议配置3个或3个以上redo log group。假设我们只有两个redo log group:group 1和group 2,并且系统中总是有大量的dirty block需要写入datafile,当我们从group 1 switch to group 2的时候,会触发checkpoint, checkpoint要求DBWn把buffer cache中的dirty block写入datafile,然而,当我们再次用完group 2里面的空间,需要再次switch to group 1并重用group 1的时候,如果我们发现redo log group 1所保护的那些dirty block还没有完全写入到datafile,整个数据库必须等待DBWn把所有的dirty block写入到datafile之后才能做其他的事情,这就是我们遇到的“checkpoint not complete”问题。这个问题往往暗示了redo log的配置有问题,就本例而言,要么是redo log太小,要么是像我们这里的redo log group太少,只有2个。而这个问题的解决方案就是加大redo log或添加更多redo log group,不管哪一种解决方案,我们的目的都是给DBWn争取更多的时间。

参考其它解释如下:
当系统要重新利用某个日志文件的时候,系统需要将该日志文件所包括的buffer cache 中的dirty block 写到相应的数据文件。由于对于一个数据库操作而言,它可能产生的redo 量仅仅是几十字节,但是对于buffer cache中确是一个block (一般为8k)。所以,对于一个仅仅是几百M的日志文件,它所保护的buffer cache 可能是几个G
一旦发生"Thread 1 cannot allocate new log",表明系统的checkpoint 没有来得及完成,也就是说 buffer cache 中的dirty data还没有完全写到数据文件,就已经有大量的日志需要写入到系统。而系统只能通知应用:checkpoint 还没有完成,你只能等待。这个时候,系统就基本处于hang 状态了 When the database waits on checkpoints,redo generation is stopped until the
log switch is done
如果,我们在这个时候查看系统信息,就会发现:v$log中的日志状态大多处于active 状态; v$session_wait 中会有很多log file switch 事件的发生


解决办法:

a. 添加更多的日志文件  

b. 加大checkpoint 触发的频度  

c. 减小redo log 的size

d. 提高DBWR的效率

e. 为了更好的了解系统的运行,可以设置

      log_checkpoint_interval = 0 log_checkpoint_timeout = 0 log_checkpoints_to_alert=True

 

 

增加日志组:

1、select group#,sequence#,bytes,members,status from v$log;  查看每组日志的状态

   GROUP#  SEQUENCE#      BYTES    MEMBERS STATUS
---------- ---------- ---------- ---------- ----------------
         1      16946   52428800          1 INACTIVE    ##  空闲的
         2      16947   52428800          1 INACTIVE    ##  空闲的
         3      16948   52428800          1 CURRENT   ##正在使用的

2、

alter database add logfile group 4 ('/opt/oradata/orclbj/redo04.log') size 200M;   增加1组日志组 视情况而定增加日志组的大小。

alter database add logfile group 5 ('/opt/oradata/orclbj/redo05.log') size 200M;

alter database add logfile group 6 ('/opt/oradata/orclbj/redo06.log') size 200M;

3、alter system switch logfile;  切换日志组

4、alter database drop logfile group 1; 删除日志组1  在线增加日志组的时候,删除日志组的时候只能删除 日志组状态为 INACTIVE 的日志组。

 

转载地址:https://blog.csdn.net/zonelan/article/details/7613519

   https://blog.csdn.net/pinchw/article/details/5778221