发生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 的日志组。