행위

Redo

DB CAFE

Dbcafe (토론 | 기여)님의 2024년 4월 17일 (수) 18:29 판 (Redo Log File 구성 및 관리하기)
thumb_up 추천메뉴 바로가기


1 REDO[편집]

  • Redo : Re(다시) do(한다), Recovery
    • Redo Log : 변경되는 내용이 있을 때 모두 기록해 두었다가 장애를 대비하는 기능
  • Undo : Un(취소) do(한다), Rollback
    • Undo TableSpace: Rollback을 위한 임시 테이블 스페이스



1.1 Redo Log의 생성 원리[편집]

  • Oracle에서 데이터의 변경(DDL, DML, TCL등)이 발생했다면 두 매커니즘에 의해 Rodo Log에 기록됨

1.1.1 Write Log Ahead[편집]

  • 실제 데이터를 변경하기 전에 Redo Log에 먼저 기록한 후 데이터를 변경
    (DBWR이 작동하기 전에 LGWR이 작동하는 것도 이것과 같은 의미)

1.1.2 Log force at Commit[편집]

  • 사용자로부터 Commit 요청이 들어오면 관련된 모든 Redo Record들은 Redo Log file에 저장한 후 Commit을 완료.
    (Redo Log File에 기록하지 않고는 Commit을 완료하지 않는다)
  • 대량의 데이터 변경 후 Commit이 한꺼번에 수행되면 Delayed Commit(지연된 커밋), Group Commit 발생

- Group Commit : Commit을 아주 짧은 시간 동안 모아서 한꺼번에 수행하는 기술 - 짧은 시간동안 많은 데이터가 변경된 후 한꺼번에 Commit 요청이 들어올 경우 발생

1.2 Redo log가 생성되고 기록되는 원리[편집]

image.jpg

1.2.1 Redo Log 기록 원리[편집]

  1. 사용자가 특정 데이터를 변경하는 쿼리 수행 시에 해당 SQL을 받은 서버 프로세스는 원하는 Block이 Database Buffer Cache에 있는지 확인 한 후 없으면 해당 블록을 데이터 파일에서 찾아서 복사한 후 Buffer Cache로 가져옴. 그리고 해당 row부분을 다른 사용자가 바꿀 수 없도록 Lock를 설정(page fix) 후 PGA에 Redo Change Vector를 생성함.
    - Change Vector : Redo Log에 기록할 변경된 데이터에 대한 모든 정보의 세트(복구 목적)
    - Redo Log는 Commit된 데이터를 복구할 때도 사용 되지만 Rollback 데이터를 복구할 때도 사용함.
     : 사용자가 커밋(commit)을 수행하고 Checkpoint 발생 전에 DB가 강제 종료 되었다면 해당 데이터를 Roll Forwared 하는 내용도 저장해야 하지만
    사용자가 Rollback한 후 아직 Rollback이 완전히 완료되지 않은 상태에서 DB가 강제 종료 되었을 경우에도 Rollback 되지 못한 데이터 전부를 Rollback 해줘야 한다.
    • 그래서, Change Vector내에 Undo 관련 내용까지 함께 저장된다.
    • PGA에 만들어진 Change Vector는 Redo Record Format으로 Row단위로 Redo Log Buffer에 복사됨
  2. (PGA에서 Change Vector 생성 후 ) Redo Log Buffer에서 필요한 용량을 계산, Latch 획득 (Change Vector를 Redo Log Buffer에 복사하기 위함)
    - Latch(래치) : 한정된 메모리 자원을 여러 사용자가 사용할 때 사용할 수 있는 순서를 정해주는 역할
    - Rodo Log Buffer에 내용을 쓰려면 두 가지 Latch를 확보해야 한다.
    1) Redo Copy Latch
    - Redo Copy Latch : Change Vector가 모두 Redo Log Buffer에 기록될 때가지 계속 가지고 있어야 하기 때문에 여러개의 Latch가 존재한다.
    2) Redo Allocation Latch

1.3 Redo Copy Latch 현황 조회 (11g)[편집]

SELECT name, gets, misses, immediate_gets, wait_time
  FROM v$latch_children
  where name='redo copy' ;


        NAME            GETS         MISSES       IMMEDIATE_GETS   WAIT_TIME
--------------- ------------ ------------ --------------------- ------------
redo copy                 6                 0                             0                   0
redo copy                 6                 0                         6707                   0
  • CPU 개수가 1개일 경우, 기본적으로 2개의 Redo Copy Latch가 조회됨
  • _log_simultaneous_copies 히든 파라미터를 이용해 개수 조정 가능.
  • Latch의 개수를 늘리는 것이 무조건 성능에 좋은 것은 아니다. (예시_은행에 고객이 많이 몰릴 때 번호표 뽑는 기계를 많이 가져다 놓는 것은 의미가 없기 때문에)
  • Latch 때문에 문제가 생기는 것인지 Redo Log Buffer나 File 자체에 문제가 있는지 확인 후 조치 필요

1.3.1 Redo Allocation Latch[편집]

  • Redo Copy Latch를 확보한 서버 프로세스는 Redo Allocation Latch를 확보한다
  • Redo Allocation Latch는 1개만 존재 (Redo Copy Latch는 여러개 존재)
    - 9i부터는 Redo Log Buffer를 여러개 공간으로 나누어서 각 공간별로 Redo Allocation Latch를 할당해주는 Shared Redo Strand 기능이 도입됨
    즉, 하나의 Redo Log Buffer를 디스크의 파티션과 같이 여러 개로 나누어 여러 서버 프로세스가 동시에 작업하게 하여 성능을 높임 (LOG_PARALLELISM 파라미터 값으로 설정)
    - Shared Rodo Strand 기능과 관련해 중요한 것은 Redo Log Buffer를 몇 개로 나누는가 인데 10g 부터는 LOG_PARALLELISM 파라미터가 _LOG_PARALLELISM 히든 파라미터로 변경되 이 값은 Oracle이 동적으로 관리하도록 _LOG_PARALLELIS_DYNAMIC 파라미터가 추가됨
  • _LOG_PARALLELISM_DYNAMIC 값이 True일 경우 Oracle이 해당 Strand 개수를 자동으로 제어
    - 이 파라미터에 대한 Oracle 권장 값은 CPU 개수 / 8
1.3.1.1 Redo Allocation Latch의 개수 조회 (11g)[편집]
SELECT COUNT(*)
  FROM V$latch_children
 WHERE NAME='redo allocation' ;

  COUNT(*)
  ------------
       28
  • 10g부터는 Shared Redo Strand 보다 더 확장된 개념인 Private Redo Strand 기능이 도입
  • 각 서버 프로세스가 Shared pool에 자신만의 독립적인 Privete Strand 공간을 만들어서 그곳에 Change Vector를 생성한 후 필요한 경우 LGWR이 Redo Log File에 바로 기록함
    Latch를 확보해서 Redo Log Buffer에 기록해야 하는 과정을 줄임으로써 성능 향상시킴. Zero Copy Redo 라고 부름.

1.3.2 [편집]

④ Redo Log Buffer에 기록된 내용들(Redo Entry)은 특정 상황이 되면 LGWR이 일부를 Redo Log File에 기록한 후
    기록 된 Redo Entries들을 Redo Log Buffer에서 삭제(Flush)
   ⇒ 어떤 Server Process가 특정 상황이 되면 Redo Writing Latch를 확보 한 후 LGWR에게 Redo Log Buffer에 있는
       내용을 Redo Log File에 기록하라고 요청


  ⅰ) 3초 마다
     * LGWR 프로세스는 할 일이 없을 경우 Sleep 상태로 있다가 rdbms ipc message라는 대기이벤트의 time out이 되는
       시점인 3초마다 Wake up을 해서 Redo Log Buffer에서 Redo Log File에 기록해야 할 내용이 있는지를 확인하여
       기록 후 해당 내용을 삭제(Flush)


  ⅱ) Redo Log Buffer 전체 크기의 1/3이 찼거나 1M가 넘을 경우
     * 서버 프로세스는 Redo Log Buffer를 할당 받을 때 마다 현재 사용된 log buffer의 Block 수를 계산
     * 사용된 Log Buffer의 Block 수가 _LOG_IO_SIZE의 값보다 많을 경우 LGWR에게 기록을 요청
     * _LOG_IO_SIZE 파라미터는 Redo Log File로 내려 쓸 임계값을 지정하는 파라미터
       ( 이 값을 512KB로 설정하면 변경사항이 512KB가 될 때 LGWR이 작동)
     * 9i – Redo Log Buffer의 1/3   10g – 1/6


  ⅲ) 사용자가 Commit 또는 Rollback을 수행할 때
     * 사용자가 Commit이나 Rollback을 수행하게 되면(즉, 트랜잭션을 종료하게 되면) 내부적 관리번호인 SCN이
       생성되어 해당 트랜잭션에 할당되고 관리된다.


  ⅳ) DBWR이 LGWR에게 쓰기를 요청할 때
     * Oracle 8i부터는 DBWR이 LGWR의 on-disk RBA 값보다 큰 high-RBA 값을 가진 Block을 데이터 파일로
       기록해야 할 때 해당 Block을 Differed Write Queue에 먼저 기록한 후 LGWR 프로세스를 먼저 수행시켜
       해당 Redo Log를 먼저 내려쓰게 만든 후 Data Block을 기록하는 방식으로 Sync를 맞춘다.


  * LGWR이 Redo Log Buffer의 내용을 Redo Log File로 내려 쓸 때 Block 단위로 내려쓴다.(=DBWR)
  * DBWR과는 달리 LGWR의 Block 크기는 OS_BLOCK_SIZE 크기에 따라 결정되며 OS에 따라 다를 수 있다.
    (DBWR은 DB_BLOCK_SIZE에 따라 Block Size 결정)



▣ Redo Log Block Size 조회 (11g)

SQL> SELECT max(lebsz) FROM sys.x$kccle;

MAX(LEBSZ)
---------------
       512


  * 모든 변경사항이 Redo Log에 기록되는 것은 아님
    예를 들어, Direct Load(SQL Loader, Insert /* APPEND */)나 Table, Index 생성시 NOLOGGING 옵션을 주는 경우
     Redo Log에 기록되지 않는다.
  * 단, NOLOGGING 옵션으로 테이블을 생성되었더라도 일반적인 Insert, Update, Delete는 Redo Log에 기록됨

1.4 Redo Log File 구성 및 관리하기[편집]

(1) Redo Log Buffer와 Redo Log File image.png

  1. 데이터가 변경되면 데이터의 안전한 복구를 위해서 Redo Log Buffer에 먼저 기록한 후 실제 데이터를 변경
    - Redo Log Buffer 에서 여러 가지 조건이 발생하게 되면 Redo Writing Latch를 획득한 Server Process가 LGWR에게 Redo Log Buffer의 내용을 Redo Log File로 기록 요청
    - LGWR이 내려쓴 내용은 Redo Log Buffer에서 지워 새로운 공간을 확보
  2. Log Switch가 발생하게 되면 Checkpoint 신호가 발생
    - Log Switch : LGWR이 Redo Log Buffer에 내용을 Redo Log File에 내려 쓰다가 해당 파일이 가득 차게 되면 다음 그룹으로 자동으로 넘어가는 것
    ⇒ DBWR이 해당 로그 파일에 있는 내용 중 Buffer Cache에서 데이터파일로 저장되지 못한 변경사항들을 내려씀.
    ⇒ 이 정보들을 데이터파일과 컨트롤 파일에 반영됨
  3. Log Switch가 일어나는 그룹의 순서는 Oracle이 라운드로빈 방식으로 알아서 결정
    (=1번 그룹 다음에 2번 그룹이고 그 다음에 3번그룹이 아닐 수도 있다라는 의미)
  • LGWR은 Redo Log File의 그룹에 멤버가 여러 개일 경우 같은 그룹안의 멤버들끼리는 서로 저장하고 있는 내용과 크기가 동일(병렬로 동시에 같은 내용 기록)
    그러나 만약 같은 디스크에 있으면 직렬로 기록(=하나 기록하고 끝나면 다른 하나를 기록)


notifications_active 리두로그 그룹 과 멤버 (오라클 권장값)
  • Redo Log File은 그룹과 멤버라는 개념으로 관리됨
  • 같은 그룹일 경우 멤버들은 같은 내용을 담고 있어서 만약 하나의 멤버가 삭제되거나 장애가 발생해도 다른 멤버가 하나 더 존재하기 때문에 안전하게 관리할 수 있음
  • 멤버를 더 추가 할 수 있지만 기록시간이 늘어나기 때문에 부하를 줄 수 있음
  • 같은 그룹의 멤버는 절대 동일한 디스크에 함께 두는 것을 권장하지 않음
  • 오라클에서 최소 그릅의 개수는 2개이며 각 그룹별로 필요한 최소 멤버는 1개
  • 오라클 권장 구성 개수 : 최소 그룹 3개, 그룹별 최소 2개 이상의 멤버

notifications_active 리두로그 기록시 에러가 발생될 경우
  1. 병렬쓰기 도중에 Redo Log File이 삭제되거나 Block에 문제가 발생할 경우에는 LGWR은 각 오픈 로그 멤버의 상태를 조사해서 어떤 파일이 에러가 발생되는지 알아냄
  2. 장애가 난 멤버는 Control File 안에 STALE 상태로 기록, LGWR은 백그라운드 Trace File에 ORA-00346 에러 기록
    - STALE 상태 : 해당 로그 파일이 문제가 있다는 것을 의미
  3. LGWR이 하나의 로그 파일에서 4개 이상의 에러를 만나게 되면 로그 파일을 닫고 더 이상 그 파일에 내용을 기록하지 않음
  4. 만약 LGWR이 어떤 로그파일에도 내용을 기록할 수 없다면 ORA-00340 에러를 발생시키고 Shutdown abort로 강제 종료되고 Startup 되지 않는다.

notifications_active 리두로그 성능 개선/조치 사항
  1. Redo Log File 크기는 각 서버의 실정에 맞게 사용해야 함(=권장 크기는 정해져 있지 않음)
    - 크기가 너무 작게 되면 Log Switch가 자주 발생 ⇒ 성능 저하
    - 크기가 너무 크면 데이터의 손상 가능성이 커짐
  2. Alert Log File에 Checkpoint Not Completed. 라는 메시지가 나오면 멤버크기를 크게 만들거나 그룹을 더 만들어주어야 함.
  • Checkpoint Not Completed 라는 메시지는 Log Switch가 너무 빈번하게 일어날 경우
    DBWR이 이전에 발생한 Checkpoint 내용을 Data File에 다 기록하지 못한 상태에서 다시 Log Switch 신호가 들어올 경우에 주로 발생함.
  • 즉, Redo Log File의 크기가 작을 경우 잦은 Log Switch가 발생할 것이므로 이 메시지가 자주 보일 것이며,
    이럴 경우 Redo Log File의 크기나 Redo Log Group의 수를 증가시켜 주어야 한다.

1.5 Redo Log File 관리 (11g 기준)[편집]

1. 신규 Group 생성 (신규 그룹 4번으로 지정)

SQL> alter database add logfile group 4
    '/app/oracle/oradata/testdb/redo04_a.log' size 5M ;

2. Member 추가

SQL> alter database add logfile member
    '/app/oracle/oradata/testdb/redo04_b.log' to group 4 ;

3. Member 삭제

SQL> alter database drop logfile member
    '/app/oracle/oradata/testdb/redo04_b.log' ;


4. Group 삭제

SQL> alter database drop logfile group 4;


5. 강제로 Log Switch 발생시키기

SQL> alter system switch logfile;


6. 강제로 Checkpoint 발생

SQL> alter system checkpoint;
  • ASM이 아닌 일반 OS파일 시스템으로 Oracle을 설치하였다면 3, 4번에 있는 삭제 과정을 수행해도 실제 해당 파일은 지워지지 않음.(11G기준,ASM 기반에서는 지울 수 있음)
  • 파일 시스템이 경우에 위 명령어들을 수행하고 난 뒤 반드시 DBA가 직접 OS 명령어로 해당 파일을 직접 지워야 함(11G기준,다른 그룹이나 멤버를 지우지 않도록 각별히 조심!)
  • Redo Log File의 상태 :
    - CURRENT : 현재 LGWR이 내용을 기록하고 있는 상태
    - ACTIVE : Redo Log File의 내용이 아직 DB Buffer Cache에서 Data File로 저장 되지 않아 지워지면 안되는 상태
    - INACTIVE : Redo Log file의 내용이 데이터 파일에도 다 저장되어서 삭제되어도 되는 상태
  • DBA가 어떤 필요에 의해 Redo Log File을 삭제하고 싶다면 반드시 INACTIVE 상태로 만들고 3, 4번 명령어로 삭제 수행.
  • 주의 사항 : Redo Log File을 삭제할 때 절대 OS 명령어로 먼저 삭제하면 안됨!!

1.6 Redo Log File 관리 실습 예제[편집]

1.6.1 현재 상태 확인하기[편집]

SQL> !vi log.sql

set line 200
col group# for 999
col mb for 999
col member for a45
col seq# for 999
col status for a8
col arc for a5

SELECT a.group#, a.member, b.bytes/1024/1024 MB, b.sequence# "SEQ#", b.status, b.archived "ARC"
  FROM v$logfile a, v$log b
 WHERE a.group#=b.group#
 ORDER BY 1,2
/
:wq
SQL> @log

GROUP# MEMBER                                     MB SEQ# STATUS  ARC
-------- ------------------------------------------------------- ---- ---- ----------- -----
     1  /app/oracle/oradata/testdb/redo01.log           50   31 INACTIVE  NO
     2  /app/oracle/oradata/testdb/redo02.log           50   32 INACTIVE  NO
     3  /app/oracle/oradata/testdb/redo03.log           50   33 CURRENT  NO


1.6.2 신규 그룹(4번 그룹) / 멤버 추가 하기[편집]

alter database add logfile group 4
    '/app/oracle/oradata/testdb/redo04_a.log' size 5M ;
  • RAC 환경(ASM)
- RAC#1
ALTER DATABASE ADD LOGFILE THREAD 1
GROUP 1 ('+REDO/db_name/redo__t1_01a.log','+REDO/db_name/redo__t1_01b.log') SIZE 100m,
GROUP 2 ('+REDO/db_name/redo__t1_02a.log','+REDO/db_name/redo__t1_02b.log') SIZE 100m,
GROUP 3 ('+REDO/db_name/redo__t1_03a.log','+REDO/db_name/redo__t1_03b.log') SIZE 100m,
GROUP 4 ('+REDO/db_name/redo__t1_04a.log','+REDO/db_name/redo__t1_04b.log') SIZE 100m;
- RAC#2
ALTER DATABASE ADD LOGFILE THREAD 2
GROUP 5 ('+REDO/db_name/redo__t2_5a.log','+REDO/db_name/redo__t2_5b.log') SIZE 100m,
GROUP 6 ('+REDO/db_name/redo__t2_6a.log','+REDO/db_name/redo__t2_6b.log') SIZE 100m,
GROUP 7 ('+REDO/db_name/redo__t2_7a.log','+REDO/db_name/redo__t2_7b.log') SIZE 100m,
GROUP 8 ('+REDO/db_name/redo__t2_8a.log','+REDO/db_name/redo__t2_8b.log') SIZE 100m;
SQL> @log 
GROUP# MEMBER                                     MB SEQ# STATUS  ARC
-------- ------------------------------------------------------- ---- ---- ----------- -----
     1  /app/oracle/oradata/testdb/redo01.log           50   31 INACTIVE  NO
     2  /app/oracle/oradata/testdb/redo02.log           50   32 INACTIVE  NO
     3  /app/oracle/oradata/testdb/redo03.log           50   33 CURRENT  NO
     4  /app/oracle/oradata/testdb/redo04_a.log          5    0 UNUSED   YES
SQL> alter database add logfile member
  2  '/app/oracle/oradata/testdb/redo04_b.log' to group 4 ;
Database altered.
SQL> @log 

GROUP# MEMBER                                     MB SEQ# STATUS  ARC
-------- ------------------------------------------------------- ---- ---- ----------- -----
     1  /app/oracle/oradata/testdb/redo01.log           50   31 INACTIVE  NO
     2  /app/oracle/oradata/testdb/redo02.log           50   32 INACTIVE  NO
     3  /app/oracle/oradata/testdb/redo03.log           50   33 CURRENT  NO
     4  /app/oracle/oradata/testdb/redo04_a.log          5    0 UNUSED   YES
     4  /app/oracle/oradata/testdb/redo04_b.log          5    0 UNUSED   YES
SQL> alter system switch logfile;
System altered.
SQL> @log 

GROUP# MEMBER                                     MB SEQ# STATUS  ARC
-------- ------------------------------------------------------- ---- ---- ----------- -----
     1  /app/oracle/oradata/testdb/redo01.log           50   31 INACTIVE  NO
     2  /app/oracle/oradata/testdb/redo02.log           50   32 INACTIVE  NO
     3  /app/oracle/oradata/testdb/redo03.log           50   33 ACTIVE    NO
     4  /app/oracle/oradata/testdb/redo04_a.log          5   34 CURRENT  NO
     4  /app/oracle/oradata/testdb/redo04_b.log          5   34 CURRENT  NO
SQL> alter system checkpoint;

System altered.
SQL> @log


GROUP# MEMBER                                     MB SEQ# STATUS  ARC
-------- ------------------------------------------------------- ---- ---- ----------- -----
     1  /app/oracle/oradata/testdb/redo01.log           50   31 INACTIVE  NO
     2  /app/oracle/oradata/testdb/redo02.log           50   32 INACTIVE  NO
     3  /app/oracle/oradata/testdb/redo03.log           50   33 INACTIVE  NO
     4  /app/oracle/oradata/testdb/redo04_a.log          5   34 CURRENT  NO
     4  /app/oracle/oradata/testdb/redo04_b.log          5   34 CURRENT  NO

※ Alter system checkpoint 명령어로 3번 그룹이 Active → Inactive로 변경됨

1.6.3 기존 멤버 삭제 / 그룹 삭제 하기 (4번 그룹 삭제)[편집]

SQL> @log

GROUP# MEMBER                                     MB SEQ# STATUS  ARC
-------- ------------------------------------------------------- ---- ---- ----------- -----
     1  /app/oracle/oradata/testdb/redo01.log           50   31 INACTIVE  NO
     2  /app/oracle/oradata/testdb/redo02.log           50   32 INACTIVE  NO
     3  /app/oracle/oradata/testdb/redo03.log           50   33 INACTIVE  NO
     4  /app/oracle/oradata/testdb/redo04_a.log          5   34 CURRENT  NO
     4  /app/oracle/oradata/testdb/redo04_b.log          5   34 CURRENT  NO


alter system switch logfile;
System altered.


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

GROUP# MEMBER                                     MB ARC  STATUS
-------- ------------------------------------------------------- ---- ---- ------------
     1  /app/oracle/oradata/testdb/redo01.log           50  NO  CURRENT
     2  /app/oracle/oradata/testdb/redo02.log           50  NO  INACTIVE
     3  /app/oracle/oradata/testdb/redo03.log           50  NO  INACTIVE
     4  /app/oracle/oradata/testdb/redo04_a.log          5  NO  ACTIVE
     4  /app/oracle/oradata/testdb/redo04_b.log          5  NO  ACTIVE


SQL> alter system checkpoint;

System altered.
select a.group#,b.thread#, a.member, b.bytes/1024/1024 MB, b.archived, b.status
  from v$logfile a, v$log b
 where a.group#=b.group#
 order by 1,2 ;

GROUP# MEMBER                                     MB ARC  STATUS
-------- ------------------------------------------------------- ---- ---- ------------
     1  /app/oracle/oradata/testdb/redo01.log           50 NO  CURRENT
     2  /app/oracle/oradata/testdb/redo02.log           50 NO  INACTIVE
     3  /app/oracle/oradata/testdb/redo03.log           50 NO  INACTIVE
     4  /app/oracle/oradata/testdb/redo04_a.log          5 NO  INACTIVE
     4  /app/oracle/oradata/testdb/redo04_b.log          5 NO  INACTIVE
  • 그룹삭제
SQL> Alter database drop logfile group 1;
  • 멤버 삭제
SQL> alter database drop logfile member '/app/oracle/oradata/testdb/redo04_b.log' ;
Database altered.
  • ASM환경에서 그룹 삭제
$ sqlplus " /as sysasm"

SQL> ALTER DISKGROUP REDO DROP FILE '+REDO/db_name/redo02a.log';
SQL> ALTER DISKGROUP REDO DROP FILE '+REDO/db_name/redo01a.log';
SQL> ALTER DISKGROUP REDO DROP FILE '+REDO/db_name/redo03a.log';
SQL> ALTER DISKGROUP REDO DROP FILE '+REDO/db_name/redo04a.log';
SQL> Alter database drop logfile group 1;

 
<source lang=sql>
SQL> !ls /app/oracle/oradata/testdb/redo04_b.log 
/app/oracle/oradata/testdb/redo04_b.log                     ← 여전히 파일이 남아 있음
SQL> !rm –rf /app/oracle/oradata/testdb/redo04_b.log        ← 수동으로 삭제
SQL> !ls /app/oracle/oradata/testdb/redo04_b.log 
ls: /app/oracle/oradata/testdb/redo04_b.log: No such file or directory


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

 

GROUP# MEMBER                                     MB ARC  STATUS
-------- ------------------------------------------------------- ---- ---- ------------
     1  /app/oracle/oradata/testdb/redo01.log           50 NO  CURRENT
     2  /app/oracle/oradata/testdb/redo02.log           50 NO  INACTIVE
     3  /app/oracle/oradata/testdb/redo03.log           50 NO  INACTIVE
     4  /app/oracle/oradata/testdb/redo04_a.log          5 NO  INACTIVE


SQL> alter database drop logfile member '/app/oracle/oradata/testdb/redo04_a.log' ;
alter database drop logfile member '/app/oracle/oradata/testdb/redo04_a.log'
*
ERROR at line 1:
ORA-00361: cannot remove last log member /app/oracle/oradata/testdb/redo04_a.log for group 4

← 그룹에 member가 1개일 경우 member는 삭제가 안되며 그룹을 지워야 한다.

SQL> alter database drop logfile group 4;
Database altered.
SQL> select a.group#, a.member, b.bytes/1024/1024 MB, b.archived, b.status
  2  from v$logfile a, v$log b
  3  where a.group#=b.group#
  4  order by 1,2 ;

GROUP# MEMBER                                          MB ARC STATUS
------ --------------------------------------------- ---- --- --------
     1 /app/oracle/oradata/testdb/redo01.log           50 NO  CURRENT
     2 /app/oracle/oradata/testdb/redo02.log           50 NO  INACTIVE
     3 /app/oracle/oradata/testdb/redo03.log           50 NO  INACTIVE
SQL> !ls /app/oracle/oradata/testdb/redo04_a.log
/app/oracle/oradata/testdb/redo04_a.log                    ← 여전히 파일이 남아 있음
SQL> !rm –rf /app/oracle/oradata/testdb/redo04_a.log       ← 수동으로 삭제
SQL> !ls /app/oracle/oradata/testdb/redo04_a.log
ls: /app/oracle/oradata/testdb/redo04_a.log: No such file or directory


1.7 심화학습, SCN과 Checkpoint[편집]

  • 사용자가 Commit을 하게 되면 Oracle 내부적으로 SCN 번호를 생성해서 트랜잭션을 관리
(1) SCN(System Commit Number)
  - SCN : Commit 할 때 생성되는 번호, 트랜잭션을 관리하며 장애 발생 시 복구도 함
  * Commit이 발생 할 때마다 모든 트랜잭션에 고유한 SCN 번호가 부여됨 (트랜잭션 단위로 할당)
  * SCN = SCN base(4bytes) + SCN Wrap(2bytes)
  * SCN base 값이 전부 다 사용되면 SCN Wrap 값이 하나씩 증가되어 사용하게 됨
  * 만약 이 SCN이 모두 다 사용되면 다시 0으로 reset 된 후 새로운 Incarnation으로 할당되어 다시 시작
  * SCN은 Sequence에서 발생시키는 것이 아니라 Steve adams가 개발한 ‘Kcmgas’라는 Function으로 구현



 ▣ SNC이 기록되는 곳
  * Control File Header ┌ Checkpoint 발생 할 때
                                 ├ Resetlogs 발생 할 때
                                 └ Incomplete Recovery 수행 때


  * Data Blocks(Cache Layer) - Block Cleanout 시 마지막 SCN을 각 Block에 기록
  * Data Blocks(ITL Entries) - Data Block의 Transaction Layer 안에 있는 ITL(Interested Transaction List) Entries 안에
                                          Commit 된 SCN 정보를 기록(Delayed Block Cleanout).
  * Data File Headers(모든 데이터 파일 헤더에 기록) ┌ 마지막 Checkpoint 발생 때
                                                                         ├ Begin Backup 수행 때
                                                                         └ 복구가 되었다면 사용된 마지막 SCN을 기록
  * Redo Records / Log Buffer – Commit이 수행되면 Commit Records에 SCN을 포함하여 저장
  * 그 외 Rollback Segment(Undo Segment)와 Tablespace Headers에도 기록



  ▣ Commit과 관련된 파라미터(10g 기준)



SQL> show parameter commit;

                       NAME                             TYPE           VALUE
------------------------------------- ----------- -----------------
commit_point_strength                               integer           1
commit_waite                                           string
max_commit_propagation_delay                  integer           0



  - commit_point_strength : 분산 데이터베이스 환경에서 2-Phase Commit에 사용합니다.
  - commit_write : 사용자가 commit을 하게 되면 LGWR이 해당 트랜잭션을 Redo Log File에 기록하게 됩니다.
                         이 내용과 관련된 4가지 방식이 있는데 이 4가지 방식 중 어떤 것을 사용하는지를 결정하는 파라미터


     ① WAIT(동기식) : 변경된 트랜잭션이 Redo Log File에 기록될 때까지 기다림
     ② NOWAIT(비동기식) : WAIT과 반대로 Redo Log File에 기록될 때까지 기다리지 않음
     ③ IMMEDIATE : Commit 요청이 들어오면 즉시 Redo Log File에 기록하기 시작
     ④ BATCH : Commit 요청이 들어오더라도 일정 시간 동안 모아서 한꺼번에 기록
  
  * 일반적으로 위 4가지 방법은 2개씩 조합해서 사용
    ex)┌ IMMEDIATE+WAIT
         │ : Commit이 수행되면 즉시 Redo Log File에 기록을 요청하고 기록이 다 될 때까지 기다림
         └ IMMEDIATE+NOWAIT
             : Commit이 수행되면 즉시 Redo Log File에 기록을 요청만 하고 사용자에게 제어권을 넘겨 다른 작업을
               진행 할 수 있도록 함


  * 비동기식 커밋(Asynchronous Commit) : BATCH나 NOWAIT 같이 Redo Log File의 내용이 아직 Redo  Log File에
     기록이 완료되지 않아도 다른 작업을 할 수 있도록 성능을 높이는 방식



▣ Commit 관련된 파라미터 (11g)



SQL> show parameter commit;


                   NAME                                 TYPE                     VALUE
------------------------------------ ----------- ------------------------------
commit_logging                                      string
commit_point_strength                             integer                         1
commit_wait                                           string
commit_write                                          string
SQL> alter system set commit_logging = immediate ;
System altered.
SQL> alter system set commit_wait = nowait ;
System altered.
SQL> alter system set commit_write = immediate, nowait;
System altered.
SQL>  show parameter commit ;


                   NAME                                 TYPE                     VALUE
------------------------------------ ----------- ------------------------------
commit_logging                                      string              IMMEDIATE
commit_point_strength                             integer            1
commit_wait                                           string             NOWAIT
commit_write                                          string             IMMEDIATE, NOWAIT




  - max_commit_propagation_delay : (RAC 환경으로 가정하고 설명)
    만약 홍길동이라는 데이터를 양쪽 노드에서 다 호출한 후 node 1에서 일지매로 업데이트 한 후에 commit 하고
    commit과 거의 동시에 node2에서 누군가 홍길동 정보를 조회했다고 가정하면 분명히 node 1에서 홍길동 정보를
    일지매로 변경 후에 Commit 했기 때문에 node 2에서는 홍길동이 아닌 일지매로 보여야 할 것이다.
    그러나 아직 node 1에서 commit 된 정보가 node 2에 도달하지 않으면 node 2에서는 잘못된 정보를 볼 수 있는
    문제가 발생
    ⇒ Oracle 에서는 node 1에서 발생한 정보를 node 2에 전송할 때 Piggyback이란 방식으로 전송


  - Piggyback : Commit이 발생하면 즉시 보내는 것이 아니라 다른 메시지가 갈 때 함께 업혀서 가는 방식
    ⇒ 메시지 발생양은 작고 트래픽 양은 작은 장점이 있으나 틀린 내용을 조회할 수 있다는 단점
        → max_commit_propagation_delay 파라미터를 사용해서 전송시간을 제어 함


    ※ 10g부터는 이 파라미터의 기본 값이 0으로 설정되어 무조건 commit을 하자마자 전송을 하도록 설정
       (이러한 방식을 Broadcast On Commit, BOC 방식이라고 함)




(2) System Change Number
 : Data File, Redo Log File, Control File 간의 동기화 정보를 맞추기 위해 사용


  * SCN = SCN_Base(4bytes) + SCN_Wrap(2bytes) + SCN_Sequence(1bytes)
  * Sequence는 동일한 SCN Block을 여러 개의 Server Process가 동시에 변경할 경우에 구분하기 위해 사용
  * Data Block Header, Redo Records, Segment Header에 기록
  - Fast Commit : Commit을 하면 DB Buffer Cache에서 데이터를 안내려 쓰고 Redo Log를 내려쓰는 것
    ⇒ Commit이 완벽하게 수행되려면 Data Block에 걸려있던 Lock까지 해제가 되어야 하지만
       (이 과정을 Block Cleanout이라고 부름) 변경된 블록이 많을 경우 일일이 찾아 다니며 작업을 하기엔
       시간이 많이 걸리기 때문에 Oracle은 블록에 걸려 있는 Commit 후 해당 블록을 처음 액세스 하는 시점에
       해제를 하는 Delayed Block Cleanout이나 Commit Cleanout 같은 여러 가지 기법을 동원해서
       Commit을 최대한 빨리 수행하고 데이터를 안전하게 지킴.



(3) Checkpoint
  - CheckPoint : Commit 된 데이터를 어디까지 저장했는지 확인하기 위해서 만들어 놓은 개념
                        ex) SCN이 100번까지 Commit 되었고 Checkpoint 정보가 90번이라면 SCN 90번 트랜잭션까지는
                              데이터 파일에 저장되었다고 확인 됨


  * Control File과 Data File의 Checkpoint 정보를 비교하여 서로 정보가 다르면 틀린 부분을 Online Redo Log나
    Archived Redo Log를 참조해서 복구



  ① Database / Global Checkpoint
     : Checkpoint가 발생하면 Buffer Cache에 있는 모든 저장 안 된 Drity Buffer들의 내용을 전부 데이터 파일로 저장,
        저장된 SCN 중 가장 번호가 큰 SCN 번호(Checkpoint SCN)를 Control File과 Data File Header 부분에 기록


  ② Thread Checkpoint / Logical Checkpoint
     : 해당 Thread 내의 저장되 않은 모든 Dirty Buffer들을 Data File로 전부 내려 씀
      이 Checkpoint는 Log Switch가 발생하면 생김, RAC 환경일 경우 각 노드별로 다르게 발생
      Single Instance 일 경우 Database Checkpoint와 같은 역할


  ③ Data File Checkpoint
     : 특정 데이터 파일에만 발생하는 Checkpoint
      해당 Tablespace를 Offline 한다거나, Begin Backup 수행 시 발생
      이 Checkpoint가 발생하면 해당 정보를 Control File과 Data File Header 부분에 기록


  ④ Mini Checkpoint
     : Drop Table과 같이 특정한 DDL 발생 시 특정 블록에만 발생


  ⑤ Recovery Checkpoint
     : 데이터 파일에 장애가 발생했을 때 백업된 데이터 파일 복원 후 Redo Change Vector를 적용시키게 됨,
       그 후 Recovery된 블록을 데이터 파일에 저장해야 하는데 이때 발생하는 Checkpoint를 말함




  * DB Buffer Cache의 변경된 Dirty Buffer들을 Data File로 저장하는 것을 Checkpoint라고 함
  * Oracle은 우선순위를 두어서 Checkpoint를 관리
    * 우선 순위가 높을 경우 Fast Checkpoint, 우선 순위가 낮을 경우 Low Checkpoint로 분류
    * 두 가지가 동시에 발생 할 경우 Fast Checkpoint부터 진행
      ex) Database Shutdown, Tablespace Begin Backup, Alter System Checkpoint 등의 명령어로 발생되는
           Checkpoint는 Fast Checkpoint로 분류되어 DB Buffer Cache 내부에 잇는 Dirty Buffer들을
           즉시 데이터 파일로 저장(=Full Checkpoint), Control File / Data File Header에 기록


          우선 순위가 낮은 경우는 Checkpoint를 해야 할 Block의 목록을 즉시 데이터 파일로 내려 쓰지 않고
          어딘가 기록해 둔 후 Background로 내려씀(=Incremental Checkpoint, 증분 체크포인트)


출처: http://o2sunn.tistory.com/20?category=599345 [썬월드]