[아이티윌 오라클 DBA 과정 91기] 260130 TIL
2026. 1. 30. 18:52ㆍCourses/아이티윌 오라클 DBA 과정
Redo Log Buffer
- 데이터베이스 데이터 블록의 모든 변경 사항을 기록
- 기본 목적은 recovery(복구)
- 내부에 기록된 변경 사항을 redo entry 라고 함
- redo entry 에는 변경 사항을 재구성하거나 재실행 할 정보가 포함이 되어 있음
- DML/DDL(create, alter, drop)/select for update
- DDL(create, alter, drop) text로 저장
log_buffer파라미터로 정의
LGWR 작동
- redo log buffer에 있는 redo entry를 redo log file에 기록
- commit, rollback
- redo log buffer 1/3 사용한 경우
- 1MB 이상 리두 정보가 입력될 경우
- 3초마다
- DBWR가 database buffer cache에 있는 dirty buffer를 datafile에 기록하기 전에 LGWR가 먼저 작동
Redo Entry 생성 과정
- 버퍼 캐시의 블록을 변경하기 전에 redo log buffer에 redo entry를 먼저 생성

- 변경 정보를 PGA 영역에 change vector 생성
- undo segment header 정보(change vector #1)
- undo block (change vector #2)
- transaction 대상이 되는 블록(change vector #3)
- PGA 영역 안에 있는 change vector 를 redo entry라는 이름으로 redo log buffer로 복사
- 이 때 반드시
redo copy latch를 획득해야 하며 change vector를 redo log buffer에 복사하는 전 과정동안redo copy latch를 보유해야 함- 이 과정에서 경합이 발생하면
latch: redo copy대기 이벤트가 발생
- 이 과정에서 경합이 발생하면
- 이 때 반드시
redo allocation latch를 획득한 후 리두 로그 버퍼 내에 redo entry를 저장할 공간을 확보- 이 과정에서 경합이 발생하면
latch: redo allocation대기 이벤트 발생 - 만약에 리두 로그 버퍼에 free 공간이 부족하면
redo writing latch를 획득한 후 LGWR에게 리두 로그 버퍼에 있는 리두 엔트리를 리두 로그 파일에 기록하도록 요청하고redo writing latch는 해제- 이 과정에서 경합이 발생하면
latch: redo writing대기 이벤트 발생
- 이 과정에서 경합이 발생하면
- 리두 로그 버퍼에 free 공간이 확보될 때까지
log buffer space대기 이벤트가 발생 - LGWR가 리두 엔트리를 current redo log file에 기록하려는 시점에 현재 그룹이 꽉 차서 log switch가 발생하는 경우 LGWR는 기다려야 함
- 이 때
log file switch completion대기 이벤트 발생
- 이 때
- 리두 로그 버퍼에 필요한 공간이 확보가 되면
redo allocation latch는 해제
- 이 과정에서 경합이 발생하면
- change vector를 리두 로그 버퍼에 redo entry 형태로 복사
- 이 과정이 끝나면
redo copy latch를 해제
- 이 과정이 끝나면
Redo Copy Latch
- PGA 영역에 생성한 Change vector를 리두 로그 버퍼로 복사하려는 경우 전체 과정동안 redo copy latch를 획득해야 함
- CPU 개수의 2배(기본값)
latch: redo copy
SYS@ora19c> col parameter format a30
SYS@ora19c> select a.ksppinm parameter, b.ksppstvl value
from x$ksppi a, x$ksppcv b
where a.indx = b.indx
and a.ksppinm = '_log_simultaneous_copies'; 2 3 4
PARAMETER VALUE
------------------------------ ------------------------------
_log_simultaneous_copies 4
SYS@ora19c> select name, gets from v$latch_children where name = 'redo copy';
NAME GETS
-------------------------------------------------- ----------
redo copy 211
redo copy 213
redo copy 212
redo copy 211
Redo Allocation Latch
- change vector를 리두 로그 버퍼에 복사하기 위해 리두 로그 버퍼 내에 프리 공간을 확보해야 함
- 이 과정에서 redo allocation latch를 획득해야 함
latch: redo allocation- 8i : 하나의 redo allocation latch만 사용
- 9i : redo log buffer를 복수개의 redo strand 라는 공간으로 분할해서 사용
- strand 마다 redo allocation latch를 사용하도록 함
log_parallelism파라미터로 결정 기본 값 1
- 10gR1 : redo strand 개수를 오라클이 동적으로 관리
_log_parallelism_dynamic히든 파라미터 값이 true(기본 값)로 설정되어있음
SYS@ora19c> select a.ksppinm parameter, b.ksppstvl value
from x$ksppi a, x$ksppcv b
where a.indx = b.indx
and a.ksppinm in ('_log_parallelism_dynamic', '_log_private_mul');
PARAMETER VALUE
------------------------------ ------------------------------
_log_parallelism_dynamic TRUE
_log_private_mul 5 <<- shared pool의 5%를 private redo strand로 사용
SYS@ora19c> select count(*) from v$latch_children where name = 'redo allocation';
COUNT(*)
----------
29
- 10gR2 : private redo strand 기능 사용함으로써 redo 데이터를 PGA 영역에서 change vector를 생성하는 것이 아니고 shared pool에 private redo strand 영역에 저장하며 이 영역에 저장된 redo 데이터는 redo log buffer를 거치지 않고 redo log file에 바로 저장
- redo copy latch, redo allocation latch를 획득하지 않아도 됨(zero copy redo)
- private redo strand 는 shared pool 공간에
_log_private_mul히든 파라미터로 지정된 비율(5%)만큼을 사용
SYS@ora19c> select * from v$sgastat where name = 'private strands';
POOL NAME BYTES CON_ID
-------------- ------------------------------ ---------- ----------
shared pool private strands 3677184 0
Redo Writing Latch
- redo log buffer 내의 공간을 확보하기 위해 LGWR에게 쓰기 요청을 하려는 경우 redo writing latch를 획득해야 함
- 1개
latch : redo writing
SYS@ora19c> select name, gets from v$latch_parent where name = 'redo writing';
NAME GETS
------------------------------ ----------
redo writing 942524
Conventional Path Load
- 데이터 버퍼 캐시를 사용해서 데이터 파일에 쓰기 작업 수행


테이블 생성
create table hr.redo_table(id number, name char(200)) tablespace users;
특정 유저 세션에 대한 리두 통계 정보 조회
SYS@ora19c> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo entries','redo size', 'redo synch writes','redo writes','redo blocks written','redo log space requests','redo log space wait time')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$session where username = 'HR')
group by n.name; 2 3 4 5 6
no rows selected
# HR로 접속 시 정보가 나옴
SYS@ora19c> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo entries','redo size', 'redo synch writes','redo writes','redo blocks written','redo log space requests','redo log space wait time')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$session where username = 'HR')
group by n.name; 2 3 4 5 6
NAME SUM(S.VALUE)
------------------------------ ------------
redo log space wait time 0
redo synch writes 1
redo writes 0
redo blocks written 0
redo entries 2
redo size 676
redo log space requests 0
7 rows selected.
redo log space wait time: redo log space request에 소요된 시간(1/1000초)redo synch writes: commit, rollback에 의해 수행된 redo write 수redo writes: LGWR 수행한 수redo blocks written: redo log file에 write된 redo log block 수redo entries: redo entry가 redo log buffer에 기록된 수redo size: redo size(byte)redo log space requests: redo log buffer에 redo entry를 LGWR가 redo log file에 쓰려고 하는데 log file이 꽉 차서 log switch 발생한 수
HR : insert 수행
HR@ora19c> insert into hr.redo_table(id, name) select object_id, object_name from all_objects;
54956 rows created.
SYS@ora19c> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo entries','redo size', 'redo synch writes','redo writes','redo blocks written','redo log space requests','redo log space wait time')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$session where username = 'HR')
group by n.name; 2 3 4 5 6
NAME SUM(S.VALUE)
------------------------------ ------------
redo log space wait time 0
redo synch writes 2
redo writes 0
redo blocks written 0
redo entries 9261
redo size 13175568
redo log space requests 0
7 rows selected.
- redo entry와 size가 증가함
- redo synch writes도 1 증가함 → 내부적으로 commit/rollback 발생
- commit/rollback이 발생했으므로 lgwr가 동작하지만 redo writes는 증가하지 않음
- redo synch writes 수로 따로 관리
- LGWR 작동 수는 = redo synch writes + redo wrties
SYS@ora19c> select s.sid, s.username, t.xidusn, xidslot, xidsqn, t.ubafil, t.ubablk, t.used_ublk
from v$session s, v$transaction t
where s.saddr = t.ses_addr
and s.username = 'HR'; 2 3 4
SID USERNAME XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK USED_UBLK
---------- ------------------------------ ---------- ---------- ---------- ---------- ---------- ----------
168 HR 5 15 2641 4 1784 39
HR : rollback
SYS@ora19c> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo entries','redo size', 'redo synch writes','redo writes','redo blocks written','redo log space requests','redo log space wait time')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$session where username = 'HR')
group by n.name; 2 3 4 5 6
NAME SUM(S.VALUE)
------------------------------ ------------
redo log space wait time 0
redo synch writes 3
redo writes 0
redo blocks written 0
redo entries 15025
redo size 14021144
redo log space requests 0
7 rows selected.
- redo sync writes 수만 1 증가
HR : truncate
HR@ora19c> truncate table hr.redo_table;
Table truncated.
SYS@ora19c> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo entries','redo size', 'redo synch writes','redo writes','redo blocks written','redo log space requests','redo log space wait time')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$session where username = 'HR')
group by n.name; 2 3 4 5 6
NAME SUM(S.VALUE)
------------------------------ ------------
redo log space wait time 0
redo synch writes 4
redo writes 0
redo blocks written 0
redo entries 15291
redo size 14057948
redo log space requests 0
7 rows selected.
- truncate 시 내부적으로 auto commit이 발생하므로(딕셔너리 테이블에 변경 작업을 수행하기 때문) redo synch writes가 1 증가
- redo entries와 redo size도 증가 → redo 가 생성됨
Direct Path Write
- 데이터 버퍼 캐시를 사용하지 않고 데이터 파일에 직접 쓰기 작업을 수행 (서버 프로세스)
- HWM 이후에 블록을 추가(append)
- 데이터가 듬성듬성 있는 경우 테이블 재구성 후 direct path write 수행하는 것이 좋음
- 추가되는 데이터에 대해서 undo 발생량이 최소화됨(딕셔너리에 대한 undo는 발생)
- 테이블에 대해서 TM Lock Exclusive(6) 모드 Lock을 설정하기 때문에 다른 세션에서 DML 작업이 허용되지 않음

SYS@ora19c> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo entries','redo size', 'redo synch writes','redo writes','redo blocks written','redo log space requests','redo log space wait time')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$session where username = 'HR')
group by n.name; 2 3 4 5 6
NAME SUM(S.VALUE)
------------------------------ ------------
redo log space wait time 0
redo synch writes 1
redo writes 0
redo blocks written 0
redo entries 2
redo size 676
redo log space requests 0
7 rows selected.
테이블에 DML 작업을 수행하면 REDO 정보 생성(yes 기본값)
SYS@ora19c> select logging from dba_tables where table_name = 'REDO_TABLE';
LOG
---
YES
HR : insert 수행
insert /*+ append */ into hr.redo_table(id, name) select object_id, object_name from all_objects;
append: direct path write를 유도하는 힌트
UNDO
SYS@ora19c> select s.sid, s.username, t.xidusn, xidslot, xidsqn, t.ubafil, t.ubablk, t.used_ublk
from v$session s, v$transaction t
where s.saddr = t.ses_addr
and s.username = 'HR'; 2 3 4
SID USERNAME XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK USED_UBLK
---------- ------------------------------ ---------- ---------- ---------- ---------- ---------- ----------
168 HR 8 5 2607 0 0 1
- undo 발생이 줄음
REDO
SYS@ora19c> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo entries','redo size', 'redo synch writes','redo writes','redo blocks written','redo log space requests','redo log space wait time')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$session where username = 'HR')
group by n.name; 2 3 4 5 6
NAME SUM(S.VALUE)
------------------------------ ------------
redo log space wait time 0
redo synch writes 2
redo writes 0
redo blocks written 0
redo entries 2225
redo size 13417996
redo log space requests 1
7 rows selected.
- redo 생성을 활성화 시킨 상태에서 작업했기 때문에 redo가 줄어들지 않음
Redo 발생 최소화
SYS@ora19c> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo entries','redo size', 'redo synch writes','redo writes','redo blocks written','redo log space requests','redo log space wait time')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$session where username = 'HR')
group by n.name; 2 3 4 5 6
NAME SUM(S.VALUE)
------------------------------ ------------
redo log space wait time 0
redo synch writes 1
redo writes 0
redo blocks written 0
redo entries 2
redo size 676
redo log space requests 0
7 rows selected.
nologging 모드로 변경
SYS@ora19c> alter table hr.redo_table nologging;
Table altered.
SYS@ora19c> select logging from dba_tables where table_name = 'REDO_TABLE';
LOG
---
NO
HR : insert 수행
insert /*+ append */ into hr.redo_table(id, name) select object_id, object_name from all_objects;
Redo
SYS@ora19c> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo entries','redo size', 'redo synch writes','redo writes','redo blocks written','redo log space requests','redo log space wait time')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$session where username = 'HR')
group by n.name; 2 3 4 5 6
NAME SUM(S.VALUE)
------------------------------ ------------
redo log space wait time 0
redo synch writes 1
redo writes 0
redo blocks written 0
redo entries 31
redo size 2864
redo log space requests 0
7 rows selected.
- redo 발생량이 크게 줄음
UNDO
SYS@ora19c> select s.sid, s.username, t.xidusn, xidslot, xidsqn, t.ubafil, t.ubablk, t.used_ublk
from v$session s, v$transaction t
where s.saddr = t.ses_addr
and s.username = 'HR'; 2 3 4
SID USERNAME XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK USED_UBLK
---------- ------------------------------ ---------- ---------- ---------- ---------- ---------- ----------
168 HR 4 19 2130 0 0 1
rollback 수행 후 세그먼트 정보 조회
SYS@ora19c> select segment_name, bytes/1024/1024 mb, blocks, extents from dba_segments where segment_name = 'REDO_TABLE';
SEGMENT_NAME MB BLOCKS EXTENTS
------------------------------ ---------- ---------- ----------
REDO_TABLE 13 1664 28
- 데이터가 입력되지 않았지만 block 및 extents 수가 증가된 채로 있음
truncate 수행 후 세그먼트 조회
SYS@ora19c> select segment_name, bytes/1024/1024 mb, blocks, extents from dba_segments where segment_name = 'REDO_TABLE';
SEGMENT_NAME MB BLOCKS EXTENTS
------------------------------ ---------- ---------- ----------
REDO_TABLE .0625 8 1
- minextent 1개만 남기고 공간이 모두 회수됨
redo 발생할 수 있도록 logging 모드로 다시 수정
SYS@ora19c> alter table hr.redo_table logging;
Table altered.
SYS@ora19c> select logging from dba_tables where table_name = 'REDO_TABLE';
LOG
---
YES
Commit/Rollback
SYS@ora19c> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo synch writes', 'user commits', 'user rollbacks')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$session where username = 'HR')
group by n.name; 2 3 4 5 6
NAME SUM(S.VALUE)
------------------------------ ------------
user rollbacks 0
redo synch writes 1
user commits 0
HR : Insert 수행 후 commit
HR@ora19c> insert into hr.redo_table(id, name) values(1, 'oracle');
1 row created.
HR@ora19c> commit;
Commit complete.
SYS@ora19c> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo synch writes', 'user commits', 'user rollbacks')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$session where username = 'HR')
group by n.name; 2 3 4 5 6
NAME SUM(S.VALUE)
------------------------------ ------------
user rollbacks 0
redo synch writes 3
user commits 1
SYS@ora19c> select event, total_waits, time_waited
from v$session_event
where sid = (select sid from v$session where username = 'HR')
and event = 'log file sync'; 2 3 4
EVENT TOTAL_WAITS TIME_WAITED
------------------------------ ----------- -----------
log file sync 3 2
- user commits 수가 증가
- redo synch writes 수도 증가
HR : Insert 수행 후 commit
HR@ora19c> insert into hr.redo_table(id, name) values(2, 'james');
1 row created.
HR@ora19c> commit;
Commit complete.
SYS@ora19c> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo synch writes', 'user commits', 'user rollbacks')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$session where username = 'HR')
group by n.name; 2 3 4 5 6
NAME SUM(S.VALUE)
------------------------------ ------------
user rollbacks 0
redo synch writes 4
user commits 2
SYS@ora19c> select event, total_waits, time_waited
from v$session_event
where sid = (select sid from v$session where username = 'HR')
and event = 'log file sync'; 2 3 4
EVENT TOTAL_WAITS TIME_WAITED
------------------------------ ----------- -----------
log file sync 4 3
- user commits 수가 증가
- redo synch writes 수도 증가
- log file sync 대기 이벤트 발생 수 증가
HR : Delete 수행 후 rollback
HR@ora19c> delete from hr.redo_table where id = 2;
1 row deleted.
HR@ora19c> rollback;
Rollback complete.
SYS@ora19c> select n.name, sum(s.value)
from v$sesstat s, v$statname n
where n.name in ('redo synch writes', 'user commits', 'user rollbacks')
and s.statistic# = n.statistic#
and s.sid = (select sid from v$session where username = 'HR')
group by n.name; 2 3 4 5 6
NAME SUM(S.VALUE)
------------------------------ ------------
user rollbacks 1
redo synch writes 6
user commits 2
SYS@ora19c> select event, total_waits, time_waited
from v$session_event
where sid = (select sid from v$session where username = 'HR')
and event = 'log file sync'; 2 3 4
EVENT TOTAL_WAITS TIME_WAITED
------------------------------ ----------- -----------
log file sync 6 4
- user rollbacks 수가 증가
- redo synch writes 수도 증가
- log file sync 대기 이벤트 발생 수 증가
정리
- user commits/user rollbacks는 유저가 직접 commit/rollback 한 수만 보여줌
- redo synch writes는 내부적으로 수행된 commit/rollback 횟수도 보여줌
log file sync 대기 이벤트
- commit/rollback 수행 시 LGWR가 redo log buffer에 있는 redo entry 를 redo log file에 기록하는데, 이 때 redo synch writes, user commits, user rollbacks 통계 값이 증가
- 서버 프로세스는 LGWR가 write가 끝날 때까지 대기
- 이 때 발생하는 대기 이벤트가
log file sync
- 이 때 발생하는 대기 이벤트가
- log file sync 대기 이벤트는 오라클에서 가장 보편적인 대기 이벤트 중 하나
- synch write가 수행되는 시간은 매우 짧기 때문에 log file sync 대기는 크게 문제가 되지 않음
- but 너무 자주 발생할 경우 문제
log file sync 대기 원인
- 빈번한 commit, rollback 수행하는 경우
- I/O 시스템이 느린 경우(LGWR는
log file parallel write대기 이벤트가 평균 시간이 높거나 전체 시스템에서 대기 시간 대비 차지하는 비중이 높다면 리두 로그 파일이 있는 I/O 시스템 성능에 문제가 있음) - 리두 데이터가 불필요하게 생성되는 경우 (nologging 옵션 고려, direct path write 고려)
- 시퀀스 생성 시에 nocache(row cache lock, log file sync)로 설정하면 sequence.nextval 수행하는 순간 딕셔너리(seq$)테이블 갱신하고 commit 수행하기 때문에 시퀀스를 사용할 때 트랜잭션 양을 고려하여 반드시 적절한 크기의 cache 속성을 부여하자
- 리두 로그 버퍼가 너무 큰 경우
'Courses > 아이티윌 오라클 DBA 과정' 카테고리의 다른 글
| [아이티윌 오라클 DBA 과정 91기] 260203 TIL (0) | 2026.02.03 |
|---|---|
| [아이티윌 오라클 DBA 과정 91기] 260202 TIL (0) | 2026.02.02 |
| [아이티윌 오라클 DBA 과정 91기] 260129 TIL (0) | 2026.01.30 |
| [아이티윌 오라클 DBA 과정 91기] 260128 TIL (0) | 2026.01.29 |
| [아이티윌 오라클 DBA 과정 91기] 260127 TIL (0) | 2026.01.29 |