454. 언두 (Undo) 세그먼트와 롤백
⚠️ 이 문서는 사용자가 "앗 실수!" 하고
ROLLBACK을 외쳤을 때 데이터베이스가 시간을 되돌릴 수 있게 해주고, 남들이 내가 수정 중인 데이터를 훔쳐보지 못하게 **수정 전의 '과거 데이터(원본)'를 몰래 복사해서 숨겨두는 마법의 휴지통인 '언두(Undo) 세그먼트'**를 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: 데이터베이스 엔진(InnoDB, Oracle 등)이 데이터를
UPDATE하거나DELETE하기 직전에, 원래 있던 옛날 값을 안전하게 대피시켜 두는 특수한 저장 공간이다.- 가치 1 (트랜잭션 롤백): 트랜잭션 도중 에러가 나거나 사용자가 취소를 눌렀을 때, 이 휴지통(Undo)에 있는 옛날 값을 꺼내서 진짜 디스크에 다시 덮어씌워 완벽한 원상 복구(Atomicity)를 이뤄낸다.
- 가치 2 (읽기 일관성): 다른 사용자가 내 데이터를 조회하려고 할 때, 내가 수정 중인 더러운 데이터(Dirty Data) 대신 이 휴지통에 있는 '깨끗한 과거 데이터'를 보여주어 MVCC(453번 문서)를 완성한다.
Ⅰ. 개요: 엎질러진 물 주워 담기 (Context & Necessity)
게시판의 글 번호 5번 제목이 [공지]였다.
관리자가 이 제목을 [긴급]으로 수정(UPDATE)했다. (아직 COMMIT은 안 한 상태)
만약 5번 글이 들어있던 하드디스크의 102번 방에 바로 [긴급]이라고 덮어써 버린다면?
- 갑자기 전원이 나가면 어떻게 다시
[공지]로 되돌릴 것인가? - 다른 사용자가 지금 게시판을 조회하면
[공지]를 보여줘야 할까, 아직 확정도 안 난[긴급]을 보여줘야 할까?
이 모든 딜레마를 해결하기 위해, DB 엔진은 102번 방을 [긴급]으로 고치기 0.001초 전에, 원래 있던 [공지]라는 글자를 '언두 세그먼트(Undo Segment)'라는 별도의 비밀의 방으로 먼저 옮겨놓는다.
📢 섹션 요약 비유: 언두 세그먼트는 **'포토샵의 Ctrl+Z(실행 취소) 역사 기록'**과 같습니다. 그림을 망쳤을 때 언제든 과거로 돌아갈 수 있게 해주고, 친구에게는 내가 그림을 완성하기 전의 '안전한 스케치본(읽기 일관성)'을 보여줄 수 있게 해주는 백업 창고입니다.
Ⅱ. 언두(Undo)와 리두(Redo)의 완벽한 비교 ★
DB 복구의 양대 산맥이다. (시험 출제율 1위)
| 구분 | Undo (언두) | Redo (리두) |
|---|---|---|
| 목적 | 🔄 과거로 되돌리기 (Rollback) | 🚀 미래로 다시 실행하기 (Roll Forward) |
| 저장 내용 | 수정되기 전의 데이터 (Old Value) | 수정된 후의 데이터 (New Value) |
| ACID 보장 | 원자성 (A) - 취소 보장 | 영속성 (D) - 정전 시 복구 보장 |
| 작동 예시 | A=10을 A=20으로 바꿨는데 취소할 때, Undo를 보고 10으로 돌려놓음 | A=20으로 고치고 Commit했는데 정전됨. 켤 때 Redo를 보고 20으로 살려냄 |
Ⅲ. ORA-01555: Snapshot Too Old 에러
오라클이나 MySQL을 운영할 때 DBA를 멘붕에 빠뜨리는 악명 높은 에러다. 이 에러는 언두 세그먼트(Undo Segment)의 '용량 부족' 때문에 발생한다.
- 원인:
- A가 아침 9시에
전체 고객 통계 엑셀 다운로드(SELECT)를 눌렀다. (데이터 1억 건, 3시간 걸림) - A가 엑셀을 다운받는 3시간 동안, B, C, D 직원들이 고객 데이터를 엄청나게
UPDATE해댔다. - DB는 A에게 '아침 9시 기준의 깨끗한 데이터'를 보여줘야 하므로(MVCC 스냅샷), B, C, D가 바꿀 때마다 옛날 데이터들을 언두 세그먼트에 계속 쌓아둔다.
- 근데 B, C, D가 너무 많이 바꿔서 언두 세그먼트 휴지통이 꽉 차버렸다.
- DB는 어쩔 수 없이 옛날 언두 데이터를 삭제하고 새 언두 데이터를 덮어쓴다.
- 엑셀 다운받던 A의 쿼리가 그 삭제된 언두 데이터를 읽으려다가 "헉! 내가 봐야 할 과거 데이터가 휴지통에서 지워졌네!"라며 뻗어버린다.
- A가 아침 9시에
- 해결책:
- 언두 세그먼트(테이블스페이스)의 물리적 하드디스크 용량을 늘린다.
- A의 통계 쿼리가 3시간이나 걸리지 않게(Long Transaction 제거) SQL 튜닝을 한다.
┌──────────────────────────────────────────────────────────────┐
│ 언두(Undo) 세그먼트를 활용한 읽기 일관성(MVCC) 시각화 │
├──────────────────────────────────────────────────────────────┤
│ │
│ [ 💾 디스크 원본 (데이터 파일) ] [ 🗑️ 언두 (Undo) 세그먼트 ] │
│ 사번 101: 잔액 5만 원 (더러움!) 사번 101: 잔액 10만 원 │
│ (현재 B가 10만->5만 수정 중) │
│ │
│ [ 👨💻 사용자 A (조회) ] "사번 101 잔액 얼마야?" │
│ │
│ 1. 디스크로 감 ──▶ "헉! B가 수정 중인 더러운(Dirty) 데이터네?" │
│ 2. 언두로 점프 ──▶ "여기 진짜 깨끗한 원본이 있군!" │
│ 3. 사용자 A에게 [ 10만 원 ] 리턴 완료 🟢 │
│ │
│ ★ 특징: 이 과정 덕분에 A는 B가 작업을 끝낼 때까지 멈춰서 기다릴 필요가 없다! │
└──────────────────────────────────────────────────────────────┘
Ⅳ. 결론
"휴지통이 없으면 마음 놓고 글을 쓸 수 없다."
데이터베이스 엔진이 수백만 건의 트랜잭션을 엉킴 없이 처리할 수 있는 이유는, 이 언두 세그먼트라는 거대한 '과거 보관소'가 보이지 않는 곳에서 충돌을 흡수해 주기 때문이다. 백엔드 개발자라면 @Transactional을 걸고 로직을 짤 때, 이 트랜잭션이 길어지면 길어질수록 DB의 언두 공간이 터져나가고 시스템 전체의 응답 속도가 박살 날 수 있다는 물리적 한계를 항상 인지해야 한다.
📌 관련 개념 맵
- 관련 특성: 원자성 (Atomicity - 441번 문서)
- 대칭 개념: Redo Log (리두 로그 - 444번 문서)
- 핵심 역할: 트랜잭션 롤백(Rollback), 읽기 일관성 (MVCC - 453번 문서)
- 튜닝 대상:
undo_retention(오라클 기준, 언두 데이터를 얼마나 오래 유지할 것인가 설정)
👶 어린이를 위한 3줄 비유 설명
- 동생이 내 그림일기장에 색연필로 마구 낙서를 하려고 해요! (UPDATE 진행 중)
- 다행히 내 일기장은 마법의 일기장(DB)이라, 동생이 낙서하기 0.1초 전에 원래 내 예쁜 그림을 복사해서 '비밀 서랍(언두 세그먼트)'에 쏙 넣어놨죠.
- 엄마가 오셔서 "원래 그림 내놔!" 하면 비밀 서랍에서 복사본을 꺼내 보여드리고(읽기 일관성), 동생이 도망가면 비밀 서랍에 있던 그림을 일기장에 다시 덮어붙여서(롤백) 완벽하게 고칠 수 있답니다!