WAL(Write-Ahead Logging) 알아보기 1편 - 버퍼 풀 관리 정책

머랭·2026년 1월 14일
post-thumbnail

0. 서론

글의 목적

안녕하세요 머랭입니다.
데이터베이스를 사용하는 애플리케이션을 개발하다 보면 수많은 트랜잭션을 커밋하게 됩니다.
그런데, 여러분이 커밋한 트랜잭션이 실제로 디스크에 반영되지 않았을 수 있다는 사실을 알고 계신가요?

디스크에 반영한다는 것은, 랜덤 I/O가 발생한다는 의미입니다.
만약 모든 트랜잭션마다 랜덤 I/O가 발생한다면, DBMS의 처리량은 매우 낮을 것입니다.
MySQL의 InnoDB는 이런 문제를 어떻게 해결했을까요?
몇 개의 포스팅을 통해 InnoDB가 높은 처리량을 보장하면서도 ACID를 지킬 수 있도록 하는 핵심 기술인 WAL(Write-Ahead Logging)에 대해 이야기해보고자 합니다.

이번 포스팅에서는 WAL(Write-Ahead Logging)을 이해하기 위해 필요한 핵심 개념인 InnoDB의 버퍼 풀 관리 정책에 대해 설명드리겠습니다.

대상 독자

  1. Undo Log와 Redo Log에 대해서 들어봤지만, 확실하게 알지 못하는 개발자
    • Undo Log와 Redo Log가 무슨 역할을 하는지, 왜 존재하는지 이해할 수 있습니다.
  2. InnoDB가 페이지를 어떻게 관리하는지 궁금한 개발자
    • 추상적인 DML 뒤에서 InnoDB 스토리지 엔진이 페이지를 어떻게 관리하는지 이해할 수 있습니다.

이번 글을 통해 얻어갈 수 있는 것들

  1. InnoDB가 효율적인 I/O를 위해 선택한 페이지 관리 방식에 대해 이해할 수 있습니다.
  2. 트랜잭션이 커밋된 후 디스크에 반영되기까지의 과정을 이해하고 설명할 수 있게 됩니다.
  3. InnoDB가 택한 버퍼 관리 정책의 심각한 문제점들을 인지하게 됩니다.

1. 버퍼(버퍼 풀)

데이터베이스의 가장 큰 병목은 언제나 디스크 I/O, 특히 랜덤 I/O 입니다.
버퍼는 디스크 I/O를 최소화하기 위해 페이지를 메모리(RAM)에 캐싱해두는 공간입니다.

InnoDB는 변형된 LRU 알고리즘을 통해 버퍼를 관리합니다.
변형된 LRU 알고리즘이 궁금하다면? MySQL InnoDB 공식 문서

  • 데이터 캐시: 자주 쓰이는 데이터를 메모리에 올려두어 디스크 I/O 없이 바로 응답합니다.
  • 쓰기 지연: 데이터를 변경할 때 즉시 디스크에 기록하지 않고, 버퍼에서 먼저 변경한 뒤 Page Ceaner가 백그라운드에서 디스크에 기록합니다.

Page Cleaner

Page Cleaner는 InnoDB의 백그라운드 스레드로, 버퍼에 있는 더티 페이지들을 주기적으로 디스크로 플러시(Flush)하여 데이터 손실을 방지하고 버퍼 풀 공간을 확보하는 역할을 합니다.


2 버퍼 관리 정책

2.1 STEAL / No-STEAL

STEAL / No-STEAL 정책은 트랜잭션이 진행 중(커밋 전)일 때, 버퍼에 존재하는 수정된 페이지를 디스크에 미리 쓸 수 있는지 여부를 결정합니다.

STEAL

트랜잭션의 진행 여부와 관계없이, 수정된 페이지를 언제든지 디스크에 쓸 수 있는 정책입니다.
버퍼가 부족하면, 버퍼 관리자는 아직 완료되지 않은 트랜잭션이 수정한 페이지라도 디스크에 기록하고 버퍼를 비울 수 있습니다.
아직 커밋되지 않은 데이터가 디스크에 존재하게 됩니다.

InnoDB를 포함한 대부분의 스토리지 엔진이 이 정책을 사용합니다.

한정된 버퍼를 효율적으로 사용할 수 있습니다.

No-STEAL

트랜잭션이 종료(커밋)될 때까지는 수정된 페이지를 절대 디스크에 쓰지 않는 정책입니다.
변경된 페이지를 계속해서 버퍼에 유지합니다.
디스크에는 항상 커밋된 데이터만 존재하게 됩니다.

트랜잭션이 다루는 데이터가 매우 크면 그만큼 엄청난 양의 메모리 버퍼가 필요해집니다.


2.2 FORCE / No-FORCE

FORCE / No-FORCE 정책은 트랜잭션이 커밋되는 시점수정된 모든 페이지를 반드시 디스크에 반영해야 하는지 여부를 결정합니다.

FORCE

매 트랜잭션이 커밋되는 시점에 수정했던 모든 페이지를 디스크에 즉시 반영하는 정책입니다.
커밋 직후 장애가 발생해도, 이미 디스크 쓰기가 완료된 상태이므로 복구가 필요 없습니다.

매 트랜잭션 커밋 시마다 랜덤 I/O가 발생하므로, 성능이 매우 떨어집니다.

No-FORCE

트랜잭션이 커밋되어도 수정된 페이지를 디스크에 즉시 반영하지 않는 정책입니다.
InnoDB를 포함한 대부분의 스토리지 엔진이 이 정책을 사용합니다.

랜덤 I/O 횟수가 크게 감소합니다.


3. 버퍼 관리 정책의 문제점

InnoDB를 포함한 대부분의 스토리지 엔진은 STEAL & No-FORCE 정책을 사용합니다.

한정된 버퍼를 효율적으로 사용하기 위해 STEAL 정책을 사용합니다.
랜덤 I/O를 최소화하기 위해 No-FORCE 정책을 사용합니다.

그러나, 두 정책을 사용하게 되면 더티 페이지가 실제 DB에 반영되는 시점과 단위가 모호해지기 때문에 Atomicity와 Durability를 보장할 수 없게 됩니다.

3.1 STEAL - Atomicity 위반

STEAL 정책은 버퍼를 효율적으로 사용하기 위해, 아직 커밋되지 않은 페이지를 디스크에 반영합니다.
이로 인해 장애 발생 시 Atomicity를 보장할 수 없습니다.

시나리오

1. 트랜잭션 시작 및 페이지 수정
디스크에서 페이지를 읽어와 버퍼 풀에서 데이터를 수정합니다.
수정할 페이지가 많아 수정 중간에 버퍼는 더티 페이지로 가득 찼습니다.

2. STEAL 발생
아직 데이터 수정이 더 필요합니다.
이때, STEAL 정책에 의해 Page Cleaner가 동작해 아직 커밋되지 않은 페이지를 디스크에 작성합니다.

3. 갑작스러운 장애 발생
나머지 데이터를 수정하던 중, 갑자기 서버가 다운되었습니다.
트랜잭션은 커밋되지 못하고 비정상 종료되었습니다.

4. 재부팅 후 Atomicity 위반
트랜잭션은 실패했으므로 데이터는 수정 전으로 롤백되어야 합니다.
그러나, Page Cleaner가 디스크에 작성한 페이지까지만 디스크에 반영되어있습니다.


3.2 No-FORCE - Durability 위반

No-FORCE 정책은 랜덤 I/O를 최소화하기 위해, 트랜잭션이 커밋되어도 수정된 페이지를 디스크에 즉시 반영하지 않고 한 번에 Flush합니다.

시나리오

1. 트랜잭션 시작 및 커밋
트랜잭션 커밋 시, 변경된 페이지는 더티 페이지 상태로 버퍼에만 존재합니다.
더티 페이지가 실제로 디스크에 반영되는 것을 기다리지 않습니다.
버퍼에 반영되었으니 트랜잭션 커밋은 성공적으로 이루어집니다.

2. 갑작스러운 장애 발생
Page Cleaner가 더티 페이지들을 디스크에 작성하기 전, 갑자기 서버가 다운되었습니다.
버퍼는 RAM에 존재하므로, 버퍼에 존재하던 더티 페이지는 유실됩니다.

3. 재부팅 후 Durability 위반
트랜잭션은 성공했었으므로, 재부팅 후에도 성공 상태로 남아있어야 합니다.
그러나, 버퍼 유실로 인해 디스크에는 커밋 전 데이터만 존재합니다.


마치며

이번 포스팅에서는 랜덤 I/O로 인한 병목을 해결하기 위해 InnoDB가 도입한 버퍼, 이를 관리하는 Page Cleaner의 역할을 살펴보았습니다.
또한, 버퍼를 관리하기 위한 정책인 STEAL / No-STEAL 그리고 FORCE / No-FORCE에 대해 알아보았습니다.
InnoDB를 포함한 대부분의 스토리지 엔진은 STEAL & No-FORCE 정책을 사용합니다.

STEAL & No-FORCE 정책은 버퍼를 효율적으로 사용하고 랜덤 I/O를 최소화한다는 장점이 있지만, Atomocity와 Durability를 보장하지 못한다는 치명적인 단점이 존재합니다.

다음 포스팅에서는, InnoDB가 이 단점들을 어떻게 해결했는지 알아보도록 하겠습니다.
끝까지 읽어주셔서 감사합니다.

참고 문서
https://dev.mysql.com/doc/refman/8.4/en/innodb-buffer-pool.html
MySQL 8.4 Glossary

https://d2.naver.com/helloworld/407507
DBMS는 어떻게 트랜잭션을 관리할까? - 오이석|NBP 서비스플랫폼개발센터

https://tech.kakao.com/posts/721
MySQL InnoDB Log에 대한 이해 - (1) - christy.seo, sun.j

profile
동작보단 원리를 좋아하는 머랭의 블로그입니다.

0개의 댓글