본문 바로가기

oracle

oracle redo log file


redo log file에 대한 잡담


made by 도익

DB에 장애가 발생하면 변경 기록들이 있어야 그 기록들을 근거로 도로 되돌리거나 고칠 수 있을 것이다.
그렇기에 DML문장이 수행되면 DML문장으로 데이터를 변경 하기 전, 우선 메모리의 어느 부분에 변경 할 것이라고 기록하게 된다. 이와같이 변경을 기록하는 메모리 영역을 redo log buffer라고 하며, 메모리(instance) 영역은 용량이 제한적이기 때문에 무한정 기록 할 수 없어서 checkpoint와 같은 어떤 이벤트를 발생 한다면 디스크에 내려 써서 저장 하게 된다. 이와 같은 일을 해 주는 백그라운드 프로세스가 LGWR이며, LGWR을 통해 디스크에 저장 된 파일을 redo log file이라 한다. 

이 redo log file은 오라클 상에서 두개 이상의 파일로 구성되며, 첫번째 파일을 다 쓸 경우, log switch가 발생하여 두번째 파일로 넘어가서 쓰게 된다. log switch가 발생할때 checkpoint가 발생하는데, 이와 같이 checkpoint가 발생하면 DB buffer cache에서 수행 된 문장들이 DBWR 백그라운드 프로세스를 통해 디스크에 기록된다. 그 후 CKPT 백그라운드 프로세스는 datafile과 control file에 SCN(system commit number)을 기록하여 이 번호를 통해 모든 작업을 동기화 시킨다. 만약 archive 모드로 운영된다면, log switch가 수행 된 순간 archive도 발생 할 것이다.

이와같은 SCN 기록작업이 어떤 연유로 필요 한 것일까?
만약 datafile이 손실 되었고, 백업본이 있어 이것으로 복구해야 한다고 가정하자.
우선 datafile의 백업본을 가지고 와야 될 것이다. 그 후 "복구해라" 명령이 떨어지면 control file에서 몇번 작업까지 수행했나 SCN번호를 통해(모두 번호가 같은지) 살필 것이다. 그 후 정말 그 번호까지 했나 datafile을 살필 것이고(물론 SCN번호가 다를 것이다. 백업본이기에) SCN번호가 다르기 때문에 redo log file에 기록된 모든 로그 기록을 보고 최근 번호까지 수행된 모든 변경된 로그를 보고 업데이트 할 것이다. 그 후 log번호를 초기화하고(resetlog) DB를 open하면 될 것이다.

Redo log file에는 3가지 상태가 있다.
첫번째 상태는 CURRENT이며 현재 쓰고 있는 redo log file을 말한다.
두번째 상태는 ACTIVE이며 다쓰거나, log switch가 발생하여 쓰는 log file이 바뀌었는데 아직 예전 로그파일에 기록된 내용이 DB buffer cache에서 datafile에 저장되지 않은 상태를 말한다.
세번째 상태는 INACTIVE이다. 이 상태는 활성화된 log file이 바뀌었고, 그 log file의 내용이 DB buffer cache에서 datafile에 저장 완료 된 상태를 말한다.
current상태에서 inactive상태로 바로 가게 할 수는 없고, 반드시 active상태를 거친 후 가야 한다.
active상태에 있는 log file들이 모두 inactive 상태로 바꾸고 싶다면, 사용자가 강제 checkpoint를 발생 시키면 될 것이다.

만약 redo log file을 삭제 할 일이 생긴다면, log switch와 강제 checkpoint를 수행해서 반드시 inactive상태로 변경해야 삭제를 수행할 수 있다.

그리고 리두로그 그룹에는 손상을 대비하여 같은 log기록 파일을 남기는 member파일을 둘 수 있다.
지금부터 필자는 redo log file 손상을 대비하여 3개의 그룹과 각그룹의 멤버파일을 하나씩 두어 3*2의 리두로그 파일을 구성 할 것이다(/app/oracle/testdb/ 디렉토리에 저장 할 것이다)

우선 필자의 컴퓨터에 redo log file의 그룹 수와 용량, sequence번호, 현재 상태 등을 알아보겠다.

SQL> select a.group#, a.member, b.bytes/1024/1024 mb, b.sequence#, b.archived, b.status
from v$logfile a, v$log b
where a.group# = b.group#
order by 1,2;



이와같이 3개의 그룹이 있다. 모든 리두로그 그룹을 다시 만들기 위하여 이 3개는 삭제 할 것이고, 그룹 1번부터 다시 생성 할 것이다. 우선 이 3개를 삭제 하기 위해 그룹 4, 그룹 5를 만들어 주자(리두로그 파일은 무조건 2개 이상 있어야 한다. 그렇기 때문에 그룹 4,5번을 만들어 준 후, 1,2,3번 그룹을 삭제 할 것이다.)


리두로그 그룹 두개를 추가 해주었다. 다음과 같이 추가되었음을 알 수 있다.


이제 로그 기록은 4,5번 그룹에 잠시 맡기고 1,2,3번 그룹을 삭제해 준다.
앞에도 언급했듯이 리두로그 파일은 inactive상태에서만 지워 줄 수 있다. 그러므로 필자는 log switch를 여러번 발생시키고 강제 checkpoint를 발생시켜 DB buffer cache의 내용을 다 disk로 내려 쓰고 inactive 상태로 만들것이다.

SQL>alter system switch logfile; (여러번)
SQL>alter system checkpoint;



 이제 1,2,3번 그룹을 지우자.

SQL> alter database drop logfile group 1;
SQL> alter database drop logfile group 2;
SQL> alter database drop logfile group 3;


이제 4,5번 그룹만 남음을 확인 한다.


이제 redo log group을 생성한다. 1,2,3번 group를 추가해준다(디렉토리는 /app/oracle/testdb/ 으로 지정 할 것이다).

SQL> !mkdir -p /app/oracle/testdb/redo (디렉토리 생성)
SQL> alter database add logfile group 1
'/app/oracle/testdb/redo01.log' size 10m;
SQL> alter database add logfile group 2
'/app/oracle/testdb/redo02.log' size 10m;
SQL> alter database add logfile group 3
'/app/oracle/testdb/redo03.log' size 10m;


추가되었음을 확인한다.


이제 임시로 만들었던 4,5번 그룹을 삭제한 후, 각 리두로그 파일의 멤버를 만들도록 한다. 우선 삭제하자.
(역시 로그스위치와 체크포인트 수행을 통해 inactive 상태로 만들어야 한다)

SQL>alter database drop logfile group 4;

SQL>alter database drop logfile group 5;


이제 각 그룹의 멤버 파일을 추가 해 보자. 멤버의 디렉토리는 /app/oracle/testdb/redomember 로 하겠다.


SQL> !mkdir -p /app/oracle/testdb/redomember (디렉토리 생성)
SQL> alter database add logfile member
'/app/oracle/testdb/redomember/redo01_a.log' to group 1,
'/app/oracle/testdb/redomember/redo02_a.log' to group 2,
'/app/oracle/testdb/redomember/redo03_a.log' to group 3;


마지막으로 멤버 파일이 잘 추가 되었나 확인 해 보자.

SQL> select a.group#, a.member, b.bytes/1024/1024 mb, b.sequence#, b.archived, b.status
from v$logfile a, v$log b
where a.group# = b.group#
order by 1,2;


다음과 같이 각 그룹에 멤버 하나씩 더 추가 되었음을 확인 할 수 있다. 이와 같은 멤버 파일은 원래 파일과 같은 데이터가 기록되게 되며, 만약 원래 파일에 손상이 있을 경우 이 멤버 파일을 이용, 손쉽게 대처 할 수 있다.


Copyright 김도익 All rights reserved.