ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 【转】cannot allocate new log

【转】cannot allocate new log

原创 Linux操作系统 作者:ljm0211 时间:2012-06-20 15:31:40 0 删除 编辑

出现此类错误一般操作是添加日志组或增大日志文件,本文描述了如何添加日志组,关于增大日志文件浏览:http://www.afant.net/cannot_allocate_new_log/

  1月10、12日某电信公司发生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争取更多的时间。

问题的解决办法:

此系统当前配置6组logfile,每组有两个成员,大小为50M,建议将log更改为200-500M的大小。

经查询(如下)每天日志switch数量大致在100-120之间,高峰时超出500多(此处必须得考虑业务突然繁忙的时刻,从中我们可以看出,1月12日switch数量是505,刚好是宕机的那一天),需要优化:

Number of Date Switches Redo Size

-------------------- -------- ---------

23-NOV-06 44   2,200

24-NOV-06 111 5,550

25-NOV-06 112 5,600

26-NOV-06 110 5,500

27-NOV-06 109 5,450

28-NOV-06 114 5,700

29-NOV-06 124 6,200

30-NOV-06 107 5,350

01-DEC-06 113 5,650

02-DEC-06 103 5,150

03-DEC-06 103 5,150

04-DEC-06 104 5,200

05-DEC-06 103 5,150

06-DEC-06 105 5,250

07-DEC-06 111 5,550

08-DEC-06 108 5,400

09-DEC-06 110 5,500

10-DEC-06 107 5,350

11-DEC-06 108 5,400

12-DEC-06 113 5,650

13-DEC-06 107 5,350

14-DEC-06 118 5,900

15-DEC-06 109 5,450

16-DEC-06 111 5,550

17-DEC-06 112 5,600

18-DEC-06 106 5,300

19-DEC-06 108 5,400

20-DEC-06 105 5,250

21-DEC-06 116 5,800

22-DEC-06 122 6,100

23-DEC-06 110 5,500

24-DEC-06 122 6,100

25-DEC-06 125 6,250

26-DEC-06 117 5,850

27-DEC-06 110 5,500

28-DEC-06 114 5,700

29-DEC-06 112 5,600

30-DEC-06 115 5,750

31-DEC-06 128 6,400

01-JAN-07 127 6,350

02-JAN-07 104 5,200

03-JAN-07 101 5,050

04-JAN-07 111 5,550

05-JAN-07 122 6,100

06-JAN-07 114 5,700

07-JAN-07 107 5,350

08-JAN-07 110 5,500

09-JAN-07 110 5,500

10-JAN-07 82 4,100

11-JAN-07 180 9,000

12-JAN-07 505 25,250

13-JAN-07 506 25,300

14-JAN-07 444 22,200

15-JAN-07 108 5,400

16-JAN-07 120 6,000

17-JAN-07 115 5,750

18-JAN-07 128 6,400

19-JAN-07 124 6,200

20-JAN-07 118 5,900

21-JAN-07 123 6,150

22-JAN-07 117 5,850

23-JAN-07 119 5,950

24-JAN-07 113 5,650

25-JAN-07 113 5,650

26-JAN-07 115 5,750

27-JAN-07 127 6,350

28-JAN-07 111 5,550

29-JAN-07 112 5,600

30-JAN-07 76   3,800

-------- ---------

sum      8848 442,400

就本机而言,建议只更改redo log的大小即可,更改大小为200M。

当前log信息如下:

SQL> select * from v$log;

GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS

----------   ----------  ----------     ----------    ---------- --- ----- -----------

1 1 190547    52428800 2 YES INACTIVE

2 1 190548    52428800 2 YES INACTIVE

3 1 190549    52428800 2 YES INACTIVE

4 1 190546    52428800 2 YES INACTIVE

5 1 190550    52428800 2 NO CURRENT

6 1 190545    52428800 2 YES INACTIVE

6 rows selected.

SQL> select member from v$logfile;

MEMBER

-----------------------------------------

/opt/oracle/db02/oradata/ORCL/redo01.log

/opt/oracle/db03/oradata/ORCL/redo01.log

/opt/oracle/db02/oradata/ORCL/redo02.log

/opt/oracle/db03/oradata/ORCL/redo02.log

/opt/oracle/db02/oradata/ORCL/redo03.log

/opt/oracle/db03/oradata/ORCL/redo03.log

/opt/oracle/db02/oradata/ORCL/redo04.log

/opt/oracle/db03/oradata/ORCL/redo04.log

/opt/oracle/db02/oradata/ORCL/redo05.log

/opt/oracle/db03/oradata/ORCL/redo05.log

/opt/oracle/db02/oradata/ORCL/redo06.log

/opt/oracle/db03/oradata/ORCL/redo06.log

12 rows selected.

此oracle的LOG大小为50M,共6组,每组有两个成员,分别位于/opt/oracle/db02和/opt/oracle/db03目录。

查询空间利用情况:

df –k查询这两个目录的空间利用情况:

所处盘区 kbytes 已使用    剩余空间大小 已使用百分比

/opt/oracle/db02 51200000     12900020    35906297     27%

/opt/oracle/db03  2048000 343661 1597823 18%

建议更改大小之后的redo log及其member仍然放在原来所处盘区/opt/oracle/db02、/opt/oracle/db03,/opt/oracle/db02剩余空间足够大,不必担心,而/opt/oracle/db03则至少需200M*6=1.2G,也不必担心,至少原来member所占用空间还可以重新利用!

1、 查询如下语句:

select * from v$log;

       GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS

----------   ----------  ----------     ----------    ---------- --- ----- -----------

1 1 190547    52428800 2 YES INACTIVE

2 1 190548    52428800 2 NO CURRENT

3 1 190549    52428800 2 YES INACTIVE

4 1 190546    52428800 2 YES INACTIVE

5 1 190550    52428800 2 YES INACTIVE

     6 1 190545    52428800 2 YES INACTIVE

2、   建议先查询并将用alter system switch logfile手工切换日志组,例如CURRENT在第二组,这样我可以先删除第六组,再重新创建第六组日志,大小为200M,这样做的原因是日志是按照顺序来使用的,而第一组日志归档时是需要几秒钟的,很快。

SQL> alter database drop logfile group 6;

手动删除第六组日志及成员文件:

SQL>! rm /opt/oracle/db02/oradata/ORCL/redo06.log

SQL>! rm /opt/oracle/db03/oradata/ORCL/redo06.log

  接下来重新创建第六组,这里要注意,大小不是原来的50M,而是200M:

SQL> alter database add logfile group 6 '/opt/oracle/db02/oradata/ORCL/redo06.log' size 200m;

SQL> alter database add logfile member '/opt/oracle/db03/oradata/ORCL/redo06.log' to group 6;

3、 接下来将CURRENT切换至第三组,并删除第一组:

SQL> alter database drop logfile group 1;

手动删除第一组日志及成员文件:

SQL>! rm /opt/oracle/db02/oradata/ORCL/redo01.log

SQL>! rm /opt/oracle/db03/oradata/ORCL/redo01.log

接下来重新创建第一组,大小为200M:

SQL> alter database add logfile group 1 '/opt/oracle/db02/oradata/ORCL/redo01.log' size 200m;

SQL> alter database add logfile member '/opt/oracle/db03/oradata/ORCL/redo01.log' to group 6;

  4、接下来将CURRENT切换至第四组,并删除第二组,方法跟上面两个一样,直至将所有的日志组及成员全部更改为200M大小。

5、 做完后再查询如下语句进行确认无误

SQL> select * from v$log;

SQL> select member from v$logfile;

注:这些步骤可以在线做,没有必要担心数据库出现问题,但建议避免业务高峰期,并且此问题必须尽快解决为好!

修改后问题解决。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/11411056/viewspace-733406/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2009-05-14

  • 博文量
    272
  • 访问量
    442071