WAL 개요
WAL 이란?
Write-Ahead Logging (WAL) is a standard method for ensuring data integrity. A detailed description can be found in most (if not all) books about transaction processing. Briefly, WAL’s central concept is that changes to data files (where tables and indexes reside) must be written only after those changes have been logged, that is, after log records describing the changes have been flushed to permanent storage. If we follow this procedure, we do not need to flush data pages to disk on every transaction commit, because we know that in the event of a crash we will be able to recover the database using the log: any changes that have not been applied to the data pages can be redone from the log records. (This is roll-forward recovery, also known as REDO.)
– PostgreSQL 공식 문서 –
WAL은 데이터를 변경하기 전에 로그 파일에 먼저 쓰고, 그 이후에 실제 데이터 파일에 쓰는 방식입니다. 이를 통해 데이터베이스 시스템이 비정상적으로 종료되는 등의 상황에서도 데이터의 일관성과 안정성을 유지할 수 있습니다. 이는 특히 대규모 트랜잭션이나 복구 작업 등에서 중요한 역할을 합니다.

WAL 파일 구조
WAL 파일
WAL 파일은 WAL Record의 연속된 집합으로 이루어진 파일 입니다. WAL 파일 위치는 Data Cluster($PGDATA) 내부의 $PGDATA/pg_wal/ 디렉토리에 기록됩니다. WAL 파일 1개의 크기는 16MB이며, 항상 1개 이상의 WAL file이 존재하여야 합니다. WAL 파일의 이름은 16진수로 표현됩니다. 맨 앞의 8자리는 timeline-id, 그 다음의 16자리는 WAL 파일이 얼마나 생성되었는지 표시합니다.

WAL 관리
WAL 파일 개수 조정
WAL 파일들은 연속적인 이름을 가지고 지속적으로 생성 되지만, 디렉토리 안에 WAL 파일 전체의 크기가 일정 이상 늘어나면 이전에 생성된 WAL 파일들을 삭제 및 재활용 합니다.
postgresql.conf 파라미터를 통해 pg_wal 디렉토리에 있는 wal 파일의 총 개수를 조정할 수 있습니다.

WAL 관련 파라미터
WAL 파일 크기 조절
옵션 | 설명 |
---|---|
max_wal_size | WAL 디렉토리 안에 WAL 파일들의 총 용량 최대 크기를 지정할 수 있습니다. soft limit이기 때문에 특별한 상황에 초과할 수 있습니다. 기본값 1GB |
max_wal_size | 해당 값 이하로는 WAL파일을 정리하지 않습니다. (최초 생성이나 WAL RESET 상황은 제외합니다.) 기본값 80MB |
WAL _level 파라미터
WAL level 은 postgreSQL 서버를 다시 시작해야 변경 가능
wal_level | 설명 |
minimal | 복구를 위하여 필요한 정보를 제외하고 모든 logging을 제거합니다. archive_mode를 지원하지 않습니다. |
replica | WAL 아카이브 보관 및 복제를 지원하기에 충분한 데이터를 기록합니다. 설정하지 않았다면 기본적으로 WAL level은 replica 입니다. |
logical | logical decoding을 지원하는 데 필요한 정보를 추가적으로 기록합니다. logical replication을 사용하려면 logical로 설정해야 합니다. |
WAL 파일 크키 변경
WAL 파일은 기본적으로 16MB 이지만, 명령어 initdb 과정 혹은 pg_resetwal을 통하여 크기를 변경할 수 있습니다.
initdb 과정에서 —wal-segsize=<segment_size> 옵션을 통하여 WAL 파일의 크기를 지정할 수 있습니다. 이때 <segment_size>는 MB 단위 입니다.
$ initdb -U postgres -D $PGDATA -X /opensql/pg/$PGVERSION/pg_wal –wal-segsize=32

$ ls -al /opensql/pg/$PGVERSION/pg_wal

pg_resetwal 명령어는 WAL file 들을 깨긋하게 정리하고, pg_control 파일에 있는 여러 정보들을 재설정 할 수 있습니다. 해당 명령어는 postgreSQL 서버를 정지시키고 실행 하셔야 합니다.
pg_resetwal을 사용하면 기존의 wal file도 없어지기 때문에 주의합니다.
$ pg_ctl stop
$ pg_resetwal -D /opensql/pg/14/data –wal-segsize=16

$ ls -al /opensql/pg/$PGVERSION/pg_wal

Archiving WAL 파일
Archive
archive 파일은 archive mode가 활성화되어 있으면 설정된 archive 디렉토리에 WAL 파일을 복사합니다.
설정한 ‘archive_command’ 을 기준으로 archive가 실행되는데 일반적으로 Unix 명령 cp로 파일을 복사합니다.

Archive 관련 파라미터
옵션 | 설명 |
---|---|
archive_mode | archive 모드를 사용할 수 있습니다. 모드를 변경하려면 재시작 해야합니다. 기본값 off |
archive_command | archive 모드를 사용하면 archiving 될 때, 이 커맨드를 실행합니다. %p 는 archive로 복사될 대상이 될 파일의 경로이고, %f 는 archive 파일명 입니다. |
ex) archive_command=‘test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f’ | |
archive_timeout | 해당 파라미터를 사용하여 초(s)단위로 WAL Segment file을 전환하여 아카이빙할 수 있도록 지원합니다. |
Archive 실습
archive mode 활성화 및 archive_command 설정
$ vi $PGDATA/postgresql.conf
….
archive_mode=on
archive_command=’test ! -f /opensql/pg/14/archive/%f && cp %p /opensql/pg/14/archive/%f’
….$ pg_ctl start


Test Table 생성 및 WAL 파일 Switching
$ psql -c “CREATE TABLE archive_test(c1 text); “
$ psql -c “SELECT pg_switch_wal();”
$ ls -al /opensql/pg/14/archive

WAL 함수
- pg_switch_wal()
- 새로운 WAL 파일로 전환
- RETURN : LSN + 1
- pg_walfile_name(lsn)
- 해당 LSN에 해당되는 WAL File의 이름을 반환
- RETURN : [text] WAL file 이름
- pg_current_wal_lsn()
- 현재 WAL에 마지막으로 기록된 LSN을 반환
- RETURN : [pg_lsn]
- pg_ls_waldir()
- 현재 WAL 디렉토리의 WAL 파일들에 대한 정보를 조회
- RETURN : WAL File 이름, WAL File Size, 마지막 업데이트 시간(timezone)
WAL 함수 실습
- WAL에 마지막으로 기록된 LSN 조회
$ SELECT pg_current_wal_lsn();

- 특정 LSN의 WAL 파일 이름 조회
$ SELECT pg_walfile_name(pg_current_wal_lsn());

- 현재 쓰고 있는 WAL 파일 이름 조회
$ SELECT pg_walfile_name(pg_current_wal_lsn());
- 현재 WAL 디렉토리(pg_wal) 내의 WAL 파일 정보 조회
- 현재 WAL 디렉토리(pg_wal) 내의 WAL 파일 정보 조회
$ SELECT pg_walfile_name(pg_current_wal_lsn());
지금까지 PostgreSQL의 ‘WAL’에 관해 알아보았습니다
‘PostgreSQL Parameter’를 바로 이어서 확인해보세요!