WAL에 대해 간단하게 알아보고, 정리해보았다.
개요 #
쓰기 전 로그(WAL
, Write Ahead Log)는 데이터를 저장(flush)하기 전에 순차적인 로그에 먼저 쌓는 방법으로, 장애 복구 뿐만 아니라 서버 쓰기 성능에도 도움을 준다.
데이터 저장 요청시, 이를 특정 형태로 append 전용 로그에 남기고(write), 이후에 실제 자료구조의 형태로 저장(flush)한다. 이러한 방법 덕분에 flush 과정에 문제가 생긴 경우, 쓰기 전 로그를 참고하여 다시 반영할 수 있다.
효용 #
-
장애 복구
특정 data를 저장해야하는 시점에 서버가 종료된 것을 가정하면, 서버는 재시작하더라도 해당 동작을 수행하지 못한다. WAL을 먼저 작성한다면 서버 재시작시 WAL의 내용을 역직렬화하여 반영하면 된다. 이는 여러 동작을 원자적으로 처리할 때에도 유용하게 사용된다.
-
쓰기 성능 향상
로그와 데이터 파일에 두 번 쓰는 구조이지만, 이를 잘 조합하면 의외로 쓰기 성능을 높일 수 있다. 여러 동작이 있을 때, 바로 반영하지 않고 WAL에 저장해놓았다가 실제 데이터 파일은 묶음(batch) 단위로 flush하여 잦은 IO를 최소화하여 쓰기 성능을 향상시키는 것이다.
문제점 & 고려사항 #
로그 파일 자체도 작성하다가 문제가 생길 수 있기 때문에, 로그 파일을 안전하게 관리해야한다. 이에 로그를 적절히 복제/분할하고, *로그 엔트리가 손상되었는지 확인하는 기법 (ex CRC, end-of-entry marker)*을 채택해야 한다.
또한, 재시도가 포함된 로그의 경우에는 해당 동작의 멱등성 또한 고려 대상일 것이다.
사례 - DB transaction #
transaction의 원칙인 ACID 중 Acid와 Durability는 WAL로 구현이 가능하다.
MySQL의 InnoDB
engine은 트랜잭션을 구현하는데에 redo log
라는 로그 파일을 두는데, 이게 일종의 WAL이다. transaction이 열리고 데이터 변경 내용은 redo log에 우선 append된다. 설정에 따라 다르지만 commit
시에 데이터를 저장하지 않고 redo log가 디스크에 안전하게 저장되었는지 여부만 확인하고, 실제 데이터는 나중에 저장될 것이다.
화이팅 !