分类: Oracle
2012-02-20 16:44:37
最近准备从一个正在的运行的中迁移空间数据,数据量是很大的(大概有80G),为windows2008 x64+oracle11GR1+arcsde9.3.1,在单位新搭建的AIX服务器上,操作系统为AIX5300 09-061013 +Oracle 11GR1 + arcsde9.3,迁移数据的方式采用ArcCataLog的copy方式,在迁移的过程中,数据库经常没有任何的反映,处于假死机的状态,查看alert.log日志文件,存在大量的重复信息,如下:
Fri May 14 22:20:27 2010
Thread 1 cannot allocate new log, sequence 859
Checkpoint not complete
Current log# 3 seq# 858 mem# 0: /fcdata/oradata/oradata/hzdb/redo03.log
Thread 1 advanced to log sequence 859
Current log# 1 seq# 859 mem# 0: /fcdata/oradata/oradata/hzdb/redo01.log
Thread 1 cannot allocate new log, sequence 860
Checkpoint not complete
Current log# 1 seq# 859 mem# 0: /fcdata/oradata/oradata/hzdb/redo01.log
Thread 1 advanced to log sequence 860
Current log# 2 seq# 860 mem# 0: /fcdata/oradata/oradata/hzdb/redo02.log
Fri May 14 22:20:40 2010
Thread 1 advanced to log sequence 861
Current log# 3 seq# 861 mem# 0: /fcdata/oradata/oradata/hzdb/redo03.log
Fri May 14 22:20:51 2010
Thread 1 cannot allocate new log, sequence 862
Checkpoint not complete
Current log# 3 seq# 861 mem# 0: /fcdata/oradata/oradata/hzdb/redo03.log
Thread 1 advanced to log sequence 862
Current log# 1 seq# 862 mem# 0: /fcdata/oradata/oradata/hzdb/redo01.log
Fri May 14 22:21:40 2010
Thread 1 cannot allocate new log, sequence 863
Checkpoint not complete
Current log# 1 seq# 862 mem# 0: /fcdata/oradata/oradata/hzdb/redo01.log
Thread 1 advanced to log sequence 863
Current log# 2 seq# 863 mem# 0: /fcdata/oradata/oradata/hzdb/redo02.log
为何会出现这样的情况呢?先了解一下基本的知识和分析一下错误的信息。
CKPT这个后台进程的就是做checkpoint这件事,checkpoint被触发的条件之一是就发生redo log switch,Checkpoint的具体包括:
•触发DBWn向磁盘写入Dirty data。
• 触发LGWR,把checkpoint信息更新到datafile header上。
• 触发LGWR,把checkpoint信息更新到control file里。
Checkpoint做的事情之一是触发DBWn把buffer cache中的Dirty cache写入磁盘。另外就是触发LGWR把最近的系统的SCN更新到datafile header和control file(每一个事务都有一个SCN),做第一件事的目的是为了减少由于系统突然宕机而需要的恢复时间,做第二件事实为了保证数据库的一致性。而redo log switch就是触发checkpoint的主要的事件(event),当第一组redo log被用完之后,就要停止使用当前的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争取更多的时间。
当oracle重用一个文件的时候,该日志文件所保护的处于Buffer cache中的脏块(dirty buffer),必须写回磁盘,且必须纪录checkpoint的位置在控制文件和数据文件头。这个过程叫做检查点checkpoint.
发生checkpoint not complete, cannot allocate new log ,表示要重用的日志文件的检查点还没有完成,被日志文件保护的脏块还没有完全被写回磁盘。必须等待该日志文件的checkpoint完成,才可以重新使用该日志文件。
V$LOG中STATUS为Active的,表示日志文件checkpoint未完成,Inactive表示checkpoint完成,current表示为当前LGWR写的日志文件。在实例恢复的时候,oracle需要使用到处于Active和Current状态的日志文件。
当因为检查点没有完成而不能重用日志文件的时候,从v$session_wait中可以看到很多session等待log file switch (checkpoint incomplete)事件,系统基本处于hang的状态。
我碰到一些情况是因为磁盘存在坏块,影响DBWR I/O.还需要注意其他问题
了解了基本的概念,着手处理这个问题显然更有针对性,AIX上现状的RedoLog使用默认的大小和组设置,大小为5M,分为3个组,这显然是不够用的。我认为由于redo日志太小,导致日志组频繁的切换,此时checkpoint也随之发生,这不足以满足系统对写日志和写磁盘的双重需要,往往写日志完成,写磁盘还在继续。系统不得不等待磁盘写完在进行日志的下一轮切换。因此,尝试增大redoLog的数量和组数。增加redelog Size 为500MB,分为5个组。具体的操作请参照本博《》,这样设置之后在继续观察一段时间。
设置log_checkpoints_to_alert = TRUE后可以在alert.log中看到checkpoint发生情况,包括开始和结束标记。另外需要说明的是,Log switch会触发一个checkpoint,但checkpoint不会导致一个log switch.唯一手工方式
alter system switch logfile或者重新设置redo logs大小 可以导致频繁switch
最后,SDE的空间数据数据量比较大,一但入库之后,更新的频率也是比较短的,这次oracle的问题并不代表实际业务的要求,建议完成SDE数据迁移后,再根据实际的业务数据量进行更改redolog的大小和组数,以符合总体的运行情况。
对于SDE的迁移,目前正在考虑不使用ArcCataLog的copy方式,采用数据的冷备份和恢复显然会更快捷和便利一些。此次遇到的问题,是实际遇到的问题,由此深入了ORACLE的操作原理,结合书本和实践,有了更深的理解。
参考文档:http://space.itpub.net/8382469/viewspace-259867
http://www.cnblogs.com/afant/archive/2009/05/08/1452772.html