로컬 UNDO와 임시 UNDO
CDB 전체가 UNDO를 공유하는 shared undo와 컨테이너마다 UNDO를 갖는 local undo의 확인과 전환, 임시 객체의 UNDO를 따로 기록하는 TEMP_UNDO_ENABLED
#핵심 요약
CDB의 UNDO 모드는 CDB 전체에 하나만 적용됨
모든 컨테이너가 shared undo(기본값)를 쓰거나 모두 local undo를 씀
현재 모드는 CDB 루트에서 DATABASE_PROPERTIES의 LOCAL_UNDO_ENABLED로 확인함
TRUE면 local undo, 아니면 shared undo임
모드를 바꾸려면 STARTUP UPGRADE로 올린 뒤 ALTER DATABASE LOCAL UNDO ON|OFF를 실행하고 재기동함
TEMP_UNDO_ENABLED=TRUE면 임시 객체 변경분의 UNDO를 임시 UNDO 로그로 따로 기록해 UNDO와 REDO 양을 줄임
기본값은 FALSE임
#개념과 동작 원리
#UNDO 모드
| 모드 | 의미 |
|---|---|
| shared undo | CDB$ROOT의 UNDO를 모든 PDB가 함께 씀CREATE DATABASE에서 UNDO 절을 지정하지 않으면 기본값 |
| local undo | 각 PDB가 자기 UNDO 테이블스페이스를 가짐 |
UNDO 모드는 CDB를 만들 때 CREATE DATABASE의 ENABLE PLUGGABLE DATABASE 절에서 정하거나, 만든 뒤 ALTER DATABASE와 재기동으로 바꿈
#임시 UNDO
기본적으로 트랜잭션 하나는 UNDO 로그 하나를 씀TEMP_UNDO_ENABLED를 켜면 임시 객체 변경분은 임시 UNDO 로그로, 영구 객체 변경분은 영구 UNDO 로그로 나뉨
결과적으로 데이터베이스 전체의 UNDO와 REDO 양이 줄어듦
전역 임시 테이블 같은 임시 객체를 쓰는 애플리케이션이면 TRUE를 권장함
ALTER SESSION과 ALTER SYSTEM으로 바꿀 수 있고 PDB에서도 바꿀 수 있음
세션에서 켜면 그 세션에 적용됨
설명: FALSE면 임시 테이블을 쓰더라도 UNDO가 일반 UNDO 테이블스페이스에 저장됨
#필수 명령어 또는 SQL
#UNDO 모드 확인
SELECT property_name, property_value
FROM database_properties
WHERE property_name = 'LOCAL_UNDO_ENABLED';결과 해석: 개별 실행 출력은 기재 없음
#UNDO 모드 변경 (shared undo로 전환)
SHUTDOWN IMMEDIATE
STARTUP UPGRADEALTER DATABASE LOCAL UNDO OFF;SHUTDOWN IMMEDIATE
STARTUP
ALTER PLUGGABLE DATABASE ALL OPEN;결과 해석:
공식 문서도 shared undo로 바꾸는 명령을 ALTER DATABASE LOCAL UNDO OFF로, local undo로 바꾸는 절차를 STARTUP UPGRADE로 시작하는 순서로 적음
local undo로 바꾸는 쪽은 LOCAL UNDO ON임
#임시 UNDO 확인과 켜기
SHOW PARAMETER temp_undo_enabledALTER SESSION SET temp_undo_enabled = TRUE;CREATE GLOBAL TEMPORARY TABLE emp_temp
(empno NUMBER, ename VARCHAR2(20))
ON COMMIT PRESERVE ROWS;결과 해석:
ON COMMIT PRESERVE ROWS는 커밋 뒤에도 세션이 끝날 때까지 행을 유지하는 전역 임시 테이블로 보이나 설명은 기재 없음
#임시 UNDO를 끄고 켤 때의 REDO 양 비교 (다른 실습 기록)
임시 테이블스페이스 절의 OCP 실습에서는 같은 전역 임시 테이블에 2만 행을 넣고 고치는 작업을 TEMP_UNDO_ENABLED FALSE와 TRUE에서 한 번씩 하고, 세션 통계를 비교했음
각 경우 새로 접속한 세션에서 실행했음
일반 사용자 세션임
CREATE GLOBAL TEMPORARY TABLE gtt_undo_test
(id NUMBER, txt VARCHAR2(100))
ON COMMIT PRESERVE ROWS;ALTER SESSION SET temp_undo_enabled = FALSE; -- 두 번째 실행에서는 TRUEINSERT INTO gtt_undo_test
SELECT ROWNUM, LPAD('x', 100, 'x') FROM dual CONNECT BY LEVEL <= 20000;
UPDATE gtt_undo_test SET txt = LPAD('y', 100, 'y');SELECT n.name, s.value
FROM v$mystat s, v$statname n
WHERE s.statistic# = n.statistic#
AND n.name IN ('redo size', 'undo change vector size');결과 해석:
| 설정 | 작업 전 redo size | 작업 후 redo size | 작업 후 undo change vector size |
|---|---|---|---|
TEMP_UNDO_ENABLED = FALSE |
수업 자료에 작업 전 조회 없음 | 4,204,772 | 3,955,408 |
TEMP_UNDO_ENABLED = TRUE |
712 | 992 | 3,704,620 |
값은 실습 SQL*Plus 세션 기록임
FALSE 쪽은 접속 직후 조회가 없어 정확한 증가분을 계산할 수 없음
실습의 해석은 다음과 같음
임시 UNDO를 켜도 UNDO 양은 거의 그대로이고 저장 위치만 TEMP로 바뀜
TEMP는 복구 대상이 아니어서 그 UNDO에 대한 REDO가 생기지 않으므로 REDO가 크게 줌
이 해석은 위 공식 문서(TEMP_UNDO_ENABLED, UNDO와 REDO 양 감소) 설명과 방향이 같음
#사용 조건과 주의사항
UNDO 모드 변경은 재기동이 두 번 필요한 서비스 중단 작업임
로컬 UNDO에서 각 PDB의 UNDO 테이블스페이스가 어떻게 만들어지는지는 기재 없음