행위

"Redo"의 두 판 사이의 차이

DB CAFE

(Redo Log Buffer와 Redo Log File)
 
(같은 사용자의 중간 판 49개는 보이지 않습니다)
1번째 줄: 1번째 줄:
┌ Redo : Re(다시) do(한다)
+
== REDO ==
└ Undo : Un(취소) do(한다), Rollback
 
 
 
  - Redo Log : 변경되는 내용이 있을 때 모두 기록해 두었다가 장애를 대비하는 기능
 
  
+
{{틀:고지상자
 +
|제목=REDO 개념
 +
|내용=* Redo : Re(다시) do(한다), Recovery
 +
** Redo Log : 변경되는 내용이 있을 때 모두 기록해 두었다가 장애를 대비하는 기능
 +
}}
  
   
+
=== Redo 로그의 목적 ===
 +
# 데이터 베이스 복구
 +
#: : 물리적인 디스크 장애시 복구, 미디어 복구(Media Recovery) 라고 함  
 +
# 캐시 복구
 +
#: : 버퍼캐시에 있는 데이터가 디스크의 데이터 블럭에 기록되기 전 장애가 발생한 경우 복구, 인스턴스 복구(Instance Recovery) 라고 함.
 +
# FAST COMMIT
 +
#: : 트랜잭션 발생시 변경사항을 Append 방식으로 순차적으로 빠르게 로그파일에 기록하고 메모리 데이터 블럭과 디스크 데이터 파일간 동기화를 통해서 배치방식으로 일괄 수행함.
 +
#:: 'Delayed 블럭 클린아웃' 방식을 이용하여 트랜잭션이 발생된 전체건이 끝나기를 기다리지 않고 우선 처리 한후 나중에 일괄 수행되는 방식.
  
1. Redo Log의 생성 원리
+
----
  * Oracle에서 데이터의 변경(DDL, DML, TCL등)이 발생했다면 아래의 두 매커니즘에 의해 Rodo Log에 기록됨
 
  
 +
=== 온라인 Redo 로그 와 아카이빙 Redo 로그 ===
 +
https://misogain.wordpress.com/wp-content/uploads/2024/05/archive.jpg
  
① Write Log Ahead
+
==== 온라인 Redo 로그 ====
    : 실제 데이터를 변경하기 전에 Redo Log에 먼저 기록한 후 데이터를 변경합니다
+
# 온라인 리두 로그는 리두로그 버퍼에 버퍼링된 로그 엔트리를 기록하는 파일
      (=DBWR이 작동하기 전에 LGWR이 작동하는 것도 이것과 같은 의미)
+
# 최소 2개 파일로 구성됨
 +
# 현재 사용중인 로그파일이 가득 차면 다른 리두로그파일로 로그 스위칭이 발생함
 +
# 모든 리두로그 파일이 가득 차면 처음 리두로그파일 부터 다시 재사용됨
  
+
==== 아카이빙 Redo 로그 ====
 +
# 온라인 리두로그가 재사용되기 전에 지정된 아키이빙 로그 디렉토리에 백업 하는 파일
  
② Log force at Commit
+
----
    : 사용자로부터 Commit 요청이 들어오면 관련된 모든 Redo Record들은 Redo Log file에 저장한 후 Commit을 완료.
 
  
      (=Redo Log File에 기록하지 않고는 Commit을 완료하지 않는다)
+
=== Redo Log의 생성 원리 ===
 +
* Oracle에서 데이터의 변경(DDL, DML, TCL등)이 발생했다면 두 매커니즘에 의해 Rodo Log에 기록됨
  
 +
==== Write Log Ahead ====
 +
* 실제 데이터를 변경하기 전에 Redo Log에 먼저 기록한 후 데이터를 변경
 +
*: (DBWR이 작동하기 전에 LGWR이 작동하는 것도 이것과 같은 의미)
 +
* LGWR(Log Writer)가 리두로그 버퍼를 리두로그 파일로 저장하는 시점
 +
# 3초마다 DBWR 프로세스가 준 신호를 받아서 저장
 +
# 로그 버퍼량이 3분의 1이 차거나 , 로그버퍼량이 1MB이상 일때
 +
# commit 이나 rollback이 실행될때
  
  * 대량의 데이터 변경 Commit이 한꺼번에 수행되면 Delayed Commit(지연된 커밋), Group Commit 발생
+
==== Log force at Commit ====
 +
* 사용자로부터 Commit 요청이 들어오면 관련된 모든 Redo Record들은 Redo Log file에 저장한 Commit을 완료.
 +
*: (Redo Log File에 기록하지 않고는 Commit을 완료하지 않는다)
  
  - Group Commit : Commit을 아주 짧은 시간 동안 모아서 한꺼번에 수행하는 기술
+
* 대량의 데이터 변경 후 Commit이 한꺼번에 수행되면 Delayed Commit(지연된 커밋), Group Commit 발생
                            짧은 시간동안 많은 데이터가 변경된 후 한꺼번에 Commit 요청이 들어올 경우 발생
+
*:- Group Commit : Commit을 아주 짧은 시간 동안 모아서 한꺼번에 수행하는 기술
 +
*:- 짧은 시간동안 많은 데이터가 변경된 후 한꺼번에 Commit 요청이 들어올 경우 발생
  
+
==== Redo log가 생성되고 기록되는 원리 ====
  
+
https://velog.velcdn.com/images/dbcafe/post/639951ce-d7f6-488e-bb26-a28ab15df1e3/image.jpg
  
▣ Redo log가 생성되고 기록되는 원리
+
===== Redo Log 기록 원리 =====
 
+
# 사용자가 특정 데이터를 변경하는 쿼리 수행 시에 해당 SQL을 받은 서버 프로세스는 원하는 Block이 Database Buffer Cache에 있는지 확인
+
#: 확인 후 없으면 해당 블록을 데이터 파일에서 찾아서 복사한 후 Buffer Cache로 가져옴.  
 
+
# 해당 row부분을 다른 사용자가 바꿀 수 없도록 Lock를 설정(page fix) 후 PGA에 Redo Change Vector를 생성함.
 
+
#:* 체인지 벡터(Change Vector) : Redo Log에 기록할 변경된 데이터에 대한 모든 정보의 세트(복구를 위한 상세한 설명서)
 
+
# Redo Log는 Commit된 데이터를 복구할 때도 사용 되지만 Rollback 데이터를 복구할 때도 사용.
<nowiki><img src=https://t1.daumcdn.net/cfile/tistory/254D743D540A39332E /></nowiki>
+
#:* 사용자가 커밋(commit)을 수행하고 Checkpoint 발생 전에 DB가 강제 종료 되었다면 해당 데이터를 Roll Forwared 하는 내용도 저장해야 하지만 사용자가 Rollback한 후 아직 Rollback이 완전히 완료되지 않은 상태에서 DB가 강제 종료 되었을 경우에도 Rollback 되지 못한 데이터 전부를 Rollback 해줘야 한다.
 
+
#:* 그래서, Change Vector내에 Undo 관련 내용까지 함께 저장된다.
< Redo Log 기록 원리 >
+
# PGA에 만들어진 Change Vector는 Redo Record Format으로 Row단위로 Redo Log Buffer에 복사됨
 
+
# (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
 
 
사용자가 특정 데이터의 변경을 요청하는 쿼리를 수행하면 해당 SQL을 받은 서버 프로세스는 원하는 Block이 Database  
 
 
 
    Buffer Cache에 있는지 확인 후 없으면 해당 블록을 데이터 파일에서 찾아서 복사한 후 Buffer Cache로 가져온다.
 
    그리고 해당 row부분을 다른 사용자가 바꿀 수 없도록 Lock를 설정(page fix) 후 PGA에 Redo Change Vector를 생성
 
 
 
 
 
 
  - Charge 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에 복사됨
 
 
 
 
 
 
(PGA에서 Change Vector 생성 후 ) Redo Log Buffer에서 필요한 용량을 계산,  
 
      Latch 획득 (Change Vector를 Redo Log Buffer에 복사하기 위함)
 
 
 
  - Latch(래치) : 한정된 메모리 자원을 여러 사용자가 사용할 때 사용할 수 있는 순서를 정해주는 역할
 
 
 
 
 
 
  * Rodo Log Buffer에 내용을 쓰려면 두 가지 Latch를 확보해야 한다.  
 
    (1) Redo Copy Latch         (2) Redo Allocation Latch
 
 
 
 
 
 
  - Redo Copy Latch : Change Vector가 모두 Redo Log Buffer에 기록될 때가지 계속 가지고 있어야 하기 때문에
 
 
 
                                여러개의 Latch가 존재한다.
 
 
 
 
 
 
 
 
 
  ▣  Redo Copy Latch 현황 조회 (11g)
 
 
 
 
 
 
 
 
 
SQL> SELECT name, gets, misses, immediate_gets, wait_time
 
  2  FROM v$latch_children
 
  3  where name='redo copy' ;
 
  
 +
==== Redo Copy Latch 현황 조회 ====
 
   
 
   
 +
<source lang=sql>
 +
SELECT name, gets, misses, immediate_gets, wait_time
 +
  FROM v$latch_children
 +
WHERE name='redo copy' ;
  
 
         NAME            GETS        MISSES      IMMEDIATE_GETS  WAIT_TIME
 
         NAME            GETS        MISSES      IMMEDIATE_GETS  WAIT_TIME
107번째 줄: 82번째 줄:
 
redo copy                6                0                            0                  0
 
redo copy                6                0                            0                  0
 
redo copy                6                0                        6707                  0
 
redo copy                6                0                        6707                  0
 
 
 
 
 
 
    * CPU 개수가 1개일 경우에는 기본적으로 2개의 Redo Copy Latch가 조회됨
 
    * _log_simultaneous_copies 히든 파라미터를 이용해 개수를 조정할 수 있다
 
 
    * Latch의 개수를 늘리는 것이 무조건 성능에 좋은 것은 아니다.
 
      (은행에 고객이 많이 몰릴 때 번호표 뽑는 기계를 많이 가져다 놓는 것은 의미가 없기 때문에)
 
    * Latch 때문에 문제가 생기는 것인지 Redo Log Buffer나 File 자체에 문제가 있는지 확인 후 조치
 
 
 
 
 
 
③ 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 파라미터 값으로 설정)
 
 
 
   
 
   
 
+
</source>
      * Shared Roe Strand 기능과 관련해 중요한 것은 Redo Log Buffer를 몇 개로 나누는가 인데
 
        10g 부터는 LOG_PARALLELISM 파라미터가 _LOG_PARALLELISM 히든 파라미터로 변경되고
 
        이 값은 Oracle이 동적으로 관리하도록 _LOG_PARALLELIS_DYNAMIC 파라미터가 추가됨
 
      * _LOG_PARALLELISM_DYNAMIC 값이 True일 경우 Oracle이 해당 Strand 개수를 자동으로 제어
 
      * 이 파라미터에 대한 Oracle 권장 값은 CPU 개수 / 8
 
 
 
 
   
 
   
 +
* CPU 개수가 1개일 경우, 기본적으로 2개의 Redo Copy Latch가 조회됨
 +
* _log_simultaneous_copies 히든 파라미터를 이용해 개수 조정 가능.
 +
* Latch의 개수를 늘리는 것이 무조건 성능에 좋은 것은 아니다. (예시_은행에 고객이 많이 몰릴 때 번호표 뽑는 기계를 많이 가져다 놓는 것은 의미가 없기 때문에)
 +
* Latch 때문에 문제가 생기는 것인지 Redo Log Buffer나 File 자체에 문제가 있는지 확인 후 조치 필요
  
   
+
==== 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
  
  ▣  Redo Allocation Latch의 개수 조회 (11g)
+
===== Redo Allocation Latch의 개수 조회 =====
 
+
<source lang=sql>
+
SELECT COUNT(*)
 
+
   FROM V$latch_children
+
  WHERE NAME='redo allocation' ;
 
 
SQL> SELECT COUNT(*)
 
   FROM V$LATCH_SHILDREN
 
  3 WHERE NAME='redo allocation' ;
 
 
 
 
  
 
   COUNT(*)
 
   COUNT(*)
 
   ------------
 
   ------------
 
       28
 
       28
 +
</source>
 +
* 10g부터는 Shared Redo Strand 보다 더 확장된 개념인 Private Redo Strand 기능이 도입
 +
* 각 서버 프로세스가 Shared pool에 자신만의 독립적인 Privete Strand 공간을 만들어서 그곳에 Change Vector를 생성한 후 필요한 경우 LGWR이 Redo Log File에 바로 기록함
 +
*: Latch를 확보해서 Redo Log Buffer에 기록해야 하는 과정을 줄임으로써 성능 향상시킴. Zero Copy Redo 라고 부름.
  
 +
==== 온라인 Redo Log 파일 ====
 +
#  Redo Log Buffer에 기록된 내용들(Redo Entry)은 특정 상황이 되면 LGWR 프로세스가 일부를 Online Redo Log File에 기록한 후 기록 된 Redo Entries들을 Redo Log Buffer에서 삭제(Flush)
 +
# 어떤 Server Process가 특정 상황이 되면 Redo Writing Latch를 확보 한 후 LGWR에게 Redo Log Buffer에 있는 내용을 Redo Log File에 기록하라고 요청
 +
{{틀:고지상자
 +
|제목=온라인 리두로그에 기록되는 상황 - Log Switch
 +
|내용=
 +
* ⅰ) 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 결정)
  
    ⇒ 10g부터는 Shared Redo Strand 보다 더 확장된 개념인 Private Redo Strand 기능이 도입
+
==== Redo Log Block Size 조회 ====
 
+
<source lang=sql>
 
 
      * 각 서버 프로세스가 Shared pool에 자신만의 독립적인 Privete Strand 공간을 만들어서 그곳에 Change Vector를
 
 
 
        생성한 후 필요한 경우 LGWR이 Redo Log File에 바로 기록함
 
        ⇒ Latch를 확보해서 Redo Log Buffer에 기록해야 하는 과정을 줄임으로써 성능 향상
 
            다른 말로 Zero Copy Redo라고 부름.
 
 
 
 
 
 
 
 
 
④ 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;
 
SQL> SELECT max(lebsz) FROM sys.x$kccle;
 
 
  
 
MAX(LEBSZ)
 
MAX(LEBSZ)
 
---------------
 
---------------
 
       512
 
       512
 
+
</source>
 
 
 
 
 
  * 모든 변경사항이 Redo Log에 기록되는 것은 아님
 
    예를 들어, Direct Load(SQL Loader, Insert /* APPEND */)나 Table, Index 생성시 NOLOGGING 옵션을 주는 경우
 
 
 
      Redo Log에 기록되지 않는다.
 
 
 
  * 단, NOLOGGING 옵션으로 테이블을 생성되었더라도 일반적인 Insert, Update, Delete는 Redo Log에 기록됨
 
 
 
 
 
 
 
 
 
 
 
2. Redo Log File 구성 및 관리하기
 
 
 
 
 
 
(1) Redo Log Buffer와 Redo Log File
 
 
 
 
 
 
 
 
 
 
 
   
 
   
 +
* 모든 변경사항이 Redo Log에 기록되는 것은 아님.
 +
*: 예를 들어, Direct Load(SQL Loader, Insert /* APPEND */)나 Table, Index 생성시 NOLOGGING 옵션을 주는 경우 Redo Log에 기록되지 않는다.
  
< Redo Log 구성도 >
+
* 단, NOLOGGING 옵션으로 테이블을 생성되었더라도 일반적인 Insert, Update, Delete는 Redo Log에 기록됨.
  
+
=== Redo Log File 구성 및 관리 ===
 +
==== Redo Log Buffer와 Redo Log File ====
 +
https://velog.velcdn.com/images/khyup0629/post/93b79e94-51c4-4cd7-aac9-f6d9d8590e63/image.png
  
+
# 데이터가 변경되면 데이터의 안전한 복구를 위해서 Redo Log Buffer에 먼저 기록한 후 실제 데이터를 변경
 +
#: - Redo Log Buffer 에서 여러 가지 조건이 발생하게 되면 Redo Writing Latch를 획득한 Server Process가 LGWR에게 Redo Log Buffer의 내용을 Redo Log File로 기록 요청
 +
# LGWR이 내려쓴 내용은 Redo Log Buffer에서 지워 새로운 공간을 확보
 +
# Log Switch가 발생하게 되면 Checkpoint 신호가 발생
 +
#: - Log Switch : LGWR이 Redo Log Buffer에 내용을 Redo Log File에 내려 쓰다가 해당 파일이 가득 차게 되면 다음 그룹으로 자동으로 넘어가는 것
 +
# DBWR이 해당 로그 파일에 있는 내용 중 Buffer Cache에서 데이터파일로 저장되지 못한 변경사항들을 내려씀.
 +
# 이 정보들을 데이터파일과 컨트롤 파일에 반영됨
 +
# Log Switch가 일어나는 그룹의 순서는 Oracle이 라운드로빈 방식으로 알아서 결정
 +
#: (=1번 그룹 다음에 2번 그룹이고 그 다음에 3번그룹이 아닐 수도 있다라는 의미)
  
  * 데이터가 변경되면 데이터의 안전한 복구를 위해서 Redo Log Buffer에 먼저 기록한 후 실제 데이터를 변경
+
::* LGWR은 Redo Log File의 그룹에 멤버가 여러 개일 경우 같은 그룹안의 멤버들끼리는 서로 저장하고 있는 내용과 크기가 동일(병렬로 동시에 같은 내용 기록)
 +
::*: 그러나 만약 같은 디스크에 있으면 직렬로 기록(=하나 기록하고 끝나면 다른 하나를 기록)
  
      → Redo Log Buffer에서 여러 가지 조건이 발생하게 되면 Redo Writing Latch를 획득한 Server Process가 LGWR에게
 
 
          Redo Log Buffer의 내용을 Redo Log File로 기록 요청
 
 
      → LGWR이 내려쓴 내용은 Redo Log Buffer에서 지워 새로운 공간을 확보
 
  
 +
{{틀:고지상자2
 +
|제목 = 리두로그 그룹 과 멤버 (오라클 권장값)
 +
|내용 = # Redo Log File은 그룹과 멤버라는 개념으로 관리
 +
# 같은 그룹일 경우 멤버들은 같은 내용을 담고 있어서 만약 하나의 멤버가 삭제되거나 장애가 발생해도 다른 멤버가 하나 더 존재하기 때문에 안전하게 관리할 수 있음
 +
# 멤버를 더 추가 할 수 있지만 기록시간이 늘어나기 때문에 부하를 줄 수 있음
 +
# 같은 그룹의 멤버는 절대 동일한 디스크에 함께 두는 것을 권장하지 않음
 +
# 오라클에서 최소 그릅의 개수는 2개이며 각 그룹별로 필요한 최소 멤버는 1개
 +
# 오라클 권장 구성 개수 : 최소 그룹 3개, 그룹별 최소 2개 이상의 멤버
 +
}}
 
   
 
   
 +
{{틀:고지상자2
 +
|제목 = 리두로그 기록시 에러가 발생될 경우
 +
|내용 = # 병렬쓰기 도중에 Redo Log File이 삭제되거나 Block에 문제가 발생할 경우에는 LGWR은 각 오픈 로그 멤버의 상태를 조사해서 어떤 파일이 에러가 발생되는지 알아냄
 +
# 장애가 난 멤버는 Control File 안에 STALE 상태로 기록, LGWR은 백그라운드 Trace File에 ORA-00346 에러 기록
 +
#: - STALE 상태 : 해당 로그 파일이 문제가 있다는 것을 의미
 +
# LGWR이 하나의 로그 파일에서 4개 이상의 에러를 만나게 되면 로그 파일을 닫고 더 이상 그 파일에 내용을 기록하지 않음
 +
# 만약 LGWR이 어떤 로그파일에도 내용을 기록할 수 없다면 ORA-00340 에러를 발생시키고 Shutdown abort로 강제 종료되고 Startup 되지 않는다.
 +
}}
  
  * Redo Log File은 그룹과 멤버라는 개념으로 관리됨
+
{{틀:고지상자
  * <Redo Log 구성도>를 보면 그룹이 3개가 있고 각각의 그룹에는 멤버가 2개씩 존재
+
|제목 = 리두로그 성능 개선/조치 사항
  * 같은 그룹일 경우 멤버들은 같은 내용을 담고 있어서 만약 하나의 멤버가 삭제되거나 장애가 발생해도 다른 멤버가
+
|내용 = # Redo Log File 크기는 각 서버의 실정에 맞게 사용해야 함(=권장 크기는 정해져 있지 않음)
 
+
#: - 크기가 너무 작게 되면 Log Switch가 자주 발생 ⇒ 성능 저하
      하나 더 존재하기 때문에 안전하게 관리할 수 있음
+
#: - 크기가 너무 크면 데이터의 손상 가능성이 커짐
  * 멤버를 더 추가 할 수 있지만 기록시간이 늘어나기 때문에 부하를 줄 수 있음
+
# '''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의 수를 증가시켜 주어야 한다.
 +
}}
  
+
=== Redo Log File 생성/삭제/관리 ===
 
+
==== 신규 Group 생성 (신규 그룹 4번으로 지정) ====
+
<source lang=sql>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
* [잘못 구성된 예]는 1개의 그룹 전체가 Disk 하나에 몰려 있기 때문에 잘못 구성된 예가 된 것
 
  1개의 그룹이 1개의 멤버를 가지는 것은 권장하지 않는다.
 
 
 
 
 
 
  * 오라클에서 최소 그릅의 개수는 2개이며 각 그룹별로 필요한 최소 멤버는 1개
 
  * 오라클 권장 구성 개수 : 최소 그룹 3개, 그룹별 최소 2개 이상의 멤버
 
 
 
 
 
 
  - Log Switch : LGWR이 Redo Log Buffer에 내용을 Redo Log File에 내려 쓰다가 해당 파일이 가득 차게 되면
 
 
 
                        다음 그룹으로 자동으로 넘어가는 것
 
 
 
 
 
 
  * Log Switch가 발생하게 되면 Checkpoint 신호가 발생
 
    ⇒ DBWR이 해당 로그 파일에 있는 내용 중 Buffer Cache에서 데이터파일로 저장되지 못한 변경사항들을 내려씀.
 
    ⇒ 이 정보들을 데이터파일과 컨트롤 파일에 반영됨
 
 
 
 
 
 
  * Log Switch가 일어나는 그룹의 순서는 Oracle이 라운드로빈 방식으로 알아서 결정
 
    (=1번 그룹 다음에 2번 그룹이고 그 다음에 3번그룹이 아닐 수도 있다라는 의미)
 
 
 
 
 
 
  * LGWR은 Redo Log File의 그룹에 멤버가 여러 개일 경우 같은 그룹안의 멤버들끼리는 서로 저장하고 있는 내용과
 
 
 
      크기가 동일(병렬로 동시에 같은 내용 기록)
 
    그러나 만약 같은 디스크에 있으면 직렬로 기록(=하나 기록하고 끝나면 다른 하나를 기록)
 
 
 
 
 
 
  * 만약 병렬쓰기 도중에 Redo Log File이 삭제되거나 Block에 문제가 발생할 경우에는 LGWR은 각 오픈 로그 멤버의
 
 
 
    상태를 조사해서 어떤 파일이 에러가 발생되는지 알아냄
 
    → 장애가 난 멤버는 Control File 안에 STALE 상태로 기록, LGWR은 백그라운드 Trace File에 ORA-00346 에러 기록
 
 
 
  * STALE 상태 : 해당 로그 파일이 문제가 있다는 것을 의미
 
  * LGWR이 하나의 로그 파일에서 4개 이상의 에러를 만나게 되면 로그 파일을 닫고 더 이상 그 파일에 내용을
 
 
 
      기록하지 않음
 
  * 만약 LGWR이 어떤 로그파일에도 내용을 기록할 수 없다면 ORA-00340 에러를 발생시키고 Shutdown abort로
 
 
 
    강제 종료되고 Startup 되지 않는다.
 
 
 
   
 
 
 
 
 
  * Redo Log File 크기는 각 서버의 실정에 맞게 사용해야 함(=권장 크기는 정해져 있지 않음)
 
  * 크기가 너무 작게 되면 Log Switch가 자주 발생 ⇒ 성능 저하
 
  * 크기가 너무 크면 데이터의 손상 가능성이 커짐
 
 
 
  * 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의 수를 증가시켜 주어야 한다.
 
 
 
 
 
 
 
 
(2) Redo Log File 관리하기 (11g 기준, 이전 버전 동일)
 
 
 
 
 
 
  ▣ 주요 명령어 정리
 
 
 
 
 
 
 
 
 
 
 
 
1. 신규 Group 생성하기 (신규 그룹 4번으로 지정)
 
 
SQL> alter database add logfile group 4
 
SQL> alter database add logfile group 4
  2  '/app/oracle/oradata/testdb/redo04_a.log' size 5M ;
+
    '/app/oracle/oradata/testdb/redo04_a.log' size 5M ;
 
+
</source>
 
   
 
   
 
+
==== Member 추가 ====
2. Member 추가하기
+
<source lang=sql>
 
SQL> alter database add logfile member
 
SQL> alter database add logfile member
  2  '/app/oracle/oradata/testdb/redo04_b.log' to group 4 ;
+
    '/app/oracle/oradata/testdb/redo04_b.log' to group 4 ;
 
+
</source>
 
   
 
   
 
+
==== Member 삭제 ====
3. Member 삭제하기
+
<source lang=sql>
 
SQL> alter database drop logfile member
 
SQL> alter database drop logfile member
  2  '/app/oracle/oradata/testdb/redo04_b.log' ;
+
    '/app/oracle/oradata/testdb/redo04_b.log' ;
 
+
</source>
 
   
 
   
 
+
==== Group 삭제 ====
4. Group 삭제하기
+
<source lang=sql>
 
SQL> alter database drop logfile group 4;
 
SQL> alter database drop logfile group 4;
 
+
</source>
 
   
 
   
 
+
==== 강제로 Log Switch 발생시키기 ====
5. 강제로 Log Switch 발생시키기
+
<source lang=sql>
 
SQL> alter system switch logfile;
 
SQL> alter system switch logfile;
 
+
</source>
 
   
 
   
  
6. 강제로 Checkpoint 발생시키기
+
==== 강제로 Checkpoint 발생 ====
 +
<source lang=sql>
 
SQL> alter system checkpoint;
 
SQL> alter system checkpoint;
 
+
</source>
 
 
 
 
 
 
 
 
 
* ASM이 아닌 일반 OS파일 시스템으로 Oracle을 설치하였다면 3, 4번에 있는 삭제 과정을 수행해도 실제 해당 파일은
 
 
 
  지워지지 않음.(ASM 기반에서는 지울 수 있음)
 
 
 
 
 
  * 파일 시스템이 경우에 위 명령어들을 수행하고 난 뒤 반드시 DBA가 직접 OS 명령어로 해당 파일을 직접 지워야 함
 
 
 
    (다른 그룹이나 멤버를 지우지 않도록 각별히 조심!)
 
 
 
 
 
 
  * Redo Log File의 상태 : CURRENT
 
    * 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.
 
 
 
  Redo Log File 관리하기
 
 
 
 
 
 
 
   
 
   
 +
* 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의 내용이 데이터 파일에도 다 저장되어서 삭제되어도 되는 상태
  
Step 1. 현재 상태 확인하기
+
* DBA가 어떤 필요에 의해 Redo Log File을 삭제하고 싶다면 반드시 INACTIVE 상태로 만들고 3, 4번 명령어로 삭제 수행.  
 +
* 주의 사항 : Redo Log File을 삭제할 때 절대 OS 명령어로 먼저 삭제하면 안됨!!
  
 +
=== Redo Log File 관리 실습 예제 ===
 +
==== 현재 Redo Log 상태 확인하기 ====
 +
<source lang=sql>
 
SQL> !vi log.sql
 
SQL> !vi log.sql
  
470번째 줄: 261번째 줄:
  
 
SELECT a.group#, a.member, b.bytes/1024/1024 MB, b.sequence# "SEQ#", b.status, b.archived "ARC"
 
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
+
  FROM v$logfile a, v$log b
WHERE a.group#=b.group#
+
WHERE a.group#=b.group#
ORDER BY 1,2
+
ORDER BY 1,2
 
/
 
/
 
 
:wq
 
:wq
 +
</source>
  
 +
<source lang=sql>
 
SQL> @log
 
SQL> @log
  
484번째 줄: 276번째 줄:
 
     2  /app/oracle/oradata/testdb/redo02.log          50  32 INACTIVE  NO
 
     2  /app/oracle/oradata/testdb/redo02.log          50  32 INACTIVE  NO
 
     3  /app/oracle/oradata/testdb/redo03.log          50  33 CURRENT  NO
 
     3  /app/oracle/oradata/testdb/redo03.log          50  33 CURRENT  NO
 +
</source>
  
+
==== 신규 그룹(4번 그룹) / 멤버 추가 하기 ====
 
+
<source lang=sql>
+
alter database add logfile group 4
 
+
    '/app/oracle/oradata/testdb/redo04_a.log' size 5M ;
Step 2. 신규 그룹(4번 그룹) / 멤버 추가 하기
+
</source>
 
 
 
 
 
SQL> alter database add logfile group 4
 
  2  '/app/oracle/oradata/testdb/redo04_a.log' size 5M ;
 
 
 
 
 
 
Database altered.
 
 
 
 
 
 
SQL> @log
 
  
 +
* RAC 환경(ASM)
 +
: - RAC#1
 +
<source lang=sql>
 +
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;
 +
</source>
 +
: - RAC#2
 +
<source lang=sql>
 +
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;
 +
</source>
 
   
 
   
 
+
<source lang=sql>
 +
SQL> @log
 
GROUP# MEMBER                                    MB SEQ# STATUS  ARC
 
GROUP# MEMBER                                    MB SEQ# STATUS  ARC
 
-------- ------------------------------------------------------- ---- ---- ----------- -----
 
-------- ------------------------------------------------------- ---- ---- ----------- -----
512번째 줄: 310번째 줄:
 
     3  /app/oracle/oradata/testdb/redo03.log          50  33 CURRENT  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_a.log          5    0 UNUSED  YES
 
+
</source>
 
   
 
   
 
+
<source lang=sql>
 
 
 
SQL> alter database add logfile member
 
SQL> alter database add logfile member
 
   2  '/app/oracle/oradata/testdb/redo04_b.log' to group 4 ;
 
   2  '/app/oracle/oradata/testdb/redo04_b.log' to group 4 ;
 
 
 
 
Database altered.
 
Database altered.
 
+
</source>
 
 
 
SQL> @log
 
 
 
 
   
 
   
 +
<source lang=sql>
 +
SQL> @log
  
 
GROUP# MEMBER                                    MB SEQ# STATUS  ARC
 
GROUP# MEMBER                                    MB SEQ# STATUS  ARC
536번째 줄: 328번째 줄:
 
     4  /app/oracle/oradata/testdb/redo04_a.log          5    0 UNUSED  YES
 
     4  /app/oracle/oradata/testdb/redo04_a.log          5    0 UNUSED  YES
 
     4  /app/oracle/oradata/testdb/redo04_b.log          5    0 UNUSED  YES
 
     4  /app/oracle/oradata/testdb/redo04_b.log          5    0 UNUSED  YES
 +
</source>
  
   
+
  <source lang=sql>
 
 
 
 
 
SQL> alter system switch logfile;
 
SQL> alter system switch logfile;
 
 
 
 
System altered.
 
System altered.
 
+
</source>
 
 
 
SQL> @log
 
 
 
 
   
 
   
 +
<source lang=sql>
 +
SQL> @log
  
 
GROUP# MEMBER                                    MB SEQ# STATUS  ARC
 
GROUP# MEMBER                                    MB SEQ# STATUS  ARC
559번째 줄: 345번째 줄:
 
     4  /app/oracle/oradata/testdb/redo04_a.log          5  34 CURRENT  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
 
     4  /app/oracle/oradata/testdb/redo04_b.log          5  34 CURRENT  NO
 
+
</source>
 
+
<source lang=sql>
 
SQL> alter system checkpoint;
 
SQL> alter system checkpoint;
 
 
  
 
System altered.
 
System altered.
 
+
</source>
 
   
 
   
 
+
<source lang=sql>
 
SQL> @log
 
SQL> @log
  
579번째 줄: 363번째 줄:
 
     4  /app/oracle/oradata/testdb/redo04_a.log          5  34 CURRENT  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
 
     4  /app/oracle/oradata/testdb/redo04_b.log          5  34 CURRENT  NO
 
+
</source>
 
 
 
 
   
 
   
 
 
※ Alter system checkpoint 명령어로 3번 그룹이 Active → Inactive로 변경됨   
 
※ Alter system checkpoint 명령어로 3번 그룹이 Active → Inactive로 변경됨   
  
 
+
==== 기존 멤버 삭제 / 그룹 삭제 하기 (4번 그룹 삭제) ====
Step 3. 기존 멤버 삭제 / 그룹 삭제 하기 (4번 그룹 삭제)
+
<source lang=sql>
 
 
 
 
 
 
SQL> @log
 
SQL> @log
 
 
  
 
GROUP# MEMBER                                    MB SEQ# STATUS  ARC
 
GROUP# MEMBER                                    MB SEQ# STATUS  ARC
602번째 줄: 378번째 줄:
 
     4  /app/oracle/oradata/testdb/redo04_a.log          5  34 CURRENT  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
 
     4  /app/oracle/oradata/testdb/redo04_b.log          5  34 CURRENT  NO
 
+
</source>
 
 
 
 
 
SQL> alter system switch logfile;
 
 
 
 
   
 
   
  
 +
<source lang=sql>
 +
alter system switch logfile;
 
System altered.
 
System altered.
 +
</source>
  
 
 
 
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 ;
 
  
   
+
<source lang=sql>
 +
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
 
GROUP# MEMBER                                    MB ARC  STATUS
629번째 줄: 401번째 줄:
 
     4  /app/oracle/oradata/testdb/redo04_a.log          5  NO  ACTIVE
 
     4  /app/oracle/oradata/testdb/redo04_a.log          5  NO  ACTIVE
 
     4  /app/oracle/oradata/testdb/redo04_b.log          5  NO  ACTIVE
 
     4  /app/oracle/oradata/testdb/redo04_b.log          5  NO  ACTIVE
 
+
</source>
 
   
 
   
  
 
+
<source lang=sql>
 
SQL> alter system checkpoint;
 
SQL> alter system checkpoint;
 
 
  
 
System altered.
 
System altered.
 
+
</source>
 
   
 
   
 
+
<source lang=sql>
SQL> select a.group#, a.member, b.bytes/1024/1024 MB, b.archived, b.status
+
select a.group#,b.thread#, a.member, b.bytes/1024/1024 MB, b.archived, b.status
   from v$logfile a, v$log b
+
   from v$logfile a, v$log b
  3 where a.group#=b.group#
+
  where a.group#=b.group#
  4 order by 1,2 ;
+
  order by 1,2 ;
 
 
  
 
GROUP# MEMBER                                    MB ARC  STATUS
 
GROUP# MEMBER                                    MB ARC  STATUS
654번째 줄: 423번째 줄:
 
     4  /app/oracle/oradata/testdb/redo04_a.log          5 NO  INACTIVE
 
     4  /app/oracle/oradata/testdb/redo04_a.log          5 NO  INACTIVE
 
     4  /app/oracle/oradata/testdb/redo04_b.log          5 NO  INACTIVE
 
     4  /app/oracle/oradata/testdb/redo04_b.log          5 NO  INACTIVE
 +
</source>
  
+
* 그룹삭제
 +
<source lang=sql>
 +
SQL> Alter database drop logfile group 1;
 +
</source>
  
+
* 멤버 삭제
 +
<source lang=sql>
 +
SQL> alter database drop logfile member '/app/oracle/oradata/testdb/redo04_b.log' ;
 +
Database altered.
 +
</source>
  
SQL> alter database drop logfile member '/app/oracle/oradata/testdb/redo04_b.log' ;
+
* ASM환경에서 그룹 삭제
 +
<source lang=sql>
 +
$ 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';
 +
</source>
  
Database altered.
+
<source lang=sql>
 +
SQL> Alter database drop logfile group 1;
  
 
   
 
   
 
+
<source lang=sql>
 
SQL> !ls /app/oracle/oradata/testdb/redo04_b.log  
 
SQL> !ls /app/oracle/oradata/testdb/redo04_b.log  
 
/app/oracle/oradata/testdb/redo04_b.log                    ← 여전히 파일이 남아 있음
 
/app/oracle/oradata/testdb/redo04_b.log                    ← 여전히 파일이 남아 있음
 
+
</source>
 
   
 
   
 
+
<source lang=sql>
 
SQL> !rm –rf /app/oracle/oradata/testdb/redo04_b.log        ← 수동으로 삭제
 
SQL> !rm –rf /app/oracle/oradata/testdb/redo04_b.log        ← 수동으로 삭제
 
+
</source>
 
   
 
   
 
+
<source lang=sql>
 
SQL> !ls /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
 
ls: /app/oracle/oradata/testdb/redo04_b.log: No such file or directory
 
+
</source>
 
   
 
   
 
 
   
 
   
 
+
<source lang=sql>
 
SQL> select a.group#, a.member, b.bytes/1024/1024 MB, b.archived, b.status
 
SQL> select a.group#, a.member, b.bytes/1024/1024 MB, b.archived, b.status
 
   2  from v$logfile a, v$log b
 
   2  from v$logfile a, v$log b
696번째 줄: 479번째 줄:
 
     3  /app/oracle/oradata/testdb/redo03.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_a.log          5 NO  INACTIVE
 
+
</source>
 
   
 
   
 
 
   
 
   
 
+
<source lang=sql>
 
SQL> alter database drop logfile member '/app/oracle/oradata/testdb/redo04_a.log' ;
 
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'
 
alter database drop logfile member '/app/oracle/oradata/testdb/redo04_a.log'
706번째 줄: 488번째 줄:
 
ERROR at line 1:
 
ERROR at line 1:
 
ORA-00361: cannot remove last log member /app/oracle/oradata/testdb/redo04_a.log for group 4
 
ORA-00361: cannot remove last log member /app/oracle/oradata/testdb/redo04_a.log for group 4
 
+
</source>
 
   
 
   
 
 
← 그룹에 member가 1개일 경우 member는 삭제가 안되며 그룹을 지워야 한다.
 
← 그룹에 member가 1개일 경우 member는 삭제가 안되며 그룹을 지워야 한다.
  
   
+
  <source lang=sql>
 
 
 
 
 
 
SQL> alter database drop logfile group 4;
 
SQL> alter database drop logfile group 4;
 
 
 
 
Database altered.
 
Database altered.
 
+
</source>
 
   
 
   
 
+
<source lang=sql>
 
SQL> select a.group#, a.member, b.bytes/1024/1024 MB, b.archived, b.status
 
SQL> select a.group#, a.member, b.bytes/1024/1024 MB, b.archived, b.status
 
   2  from v$logfile a, v$log b
 
   2  from v$logfile a, v$log b
 
   3  where a.group#=b.group#
 
   3  where a.group#=b.group#
 
   4  order by 1,2 ;
 
   4  order by 1,2 ;
 
 
  
 
GROUP# MEMBER                                          MB ARC STATUS
 
GROUP# MEMBER                                          MB ARC STATUS
735번째 줄: 508번째 줄:
 
     2 /app/oracle/oradata/testdb/redo02.log          50 NO  INACTIVE
 
     2 /app/oracle/oradata/testdb/redo02.log          50 NO  INACTIVE
 
     3 /app/oracle/oradata/testdb/redo03.log          50 NO  INACTIVE
 
     3 /app/oracle/oradata/testdb/redo03.log          50 NO  INACTIVE
 
+
</source>
 
   
 
   
 
+
<source lang=sql>
 
SQL> !ls /app/oracle/oradata/testdb/redo04_a.log
 
SQL> !ls /app/oracle/oradata/testdb/redo04_a.log
 
/app/oracle/oradata/testdb/redo04_a.log                    ← 여전히 파일이 남아 있음
 
/app/oracle/oradata/testdb/redo04_a.log                    ← 여전히 파일이 남아 있음
 
+
</source>
 
   
 
   
 
+
<source lang=sql>
 
SQL> !rm –rf /app/oracle/oradata/testdb/redo04_a.log      ← 수동으로 삭제
 
SQL> !rm –rf /app/oracle/oradata/testdb/redo04_a.log      ← 수동으로 삭제
 
+
</source>
 
   
 
   
 
+
<source lang=sql>
 
SQL> !ls /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
 
ls: /app/oracle/oradata/testdb/redo04_a.log: No such file or directory
 
+
</source>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3. 심화학습, 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이 기록되는 곳
+
{{:REDO Waiting Event (리두 대기 이벤트)}}
 
 
  * 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 [썬월드]
+
[[Category:oracle]]

2024년 6월 16일 (일) 21:37 기준 최신판

thumb_up 추천메뉴 바로가기


1 REDO[편집]

  • Redo : Re(다시) do(한다), Recovery
    • Redo Log : 변경되는 내용이 있을 때 모두 기록해 두었다가 장애를 대비하는 기능



1.1 Redo 로그의 목적[편집]

  1. 데이터 베이스 복구
     : 물리적인 디스크 장애시 복구, 미디어 복구(Media Recovery) 라고 함
  2. 캐시 복구
     : 버퍼캐시에 있는 데이터가 디스크의 데이터 블럭에 기록되기 전 장애가 발생한 경우 복구, 인스턴스 복구(Instance Recovery) 라고 함.
  3. FAST COMMIT
     : 트랜잭션 발생시 변경사항을 Append 방식으로 순차적으로 빠르게 로그파일에 기록하고 메모리 데이터 블럭과 디스크 데이터 파일간 동기화를 통해서 배치방식으로 일괄 수행함.
    'Delayed 블럭 클린아웃' 방식을 이용하여 트랜잭션이 발생된 전체건이 끝나기를 기다리지 않고 우선 처리 한후 나중에 일괄 수행되는 방식.

1.2 온라인 Redo 로그 와 아카이빙 Redo 로그[편집]

archive.jpg

1.2.1 온라인 Redo 로그[편집]

  1. 온라인 리두 로그는 리두로그 버퍼에 버퍼링된 로그 엔트리를 기록하는 파일
  2. 최소 2개 파일로 구성됨
  3. 현재 사용중인 로그파일이 가득 차면 다른 리두로그파일로 로그 스위칭이 발생함
  4. 모든 리두로그 파일이 가득 차면 처음 리두로그파일 부터 다시 재사용됨

1.2.2 아카이빙 Redo 로그[편집]

  1. 온라인 리두로그가 재사용되기 전에 지정된 아키이빙 로그 디렉토리에 백업 하는 파일

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

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

1.3.1 Write Log Ahead[편집]

  • 실제 데이터를 변경하기 전에 Redo Log에 먼저 기록한 후 데이터를 변경
    (DBWR이 작동하기 전에 LGWR이 작동하는 것도 이것과 같은 의미)
  • LGWR(Log Writer)가 리두로그 버퍼를 리두로그 파일로 저장하는 시점
  1. 3초마다 DBWR 프로세스가 준 신호를 받아서 저장
  2. 로그 버퍼량이 3분의 1이 차거나 , 로그버퍼량이 1MB이상 일때
  3. commit 이나 rollback이 실행될때

1.3.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.3.3 Redo log가 생성되고 기록되는 원리[편집]

image.jpg

1.3.3.1 Redo Log 기록 원리[편집]
  1. 사용자가 특정 데이터를 변경하는 쿼리 수행 시에 해당 SQL을 받은 서버 프로세스는 원하는 Block이 Database Buffer Cache에 있는지 확인
    확인 후 없으면 해당 블록을 데이터 파일에서 찾아서 복사한 후 Buffer Cache로 가져옴.
  2. 해당 row부분을 다른 사용자가 바꿀 수 없도록 Lock를 설정(page fix) 후 PGA에 Redo Change Vector를 생성함.
    • 체인지 벡터(Change Vector) : Redo Log에 기록할 변경된 데이터에 대한 모든 정보의 세트(복구를 위한 상세한 설명서)
  3. Redo Log는 Commit된 데이터를 복구할 때도 사용 되지만 Rollback 데이터를 복구할 때도 사용.
    • 사용자가 커밋(commit)을 수행하고 Checkpoint 발생 전에 DB가 강제 종료 되었다면 해당 데이터를 Roll Forwared 하는 내용도 저장해야 하지만 사용자가 Rollback한 후 아직 Rollback이 완전히 완료되지 않은 상태에서 DB가 강제 종료 되었을 경우에도 Rollback 되지 못한 데이터 전부를 Rollback 해줘야 한다.
    • 그래서, Change Vector내에 Undo 관련 내용까지 함께 저장된다.
  4. PGA에 만들어진 Change Vector는 Redo Record Format으로 Row단위로 Redo Log Buffer에 복사됨
  5. (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.4 Redo Copy Latch 현황 조회[편집]

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.5 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.5.1 Redo Allocation Latch의 개수 조회[편집]
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.6 온라인 Redo Log 파일[편집]

  1. Redo Log Buffer에 기록된 내용들(Redo Entry)은 특정 상황이 되면 LGWR 프로세스가 일부를 Online Redo Log File에 기록한 후 기록 된 Redo Entries들을 Redo Log Buffer에서 삭제(Flush)
  2. 어떤 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 결정)

1.3.7 Redo Log Block Size 조회[편집]

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


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


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



1.5 Redo Log File 생성/삭제/관리[편집]

1.5.1 신규 Group 생성 (신규 그룹 4번으로 지정)[편집]

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

1.5.2 Member 추가[편집]

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

1.5.3 Member 삭제[편집]

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

1.5.4 Group 삭제[편집]

SQL> alter database drop logfile group 4;

1.5.5 강제로 Log Switch 발생시키기[편집]

SQL> alter system switch logfile;


1.5.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 현재 Redo Log 상태 확인하기[편집]

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


2 리두(Redo) 대기 이벤트[편집]

  • latch: redo writing
  • latch: redo allocation
  • latch: redo copy

2.1 redo writing 래치[편집]

  1. redo 버퍼내의 공간을 확보하기 위해 LGWR에게 쓰기 요청을 하려는 프로세스는 redo writing 래치를 획득해야함
  2. LGWR에 의한 쓰기 작업은 동시에 수행될 수 없으므로 전체 인스턴스에 하나만 존재 함.
  3. redo writing 래치는 Willing-to-wait 모드로 획득 됨
  4. redo writing 래치를 획득하는 과정에서 경합이 발생하면 latch: redo writing 이벤트를 대기 함

2.2 redo copy 래치[편집]

  1. PGA내의 체인지 벡터를 리두 버퍼로 복사하려는 프로세스는 작업의 전체과정 동안 redo copy 래치를 보유해야 한다.
  2. redo copy 래치는 기본적으로 No-wait 모드로 획득
  3. 만일 프로세스가 redo copy 래치를 획득하는데 실패하면 연속적으로 다음 redo copy 래치를 획득하기 위해 시도한 후 마지막 redo copy 래치를 획득하는 과정에서는 Willing-to-wait 모드가 사용 됨
  4. redo copy 래치를 획득하는 과정에서 경합이 발생하면 latch: redo copy 이벤트를 대기

2.3 redo allocation 래치[편집]

  1. 체인지 벡터를 리두 버퍼에 복사하기 위해 리두 버퍼 내에 공간을 확보 하는 과정에서 redo allocation 래치를 획득해야 함
  2. 전체 리두 버퍼를 복수개의 Redo strands라는 공간으로 분할해서 사용할 수 있으며, 하나의 redo allocation 래치가 하나의 redo strand를 관리
  3. 복수개의 redo allocation 래치를 사용 가능하기 때문에 래치 경합을 다소 줄일 수 있다.
  4. 또한 Dynamic Parellelism에 의해 동적으로 redo strands의 개수를 조정해서 redo allocation 래치의 수가 크게 늘어났다.
  5. SGA에 추가적으로 private redo strands라는 기능을 도입하여 다중 strands의 개념을 더욱 확장하였다.
  6. Private strands 영역은 프로세스 간에 공유되지 않기 때문에 리두를 생성하는 과정에서 래치를 획득할 필요가 없으며, LGWR에 의해서 리두 로그 파일로 바로 쓰여 지기 때문에 PGA에서 리두 버퍼로 복사하는 과정이 불필요하다.
    이것은 zero copy redo라고 표현하기도 한다.
notifications_active 일반적인 환경에서는 리두 관련 래치 경합은 잘 발생하지 않는다.
  1. 래치 경합의 횟수보다는 래치 경합에 따른 대기시간을 경합의 발생 증거로 활용.
  2. 리두 버퍼의 크기가 리두 래치 경합을 일으키는 요인이 될 수도 있음
  3. 리두와 관련된 대부분의 성능문제가 래치 경합보다는 어플리케이션의 작동 방식이나 I/O 성능과 관련이 있다.
  4. 리두 래치에서 발생하는 경합에 대해서는 뚜렷한 해결책이 없는 경우가 많음
  5. 버전이 올라감에 따라 리두 버퍼 관련 알고리즘이 개선되어서 대부분의 경우 래치 경합은 더 이상 문제가 되지 않는다.

2.4 log file sync[편집]

select a.sid,
a.event,
a.time_waited,
a.time_waited / c.sum_time_waited * 100 pct_wait_time,
d.value user_commits,
round((sysdate - b.logon_time) * 24) hours_connected
from v$session_event a, v$session b, v$sesstat d,
(select sid, sum(time_waited) sum_time_waited
from v$session_event
where event not in (
'Null event',
'client message',
'KXFX: Execution Message Dequeue - Slave',
'PX Deq: Execution Msg',
'KXFQ: kxfqdeq - normal deqeue',
'PX Deq: Table Q Normal',
'Wait for credit - send blocked',
'PX Deq Credit: send blkd',
'Wait for credit - need buffer to send',
'PX Deq Credit: need buffer',
'Wait for credit - free buffer',
'PX Deq Credit: free buffer',
'parallel query dequeue wait',
'PX Deque wait',
'Parallel Query Idle Wait - Slaves',
'PX Idle Wait',
'slave wait',
'dispatcher timer',
'virtual circuit status',
'pipe get',
'rdbms ipc message',
'rdbms ipc reply',
'pmon timer',
'smon timer',
'PL/SQL lock timer',
'SQL*Net message from client',
'WMON goes to sleep')
having sum(time_waited) > 0 group by sid) c
where a.sid = b.sid
and a.sid = c.sid
and a.sid = d.sid
and d.statistic# = (select statistic#
from v$statname
where name = 'user commits')
and a.time_waited > 10000
and a.event = 'log file sync'
order by pct_wait_time, hours_connected;
  1. 서버 프로세스가 커밋 또는 롤백을 수행하면 LGWR은 리두 버퍼에서 가장 최근에 기록이 이루어진 이후 시점부터 커밋 지점까지의 리두 레코드를 리두 로그 파일에 기록한다.
  2. 이것을 "sync write"라고 부르며 redo synch writes 통계값을 통해 조회 가능.
  3. 트랜잭션의 존재 이유가 데이터를 변경하고 커밋을 수행하는 것이기 때문에 log file sync 대기이벤트는 오라클에서 가장 보편적인 대기이벤트 중 하나이다.
  4. 보통 sync write가 수행되는 시간은 매우 짧기 때문에 log file sync 대기는 문제가 되지 않는다.
  5. 하지만 일단 발생하게 되면 상당히 해결하기 어려운 대기현상이다.
  6. 만일 log file sync 대기가 광범위하게 나타난다면 아래와 같은 사실을 의심해야한다.
    1. 커밋 회수와 log file sync
      - 지나치게 잦은 커밋은 log file sync 대기의 주범이다. 여러 세션에서 동시에 대량의 커밋을 수행하면 log file sync 대기가 광범위하게 나타날 수 있다.
      - 오라클은 여러 세션에서 동시에 실행하거나, PL/SQL 블록에서 반복적으로 커밋이 이루어지거나, Recursive SQL에 의해서 커밋이 이루어지는 경우 그룹 커밋 기능이 사용된다.
      이때, user commits 통계 값은 커밋 명령을 호출한 횟수와 동일하게 증가하지만, log file sync는 한번만 발생하게 된다.
    2. nocache 속성의 시퀀스 또한 log file sync를 유발한다.
      - Sequence.nextval을 호출하면 매번 딕셔너리 테이블의 정보를 갱신하고 커밋을 수행해야하기 때문이다.
    3. I/O 시스템의 성능과 log file sync
      - 리두 로그 파일이 위치한 I/O 시스템의 성능이 느린 경우에는 LGWR의 synch write를 수행하는 시간이 늘어나고 이로 인해 log file sync 대기시간이 증가할 수 있다. ##: 이 경우, 서버 프로세스가 log file sync 이벤트를 대기하는 동안 LGWR는 log file parallel write 이벤트를 대기하게 된다.
      - 일반적인 가이드는 리두 로그 파일올 가장 빠른 다바이스에 위치시키는 것이다.
      - 디스크 경합을 피하기 위해 서로 다른 그룹의 리두 로그 파일은 서로 다른 디스크에 분산시켜야 한다.
      - 리두 로그 파일을 데이터 파일이나 컨트롤 파일과 다른 디스크에 배치시켜야 한다.
    4. 리두 데이터의 양과 log file sync
      커밋 수행시 리두 로그 파일에 기록해야 할 데이터양을 줄이면 log file sync 대기시간 또한 줄일 수 있다.
      특히 크고 긴 트랜잭션에서 리두 데이터양을 줄이게 되면 LGWR의 백그라운드 기록 작업이 줄게 되고 자연스럽게 리두와 관련된 경합이 해소될 수 있다.
      대량의 데이터를 생성하는 작업에서는 다음과 같은 기법을 쓸 수 있는지 검토해 보아야한다.
      (1) Nologging 옵션을 사용할 수 있는지
      (2) SQL*Loader로 대량의 데이터를 적재할 때는 Direct load option을 사용한다.
      (3) 임시 작업이 필요할 때는 가능하면 임시 테이블을 사용한다.
      (4) 인덱스가 있는 테이블에 대해 Direct load 작업을 수행할 때는 인덱스를 Unusable로 변경하고 데이터 생성하고 인덱스를 Nologging 모드로 재구성과 같은 절차를 통해서 인덱스에 의해 리두가 생성되는 것을 방지한다.
      (5) LOB 데이터의 경우 데이터의 크기가 크다면 가급적 Nologging 속성을 부여한다.
    5. 리두 버퍼의 크기와 log file sync
      - 일반적으로 리두 버퍼의 크기가 지나치게 큰 경우에 log file sync 대기가 증가하는 경향이 있다.
      - 리두 버퍼의 크기가 큰 경우, LGWR에 의한 백그라운드 기록 횟수가 줄어 드는데, 이 경우 유저 세션에서 sync write를 수행할 때 기록해야 할 데이터의 양이 많아지고 이로 인해 log file sync 대기 시간이 길어질 수 있기 때문이다.
      - 반대로 log buffer space 대기가 증가하는 경향을 보인다면 리두 버퍼의 크기를 늘리는 것이 일반적인 해결책이다.
      - 이런 경우의 해결책은 _LOG_IO_SIZE 히든 파라미터를 이용하는 것이다.
      _LOG_IO_SIZE 파라미터는 LGWR이 리두 버퍼의 내용을 리두 로그 파일에 저장하는 임계치 값을 나타낸다.
      - log buffer space 대기를 줄이기 위해 리두 버퍼의 크기를 키우고 이와 동시에 log file sync 대기를 줄이기 위해_LOG_IO_SIZE 값을 적당히 작은 크기로 조정하면 된다.

2.5 log file parallel write[편집]

  1. LGWR 프로세스에만 발생하는 대기 이벤트
  2. LGWR은 리두 버퍼의 내용을 리두 로그 파일에 기록하기 위해 필요한 I/O 콜을 수행한 후 I/O 작업이 완료되기를 기다리는 동안 log file parallel write 이벤트를 대기
  3. I/O 시스템의 성능에는 아무런 이상 징후가 없는데도 리두 데이터양이 지나치게 많은 경우 log file parallel write 대기가 증가할 수 있다.
  4. 이것을 해결하기 위한 방법은 아래와 같다.
    (1) 불필요한 커밋을 줄인다.
    (2) Nologging 옵션을 활용하여 리두 데이터의 양을 줄인다.
    (3) 리두 로그 파일이 위치한 I/O 시스템의 성능을 높인다.
    (4) 핫백업을 너무 자주 수행하지 말고, 특히 트랜잭션이 많은 시점에 수행하지 않아야 한다.
    핫백업 모드에서는 리두 데이터가 로우 레벨이 아닌 블록 레벨로 생성되기 때문이다.

2.6 log buffer space[편집]

  1. redo allocation 래치를 획득한 상태에서 리두 버퍼에 공간을 확보하려는 순간에 적절한 여유 공간이 없는 경우, 공간이 확보되기를 기다려야 한다.
  2. 이때 경우에 따라 두 가지 종류의 이벤트를 대기하게 된다.
    1. 만일 현재 시용 중인 리두 로그 파일이 꽉 차서 더 이상 여유 공간을 확보할 수 없다면, LGWR은 로그 파일 스위치를 수행하고, 서버 프로세스는 log file switch completion 이벤트를 대기한다.
    2. 그 외의 경우에는 log buffer space 이벤트를 대기하게 된다.
  3. log buffer space 대기는 트랜잭션에 의해 생성되는 리두의 양에 비해 리두 버퍼의 크기가 작을 때 발생한다. # log buffer space 대기를 줄이기 위해 리두 버퍼 크기를 늘리는 경우, log file sync 대기가 증가할 수 있다.
  4. log buffer space 대기를 줄이는 또 하나의 방법은 리두 데이터를 적게 생성하는 것이다.
  5. Direct load 기능을 적당히 사용하고 Nologging 옵션을 부여하는 것 등이 이 방법에 속한다.
  6. 또한 더 빠르고 효율적인 I/O 시스템을 리두 로그 파일에 사용함으로써 LGWR의 쓰기 성능을 개선하고, log buffer space 대기를 줄일 수 있다.
  • log file switch completion
  • log file switch (checkpoint incomplete)
  • log file switch (archiving needed)
  • log file switch (private strand flush incomplete)
    • 서버 프로세스는 LGWR에 의해 로그 파일 스위치가 끝날 때까지 log file switch completion 이벤트를 대기하게 된다.
    • 하지만 로그 파일 스위치가 끝나는 시점에, 새로 사용할 리두 로그 파일에 대해 아직 종료되지 않은 작업이 있다면 아래와 같이 추가적으로 이벤트를 대기해야 한다.
      1) 새로 사용할 리두 로그 파일에 대한 체크포인트 작업이 끝나지 않았다면 프로세스는 DBWR에 의해 체크포인트가 끝나기를 대기해야 한다. 이 경우 log file switch (checkpoint incomplete) 이벤트를 대기한다.
      2) 새로 사용할 리두 로그 파일에 대해 아카이브 작업이 아직 끝나지 않았다면 프로세스는 아카이브 작업이 끝나기를 기다려야한다. 이 경우 log file switch (archiving needed) 이벤트를 대기한다.
      3) 새로 사용할 리두 로그 파일에 대한 Private strands에 대한 플러시 작업이 아직 끝나지 않았다면, 이 작업이 끝나기를 기다려야한다. 이 경우 log file switch (private strand flush incomplete)이벤트를 대기하게 된다.

서버 프로세스는 먼저 log file completion이벤트를 대기하고 특수한 경우 위의 이벤트를 대기하게 된다. 위 방법들에 대한 해결책은 동일하다. 발생 원인은 트랜잭션이 생성하는 리두 데이터 양에 비해 리두 로그 파일이 지나치게 작다는 것이다. 따라서 리두 로그 파일의 크기를 충분히 키워주고, Direct load operation이나 Nologging 옵션을 사용하여 리두 데이터의 양을 줄여야 한다.