테마
버퍼 풀과 로그
InnoDB가 데이터를 쓰는 경로 전체를 다룬다. 변경은 먼저 버퍼 풀(buffer pool)이라는 메모리 작업대에서 일어난다. 무엇을 바꿨는지는 리두 로그(redo log)에 적어 장애 뒤 다시 실행할 수 있게 하고, 바꾸기 전 값은 언두 로그(undo log)에 남겨 되돌릴 수 있게 한다. 여기에 보조 장치로 더블라이트 버퍼(doublewrite buffer)와 체인지 버퍼(change buffer)가 붙는다.
쓰기 한 방의 경로
다이어그램 로딩…
- 변경은 버퍼 풀에 올라온 페이지(page)에 먼저 반영된다. 디스크가 아니라 메모리를 고치므로 빠르다.
- 리두 로그에 "이렇게 바꿨다"를 기록한다. 기본 설정(
innodb_flush_log_at_trx_commit=1)에서는 트랜잭션(transaction)을 확정하는 커밋(commit)마다 리두 로그를 디스크까지 플러시(flush)한 뒤 응답한다. 이 값을 0이나 2로 낮추면 성능을 얻는 대신 최근 커밋을 잃을 수 있다. - 버퍼 풀에서 바뀌었지만 아직 디스크에 쓰이지 않은 페이지를 더티 페이지(dirty page)라 한다. 더티 페이지는 백그라운드에서 계속 데이터 파일로 내려간다. 체크포인트(checkpoint)는 데이터 파일에 "어디까지 반영됐는지"를 표시하는 기준점이다. 리두 로그 공간이 부족해지지 않도록 플러시 진도를 제어하는 것도 체크포인트의 몫이다.
- 언두 로그는 변경 전 버전을 보관한다. 트랜잭션을 취소하는 롤백(rollback)과 MVCC(Multi-Version Concurrency Control, 다중 버전 동시성 제어)의 과거 버전 읽기가 여기서 나온다.
로그별 역할 정리
| 로그 | 질문 | 용도 |
|---|---|---|
| 리두 로그 | "페이지를 어떻게 바꿨나" | 크래시 복구(crash recovery) 때 재실행. 순환 구조(circular)1라 백업 아님 |
| 언두 로그 | "하기 전 뭐였나" | 롤백 + MVCC 과거 버전 |
| 바이너리 로그(binary log) | "서버에서 무슨 일이" | 복제(replication)·시점 복구(point-in-time recovery). 서버 층이라 엔진 무관 |
리두 로그와 바이너리 로그를 헷갈리면 안 된다. 리두 로그는 InnoDB가 자기 페이지를 복구하려고 쓰는 내부 기록이다. 바이너리 로그는 MySQL 서버 층이 남기는 기록으로, 실행한 SQL 문장(statement) 또는 바뀐 행(row) 단위의 이벤트를 적어 복제와 시점 복구에 쓴다. MySQL 8.4의 기본은 바뀐 행을 적는 ROW 포맷이다(바이너리 로그 포맷과 동기화 방식). 바이너리 로그가 켜져 있으면 한 트랜잭션이 두 로그에 모두 기록된다. 그래서 둘의 커밋 여부가 어긋나지 않도록 2단계 커밋(two-phase commit)으로 맞춘다.
더블라이트와 체인지 버퍼
- 더블라이트 버퍼: 16KB 페이지는 더 작은 조각으로 나뉘어 디스크에 쓰일 수 있다. 쓰는 도중 서버가 죽으면 페이지 일부만 새 값으로 바뀌어 깨지는데, 이를 파셜 라이트(partial write)라 한다. 이를 막으려고 InnoDB는 페이지를 먼저 디스크의 별도 영역에 순서대로 통째로 써 두고, 그다음 원래 자리에 쓴다. 제자리 페이지가 깨졌으면 더블라이트 버퍼의 사본으로 복구한다.
- 체인지 버퍼: 세컨더리 인덱스(secondary index)를 바꿔야 하는데 해당 페이지가 버퍼 풀에 없을 때 쓰는 장치다. 디스크에서 페이지를 읽어 오지 않고 변경 내용만 적어 두고 나중에 병합한다. 읽기 없이 쓰기를 처리하므로 쓰기가 몰릴 때 유리하다. 단 PK(Primary Key, 기본 키)와 유니크 인덱스(unique index)는 값이 겹치는지 즉시 확인해야 해서 대상이 아니다.
- MySQL 8.4에서는
innodb_change_buffering기본값이none, 즉 체인지 버퍼를 쓰지 않는 것이다(8.0의 기본은 모든 변경을 모으는all). 켜려면 디스크 I/O(Input/Output, 입출력)가 줄어드는 이득만 보지 말고, 장애 복구·대량 적재·버퍼 풀 크기 변경 때 드는 비용까지 실제 서비스 부하로 검증해야 한다.
면접 포인트
- "커밋했는데 데이터 파일에 아직 없을 수 있나요?" → 그렇다. 기본 내구성 설정에서는 리두 로그가 먼저 디스크에 보장되고, 더티 페이지는 백그라운드 플러시와 체크포인트로 뒤따라간다.
- "리두 로그와 언두 로그의 차이?" → 재실행용 vs 되돌리기용. 한 문장으로.
- "파셜 라이트가 뭐예요?" → 페이지 쪼개 쓰기 중 장애 → 더블라이트 버퍼로 복구.
참고
정해진 크기의 공간을 끝까지 쓰면 앞부분부터 다시 덮어쓰는 구조. 이미 반영된 옛 기록은 사라지므로 과거 데이터를 되살리는 백업으로는 쓸 수 없다. ↩︎
