데이터베이스 연구실.log

UNDO와 REDO

UNDO와 REDO의 목적, 저장 위치, 보호 방식 비교 및 DML의 UNDO와 REDO 생성 관계를 보여 주는 실습 기록

UNDOREDO롤백읽기 일관성커밋V$MYSTAT

#핵심 요약

UNDO는 변경을 되돌리는 정보, REDO는 변경을 다시 적용하는 정보임

DML 하나는 UNDO와 REDO를 모두 만듦
UNDO도 데이터베이스 블록에 저장되므로 UNDO를 만드는 것 자체가 REDO를 만듦
반대로 REDO를 만든다고 UNDO가 생기지는 않음

커밋은 변경 내용이 디스크의 리두 로그 파일에 기록됐음을 확인하는 절차임
데이터 파일에 아직 반영되지 않았더라도 인스턴스가 다시 시작될 때 리두를 다시 적용해 복원함

#개념과 동작 원리

#비교

구분 UNDO REDO
기록 내용 변경을 어떻게 되돌릴 것인가 변경을 어떻게 재현할 것인가
쓰임새 롤백, 읽기 일관성, 플래시백 유실된 변경의 재적용(roll forward), 인스턴스 복구
저장 위치 UNDO 세그먼트(UNDO 테이블스페이스) 리두 로그 파일
보호 방식 다중화 개념이 없음 한 그룹 안에 멤버를 여럿 두어 다중화

#UNDO가 쓰이는 곳과 저장 방식

UNDO 데이터는 진행 중인 트랜잭션의 롤백, 비정상 종료된 트랜잭션의 복구, 읽기 일관성, 일부 논리적 플래시백 작업에 쓰임

UNDO 데이터는 외부 로그가 아니라 데이터베이스 안의 블록에 저장되고, 이 블록도 데이터 블록처럼 갱신되며 그 변경은 리두 레코드를 만듦

영구 객체의 UNDO는 UNDO 테이블스페이스에 저장됨
트랜잭션이 시작되면 현재 UNDO 테이블스페이스의 UNDO 세그먼트 하나에 할당됨

실습 표의 "저장 위치"와 "UNDO 생성이 REDO를 만든다"는 설명은 위 공식 문서 내용과 일치함

#커밋과 인스턴스 복구

커밋하면 트랜잭션의 변경 사항이 리두 로그 파일에 기록됨
리두 로그 파일은 대체로 다중화되어 있음

커밋된 변경이 데이터 파일에 반영되기 전에 정전이 나도, 재시작할 때 반영되지 않은 리두 레코드를 다시 적용(roll forward)해 복원함

커밋 시점의 LGWR 동작은 서버 프로세스와 백그라운드 프로세스를 함께 봄

#필수 명령어 또는 SQL

#실습 준비

SQL*Plus (일반 사용자, PDB)객체 또는 설정을 변경함
CONNECT <USERNAME>/<PASSWORD>@<SERVICE_NAME>

CREATE TABLE ur_chk AS SELECT * FROM emp;
COMMIT;

결과 해석:

emp는 실습 계정의 예제 테이블임
없는 환경에서는 다른 테이블로 바꿈

#통계 조회 (각 단계 뒤에 반복)

SQL*Plus (같은 세션)조회만 함
SELECT n.name, s.value
  FROM v$mystat s JOIN v$statname n ON s.statistic# = n.statistic#
 WHERE n.name IN ('redo size', 'undo change vector size');

결과 해석:

두 값 모두 세션 누적값이므로 단계 앞뒤의 차이를 봄

#단계별 실습 기록

SQL*Plus (같은 세션)데이터 또는 파일을 삭제함, 되돌릴 수 없음
UPDATE ur_chk SET sal = sal + 1;
DELETE FROM ur_chk;
ROLLBACK;

결과 해석:

실습에서는 위 세 문장을 하나씩 실행하고 매번 통계를 조회했음

단계 redo size 증가 undo change vector size 증가 해석
UPDATE 14행 +5,444 +2,568 DML 하나가 둘 다 만듦
DELETE 14행 +7,828 +5,208 행 전체를 UNDO에 남기는 DELETE는 UNDO가 크고 REDO도 함께 커짐
ROLLBACK +2,724 +464 되돌리는 것도 변경이므로 REDO가 생김

ROLLBACK 뒤 COUNT(*)는 14로 원래 행 수가 돌아왔음
표의 증가분은 기록된 누적값의 차이를 계산한 것임
ROLLBACK 단계의 UNDO 증가분은 수업 자료 본문에 언급이 없음

#누적값 비교와 정리

SQL*Plus (같은 세션)조회만 함
SELECT MAX(DECODE(n.name, 'redo size', s.value))               AS redo_total,
       MAX(DECODE(n.name, 'undo change vector size', s.value)) AS undo_total
  FROM v$mystat s JOIN v$statname n ON s.statistic# = n.statistic#
 WHERE n.name IN ('redo size', 'undo change vector size');
SQL*Plus (같은 세션)데이터 또는 파일을 삭제함, 되돌릴 수 없음
DROP TABLE ur_chk PURGE;

결과 해석:

실습 기록은 REDO_TOTAL 24116, UNDO_TOTAL 10344였음
실습에서는 REDO 누적값이 항상 더 큰 이유를 UNDO 변경 기록이 REDO에 들어 있기 때문이라고 설명함

#사용 조건과 주의사항

실습에서는 DIRECT PATH LOAD와 NOLOGGING을 함께 쓰면 REDO가 크게 줄어드는 예외가 있다고만 적었음
조건은 기재 없음

기출 문제의 결론(UNDO 생성은 REDO를 만들고, DML은 둘을 모두 만듦)은 핵심 요약에 반영했음

UNDO 테이블스페이스 생성은 UNDO 공간과 보존에 있음

SEO_HKabsumveritas@gmail.comBuilt with Claude Code & Codex

마지막 갱신 개인 학습 기록이며 운영 환경 적용 전 공식 문서 확인 필요

두 글자 이상 입력, 위아래 화살표로 이동하고 Enter로 열기