Database/ORACLE

[스크랩] Redo Log File - Thread 1 cannot allocate

99iberty 2015. 9. 23. 20:24

http://aladdin76.tistory.com/595


매우 중요한 파일로써 데이터베이스의 Transaction과 관련된 로그들 입니다. 만약 DB의 전원이 갑자기 나가 인스턴스 오류가 발생하면 정원이 나간 바로 그시점전 까지 복구를 위해 온라인 재실행 로그를 사용하게 되고, 데이터 파일이 있는 디스크가 못쓰게 되었다면 특정 시점으로의 복구를 위해 온라인 재실행 로그 뿐 아니라 아카이브된 재실행 로그를 활용해서 복구를 시도할 것 입니다.

모든 오라클 연산은 재실행 정보를 생성하여 온라인 재실행 로그 파일에 기록을 합니다. 예를 들어 테이블에 데이터가 추가 되거나 삭제 될 때 그 기록이 재실행 로그에 기록되어 지니다. 만약 테이블을 삭제 한다면 삭제한 결과가 재실행 로그에 기록되며 삭제된 테이블이 가지고 있던 데이터는 기록되지 않습니다. 한편 테이블을 삭제하기 위해 수행되는 오라클의 Recursive SQL(반복/재귀 SQL)은 재실행 정보를 생성 합니다. 예를 들면 오라클은 테이블 삭제를 위해 SYS.OBJ$ 테이블로부터 한 행을 제거 하는데 이로써 재실행 정보가 생성 됩니다.

어떤 연산들은 재실행 로그의 사용을 적게 하는 모드로 수행 될 수 있는데, NOLOGGING 속성을 가지는 인덱스를 생성 할 수 있습니다. 이것의 의미는 인덱스의 (초기) 생성은 로그를 기록하지 않지만 오라클이 수행하는 반복/재귀 SQL은 로그로 기록됨을 의미 합니다.

즉 이와 같이 인덱스가 존재하는 테이블에 대한 한 행의 삽입은 재실행 로그에 기록되지 않지만 SQL 삽입,삭제, 갱신 연산을 이용하여 인덱스를 변경 하는 것은 로그에 기록된다는 것입니다.

온라인 재실행 로그

모든 오라클 데이터베이스는 최소 2개 이상의 온라인 재실행 로그 파일을 가집니다. 이들 파일들은 모두 고정된 크기를 가지면서 돌아가면서 사용 됩니다.먼제 로그 1번 파일에 기록되고 이 파일이 가득차면 2번 파일, 또 가득차면 로그3번 파일로 옮겨서 기록 합니다. 이를 반복하면서 각 로그파일은 이전에 기록된 내용을 덮어 써 가면서 새로운 로그를 기록 합니다.

한 로그 파일로부터 다른 로그 파일로 전환하는 것을 로그 스위치(Log Switch)라고 하며 이러한 로그 스위치는 제대로 튜닝이 안된 DBMS에서는 그 순간 잠시 정체 할 수도 있습니다. 재 실행 로그는 복구를 위해 사용 되므로 덮어 써지기 전에 그 로그가 100% 필요 없다는 확신이 필요 합니다.

만약 오라클이 로그 파일의 내용이 더 이상 필요 없다는 것을 확신 하지 못한다면, 데이터베이스 연산은 순간적으로 정지되고 해당 하는 재실행 로그를 보호하는 데이터가 디스크에 안전하게 저장되어 있는지를 확인 할 것입니다. 일단 이것이 확인 되면 수행이 재개되며 재실행 로그 파일은 사용 되어 집니다. 여기서 체크 포인팅(Checkpointing)에 대해 이야기를 해야 되는데 온라인 재실행 로그의 사용 방법을 이해하기 위해서는 체크포인트, 데이터베이스 버퍼캐쉬의 동작 방법, DBWn(DataBase Block Writer) 이라 불리는 프로세스가 하는 일에 대해 알 필요가 있습니다.

데이터베이스 버퍼 캐시는 데이터베이스 블록들이 임시로 저장되는 장소로서 오라클의 SGA에 위치 하고 있습니다. 데이터 블록들이 읽혀 지면 데이터베이스 버퍼 캐시에 저장하여 향후 이 블록들을 디스크에서 다시 읽지 않도록 합니다.

데이터베이스 버퍼 캐시는 가장 중요한 성능 튜닝 디바이스로서 느린 물리적 디스크 I/O를 실제 보다 더욱 빠르게 만듭니다. 만약 블록의 내용이 변경 되면 데이터베이스 버퍼 캐시에 있는 블록들에게 적용 됩니다. 이러한 변경을 재실행 할 충분한 정보는 또 다른 SGA 데이터 구조인 재실행 로그 버퍼(Redo Log Buffer)에 기록 됩니다. 이때 커밋(Commit)을 한다면

오라클은 SGA에서 변경된 모든 블록들을 디스크에 기록하지 않는 대신에 재실행 로그 버퍼의 내용을 온라인 재실행 로그로 기록 합니다. 변경된 블록이 디스크에 기록되지 않고 데이터베이스 버퍼 캐시에 있는 동안에는 온라인 재실행 로그의 기록이 필요 합니다. 만약 커밋한 바로 얼마 후 전원이 나간다면 데이터베이스 버퍼 캐시는 완전히 비게 됩니다.(메모리 구조 이므로) 이 경우엔 변경된 내용은 온라인 재실행 로그 파일에 있어 DB 재구동시 오라클은 이전의 트랜잭션을 다시 수행하여 블록을 변경 시키고 커밋을 하게 됩니다. 그래서 변경된 블록이 디스크에 기록되지 않고 데이터베이스 버퍼 캐시에 있는 동안에는 온라인 재실행 로그를 덮어 써 버리면 안 되는 것입니다.

DBWn은 오라클의 백그라운드 프로세스로서 데이터베이스 버퍼 캐시가 가득 차 있는 상태에서 체크포인트를 수행 하기 위해 버퍼 캐시에 공간을 만드는 역할을 담당 합니다. 체크포인트는 손상된 블록(dirty/modified blocks)들을 데이터베이스 버퍼 캐시에서 디스크로 내리는 것입니다.

가장 일반적인 경우는 재실행 로그 스위치 입니다. 로그파일1이 가득차 로그파일2로 스위치 될 때 오라클은 체크 포인트를 시작 시킵니다. 이 시점에 DBWn은 로그 파일2에 의해서 보호된 변경된 블록을 모두 디스크로 내리기 시작하며 DBWn이 모두 디스크로 내리기 전까지 로그파일2를 사용 할 수 없습니다. 만약 DBWn이 모두 내리기 전에 로그파일1을 사용하려고 하면 다음과 같은 오류가 발생 합니다.

Thread 1 cannot allocate new log, sequence 66
Checkpoint not complete
Current log #2 seq# 65 mem# 0: c:\oracle\oradata\WINK\redo02.log

이 메시지가 나타날 때 데이터베이스는 잠시 정지되고 DBWn은 급히 체크포인트를 완료 합니다. 이 시점에 오라클은 모든 힘을 DBWn에게 주어 빨리 체크 포인트가 끝나도록 합니다.

이와 같은 현상은 잘 튜닝된 DBMS에서는 잘 발생하지 않도록 원할 것이며 DBA의 입장에서는 체크포인트가 완료 되기 전에 온라인 재실행 로그 파일이 사용되지 않도록 충분히 큰 로그파일을 원할 겁니다. 만약 앞의 메시지를 자주 보게 되면 충분한 온라인 재실행 로그를 할당하지 않았거나 DBWn이 효율적으로 동작하도록 튜닝이 필요하다는 것을 의미 합니다.


온라인 재실행 로그의 개수와 크기를 정할 때 고려해야 하는 요소

1.대기 데이터베이스(standby database) : 만약 대기 데이터베이스를 활용하고 있다면 재실행 로그들이 가득 찰 경우 대기 데이터베이스로 보내어 지기 때문에, 대부분 크기는 작지만 많은 수의 재실행 로그들이 필요 합니다.

2.동일한 블록을 변경하는 사용자가 많은 경우 : 이 경우에는 대용량의 온라인 재실행 로그 파일이 필요 합니다.모든 사람들이 동일한 블록을 변경 하기 때문에 이 블록들을 디스크에 기록하기 전까지는 재실행 로그가 다시 사용되면 안 되는 것이다. 각각의 로그스위치는 체크포인트를 발생 시키기 때문에 로그스위치가 자주 일어나지 않게 할 필요가 있습니다.


3.복구 평균 시간 : 만약 복구 시간이 최대한 단축되어야 한다면 동일한 블록을 변경하는 사람이 많다고 할지라도 적은 용량의 온라인 재실행 로그 파일이 필요 합니다. 복구를 위해 하나의 큰 로그파일을 처리하는 것보다 적은 양으로 여러 개의 로그 파일을 처리하는 것이 시간을 줄일 수 있습니다. 적은 크기의 온라인 재실행 로그를 사용하면 빈번한 로그스위치로 인한 체크포인트가 발생하여 성능은 떨어지지만 복구를 위한 사간은 줄어 듭니다.


아카이브된 재실행 로그 파일(Archived Redo Log File)

오라클데이터 베이스는 NOARCHIVELOG와 ARCHIVELOG의 두가지 모드 중 하나로 동작 합니다. 대부분 ARCHIVELOG로 운영되지 않는 시스템은 생산시스템이 아닙니다. 왜냐하면 ARCHIVELOG로 운영되지 않으면 언젠가는 DB의 데이터는 잃어 버리게 됩니다. 단지 TEST 용도로 쓰이는 DB만 NPARCHIVELOG로 돌려야 합니다.

이 두 모드의 차이는 오라클이 온라인 재실행 로그를 처리하는 방법에 따라 차이가 납니다. “재실행 로그를 재사용 할 때, 재실행 로그의 복사본을 유지하는가? 아님 덮어 써버리는가?” 입니다. ARCHIVELOG모드인 경우 온라인 재실행 로그를 덮어 쓰기 전에 HDD에 정해진 ARCHIVE DESTINATION 폴더에 파일로써 보관을 하는 겁니다.

DB가 NOARCHIVELOG로 운영되며 일주일에 한번 매주 토요일에 백업을 한다고 가정을 하겠습니다. 일주일 동안 몇 백개의 재실행 로그를 생성한 후 금요일 오후에 HDD 오류가 생겼다고 할 때 선택할 수 있는 방법은 다음의 두가지중 하나 입니다.

오류가 발생한 디스크에 있는 테이블스페이스를 없앰… 이 경우 해당 테이블스페이스의 데이터는 모두 날아가게 됩니다. 만약 SYSTEM 테이블스페이스가 영향을 받게 되면 이 방법은 사용 할 수가 없습니다.

지난 토요일의 백업 데이터를 이용하여 복구… 이 경우 이번 주 작업한 것은 잃어버리게 되는 겁니다.

결론적으로 중요한 데이터베이스 시스템은 반드시 ARCHIVELOG 모드로 운영 되어야 합니다

 

 

참고)

...
Thread 1 cannot allocate new log, sequence 66
Checkpoint not complete
Current log# 2 seq# 65 mem# 0: C:\ORACLE\ORADATA\ORA10G\REDO02.LOG
...

So, at the point in time when this message appeared, processing was suspended in the database while DBWn hurriedly finished its checkpoint. Oracle gave all the processing power it could to DBWn at that point in the hope it would finish faster.

This is a message you never want to see in a nicely tuned database instance. If you do see it, you know for a fact that you have introduced artificial, unnecessary waits for your end users. This can always be avoided. The goal (and this is for the DBA, not the developer necessarily) is to have enough online redo log files allocated so that you never attempt to reuse a log file before the checkpoint initiated by it completes. If you see this message frequently, it means a DBA has not allocated sufficient online redo logs for the application, or that DBWn needs to be tuned to work more efficiently.

Different applications will generate different amounts of redo log. A Decision Support System (DSS, query only) or DWsystem will naturally generate significantly less online redo log than an OLTP (transaction processing) system would, day to day. A system that does a lot of image manipulation in Binary Large Objects (BLOBs) in the database may generate radically more redo than a simple order-entry system. An order-entry system with 100 users will probably generate a tenth the amount of redo 1,000 users would generate. There is no “right” size for your redo logs, although you do want to ensure they are large enough for your unique workload.

You must take many things into consideration when setting both the size of and the number of online redo logs. Many of them are beyond the scope of this particular book, but I’ll list some of them to give you an idea:

      • Peak workloads: You would like your system to not have to wait for checkpoint notcomplete messages, to not get bottlenecked during your peak processing. You will be sizing your redo logs not for “average” hourly throughput, but rather for your peak processing. If you generate 24GB of log per day, but 10GB of that log is generated between 9:00 am and 11:00 am, you’ll want to size your redo logs large enough to carry you through that two-hour peak. Sizing them for an average of 1GB per hour would probably not be sufficient.
      • Lots of users modifying the same blocks: Here you might want large redo log files. Since everyone is modifying the same blocks, you would like to update them as many times as possible before writing them out to disk. Each log switch will fire a checkpoint, so you would like to switch logs infrequently. This may, however, affect your recovery time.
      • Mean time to recover: If you must ensure that a recovery takes as little time as possible, you may be swayed toward smaller redo log files, even if the previous point is true. It will take less time to process one or two small redo log files than a gargantuan one upon recovery. The overall system will run slower than it absolutely could day to day perhaps (due to excessive checkpointing), but the amount of time spent in recovery will be shorter. There are other database parameters that may also be used to reduce this recovery time, as an alternative to the use of small redo log files.


http://l0vemode.tistory.com/151


bdump 에서 해당과 같은 메시지가 발견되었다.
로그를 확인해보니 자주 발생했던 녀석은 아닌 것 같긴 한데,
이 날 만 그랬는지 내역을 조회해 보고 있다.

토요일 오전이면 Transaction이 많이 발생할 때도 아닌 것 같은데 찜찜하네

인터넷을 찾아보니 Redo Log Group 갯수 부족 + Redo Log Size 크기 부족
두 가지가 원인이 된다고 하는데 해당 DB의 내역을 보니
Group도 3개, Size도 500MB 정도면 작은 편도 아닌데 진짜 많이 쓰나보네
토요일에 도대체 무슨 짓을 한건지 (-_-;) 따로 작업 한 것도 없는데..

차후 이와 같은 에러가 계속 발생 할 경우 Redo Log Size를 증가시키거나, Redo Log Group의 갯수를 늘려줄 것!

해당 현상에 대해 다루어 놓은 2개의 블로그 글을 첨부해둔다.

[에러 메시지 관련 블로그 글]
http://blog.naver.com/anova91?Redirect=Log&logNo=50007809716

[Redo Log 관련 개론(?)]
http://majesty76.tistory.com/62



http://www.oracleracexpert.com/2013/07/thread-1-cannot-allocate-new-log.html


Thread 1 cannot allocate new log & Checkpoint not complete

Users will see these messages when Oracle wants to reuse the redolog file, but checkpoint position is still in the log, Oracle must wait until the checkpoint completes.

Cause: In this situation either DBWR writes slowly or log switch happens before the log is completely full or log file is small.

Mon Apr 15 07:20:42 2013
Thread 1 advanced to log sequence 5021
Current log# 1 seq# 5021 mem# 0: /oracle/ORCL/redoA/redo01.log
Mon Apr 15 07:21:15 2013
Thread 1 cannot allocate new log, sequence 5022
Checkpoint not complete


If you have many updates in the system, you might need more redo groups. If you have fewer redo groups then adding more redo groups will help.

Use below syntax to add more redo groups

ALTER DATABASE ADD LOGFILE GROUP <Group No> ('<Redo log member 1 path’ ,'<redo log member 2 path>') size 500M;

If you have smaller redo log and if you see many log switches then increasing the redo size might help.

Step1: Switch logfile to make group 1 ‘INACTIVE’

SQL> Alter system switch logfile;
SQL> select group#, status from v$log;

GROUP# STATUS
---------- ----------------
1 INACTIVE
2 ACTIVE
3 CURRENT

Step2:- Drop the log group1 which is ‘INACTIVE’ and recreate with bigger size.

SQL> alter database drop logfile group 1;

SQL> alter database add logfile group 1 ('/db01/ORCL/redoA/log1_m1.dbf',' /db01/ORCL/redoB/log1_m2.dbf') size 100M reuse;

Repeat step 1 and 2 until you drop and recreate all redo logs with bigger size.

It is a recommended to have 4-5 log switches per hour. You can use below Script to find the log switches on hourly basis.

set lines 120;
set pages 999;
SELECT to_char(first_time,'YYYY-MON-DD') day,
to_char(sum(decode(to_char(first_time,'HH24'),'00',1,0)),'99') "00",
to_char(sum(decode(to_char(first_time,'HH24'),'01',1,0)),'99') "01",
to_char(sum(decode(to_char(first_time,'HH24'),'02',1,0)),'99') "02",
to_char(sum(decode(to_char(first_time,'HH24'),'03',1,0)),'99') "03",
to_char(sum(decode(to_char(first_time,'HH24'),'04',1,0)),'99') "04",
to_char(sum(decode(to_char(first_time,'HH24'),'05',1,0)),'99') "05",
to_char(sum(decode(to_char(first_time,'HH24'),'06',1,0)),'99') "06",
to_char(sum(decode(to_char(first_time,'HH24'),'07',1,0)),'99') "07",
to_char(sum(decode(to_char(first_time,'HH24'),'08',1,0)),'99') "0",
to_char(sum(decode(to_char(first_time,'HH24'),'09',1,0)),'99') "09",
to_char(sum(decode(to_char(first_time,'HH24'),'10',1,0)),'99') "10",
to_char(sum(decode(to_char(first_time,'HH24'),'11',1,0)),'99') "11",
to_char(sum(decode(to_char(first_time,'HH24'),'12',1,0)),'99') "12",
to_char(sum(decode(to_char(first_time,'HH24'),'13',1,0)),'99') "13",
to_char(sum(decode(to_char(first_time,'HH24'),'14',1,0)),'99') "14",
to_char(sum(decode(to_char(first_time,'HH24'),'15',1,0)),'99') "15",
to_char(sum(decode(to_char(first_time,'HH24'),'16',1,0)),'99') "16",
to_char(sum(decode(to_char(first_time,'HH24'),'17',1,0)),'99') "17",
to_char(sum(decode(to_char(first_time,'HH24'),'18',1,0)),'99') "18",
to_char(sum(decode(to_char(first_time,'HH24'),'19',1,0)),'99') "19",
to_char(sum(decode(to_char(first_time,'HH24'),'20',1,0)),'99') "20",
to_char(sum(decode(to_char(first_time,'HH24'),'21',1,0)),'99') "21",
to_char(sum(decode(to_char(first_time,'HH24'),'22',1,0)),'99') "22",
to_char(sum(decode(to_char(first_time,'HH24'),'23',1,0)),'99') "23"
from
v$log_history
GROUP by to_char(first_time,'YYYY-MON-DD');

Click here to learn about "Private Strand Flush Not Complete"  message in alert.log

Regards,
Satishbabu Gunukula, Oracle ACE
http://www.oracleracexpert.com