본문 바로가기
삵
Cloud Computing & MSA

PostgreSQL 17 네이티브 증분 백업

아아무로레이·2026년 11월 6일·조회 0

매일 밤 pg_basebackup으로 전체 클러스터를 통째로 복사하던 운영 서버가 있었다. 데이터가 수백 GB로 불어나니 백업 한 번에 디스크와 네트워크가 꽤 오래 묶였다. 그동안은 WAL 아카이빙과 PITR로 중간 복구 지점을 메웠는데, 백업 자체를 가볍게 줄일 방법은 없었다. PostgreSQL 17에 증분 백업이 서버 네이티브 기능으로 들어오면서 이 부분이 달라졌다.

핵심만 먼저 적으면, PostgreSQL 17은 summarize_wal을 켜 WAL 요약 파일을 만들고, pg_basebackup --incremental로 직전 백업 이후 변경된 블록만 받는다. 복원할 때는 전체 백업과 증분 백업들을 pg_combinebackup으로 합쳐 하나의 완전한 데이터 디렉터리로 만든 뒤 그 위에서 서버를 띄운다. 증분 백업 파일 자체로는 직접 기동할 수 없다.

먼저 용어 몇 개를 짚는다. WAL summarizer는 PostgreSQL 17에 추가된 백그라운드 프로세스로, WAL을 읽어 "어떤 블록이 바뀌었는지"만 추려 요약 파일(pg_wal/summaries)로 남긴다. 증분 백업은 이 요약을 근거로 변경 블록을 골라낸다. backup_manifest는 백업 디렉터리 안에 생기는 파일 목록 겸 체크섬 명세인데, 다음 증분 백업이 "어디를 기준으로 삼을지"를 가리키는 기준점 역할을 한다. 전체 백업 하나에 증분 백업 여러 개가 사슬처럼 이어진 것을 백업 체인이라 부른다.

summarize_wal 켜기, 재시작은 필요 없다

증분 백업의 전제는 WAL 요약이다. summarize_wal은 기본값이 off라 먼저 켜야 한다. 이 파라미터는 postgresql.conf 또는 서버 커맨드라인에서 설정하는 SIGHUP 파라미터다. 서버 재시작 없이 reload만으로 반영된다.

sarc=# ALTER SYSTEM SET summarize_wal = on;
ALTER SYSTEM
sarc=# SELECT pg_reload_conf();
 pg_reload_conf
----------------
 t
(1 row)

sarc=# SHOW summarize_wal;
 summarize_wal
---------------
 on
(1 row)

reload 직후 walsummarizer 프로세스가 올라온다. 상태는 pg_get_wal_summarizer_state()로 확인한다. summarizer_pid에 값이 잡히고 summarized_lsn이 전진하면 정상 기동한 것이다.

sarc=# SELECT * FROM pg_get_wal_summarizer_state();
 summarized_tli | summarized_lsn | pending_lsn | summarizer_pid
----------------+----------------+-------------+----------------
              1 | 0/5000060      | 0/5000060   |           4821
(1 row)

요약 파일이 실제로 쌓이는지는 pg_available_wal_summaries()로 본다. 각 행이 요약이 커버하는 LSN 구간이다. 증분 백업은 기준 백업의 끝 LSN부터 현재까지의 구간을 이 요약들이 빠짐없이 덮고 있어야 성립한다.

sarc=# SELECT * FROM pg_available_wal_summaries();
 tli | start_lsn | end_lsn
-----+-----------+-----------
   1 | 0/4000028 | 0/5000060
(1 row)

한 가지 전제가 있다. wal_level이 minimal이면 증분 백업을 쓸 수 없다. 공식 문서에 따르면 summarize_wal=on 상태로는 wal_level=minimal인 서버가 아예 기동을 거부한다. 서버가 뜬 뒤에 minimal인 채로 summarize_wal을 켜면 summarizer는 돌지만 minimal로 생성된 WAL에 대해서는 요약 파일 생성을 거부한다. 복제를 쓰는 환경이라면 wal_level이 이미 replica 이상일 테니 문제될 일은 적다. 확인만 해 둔다.

sarc=# SHOW wal_level;
 wal_level
-----------
 replica
(1 row)

전체 백업 한 번, 그다음은 변경분만

증분 백업의 기준점이 되는 전체 백업을 평소대로 한 번 받는다. 디렉터리 안에 backup_manifest가 함께 만들어진다. 이 파일이 다음 증분 백업의 입력이 된다.

$ pg_basebackup -D /backup/full -c fast -P
 1392081/1392081 kB (100%), 1/1 tablespace
$ ls /backup/full/backup_manifest
/backup/full/backup_manifest

이후 백업은 --incremental에 직전 백업의 manifest 경로를 넘긴다. 전송량을 보면 차이가 분명하다. 전체 백업이 1.3GB대였는데 증분은 변경 블록만 담아 수십 MB 수준으로 떨어진다. 실제 크기는 그사이 변경량에 비례하므로 워크로드에 따라 다르다.

$ pg_basebackup -D /backup/incr1 \
    --incremental=/backup/full/backup_manifest -c fast -P
   24576/24576 kB (100%), 1/1 tablespace

체인을 더 길게 가져갈 때는 두 가지 방식을 쓸 수 있다. 증분 백업마다 바로 앞 증분의 manifest를 참조하면 사슬이 길게 이어진다. 매번 전체 백업의 manifest를 참조하면 전체 백업 이후 누적 변경분을 담는 차등 백업이 된다. 앞 방식은 백업이 가볍지만 복원할 때 중간 백업이 하나라도 빠지면 복원이 안 된다. 뒤 방식은 복원이 단순한 대신 시간이 갈수록 증분 크기가 커진다.

$ pg_basebackup -D /backup/incr2 \
    --incremental=/backup/incr1/backup_manifest -c fast -P
   31744/31744 kB (100%), 1/1 tablespace

pg_combinebackup으로 합성 풀백업 만들기

증분 백업 디렉터리를 그대로 데이터 디렉터리로 쓰고 서버를 띄우려 하면 실패한다. 증분 백업은 블록 조각이지 완전한 클러스터가 아니기 때문이다. pg_combinebackup이 전체 백업과 증분들을 합쳐 하나의 완전한 데이터 디렉터리를 합성해 준다.

인자 순서가 중요하다. 가장 오래된 전체 백업을 맨 앞에 두고, 복원하려는 시점의 마지막 증분 백업을 맨 뒤에 둔다. 그사이 체인에 속한 백업을 전부 순서대로 나열한다. 결과를 쓸 디렉터리는 -o로 지정하며, 이 옵션은 필수다.

$ pg_combinebackup \
    /backup/full \
    /backup/incr1 \
    /backup/incr2 \
    -o /backup/restored
$ ls /backup/restored/PG_VERSION
/backup/restored/PG_VERSION

성공하면 /backup/restored에 완전한 데이터 디렉터리가 생긴다. 여기에 복구 설정을 넣고 서버를 기동하면 된다. pg_combinebackup은 넘긴 백업들이 올바른 체인을 이루는지 먼저 검증한다. 중간 백업이 빠졌거나 순서가 틀리면 합성 단계에서 바로 멈춘다. 개별 백업의 무결성은 pg_verifybackup으로 따로 점검한다.

$ pg_verifybackup /backup/full
backup successfully verified

합성 결과물은 다시 다음 pg_combinebackup의 입력으로 재사용할 수 있다. 증분을 길게 쌓아 왔다면 주기적으로 합성해 새 "기준 전체 백업"으로 삼고 체인을 끊어 주면 복원 시간과 체인 길이를 동시에 관리할 수 있다.

체인이 끊어지는 자리

증분 백업 운영에서 걸리는 지점은 대부분 체인과 요약 보존 두 군데다.

첫째, 전체 백업이나 중간 증분 백업을 지우면 그 뒤 증분들이 전부 무용지물이 된다. 전체 백업을 받았다고 안심하고 기준 백업을 정리하는 실수가 여기 해당한다. 증분은 반드시 기준 백업과 한 묶음으로 보관해야 한다.

둘째, WAL 요약 파일의 보존 기간이다. wal_summary_keep_time이 오래된 요약을 자동 삭제하는데 기본값은 10일이다. 기준 백업과 다음 증분 백업 사이 간격이 이 기간을 넘기면, 증분에 필요한 요약이 이미 삭제되어 백업이 실패할 수 있다. 주간 전체 백업에 2주 간격 증분을 섞는 식이라면 보존 기간을 늘려 둔다.

sarc=# ALTER SYSTEM SET wal_summary_keep_time = '30d';
ALTER SYSTEM
sarc=# SELECT pg_reload_conf();
 pg_reload_conf
----------------
 t
(1 row)

셋째, 타임라인이다. 장애 복구나 승격으로 타임라인이 바뀌면 기존 체인의 기준점과 어긋날 수 있다. 복제 토폴로지를 바꾸거나 복구를 수행한 뒤에는 증분을 이어 붙이지 말고 새 전체 백업부터 체인을 다시 시작하는 편을 권한다.

증분 백업이 WAL 아카이빙 기반 PITR을 대체하는 것은 아니다. 증분은 전체 백업을 가볍게 받는 수단이고, 임의 시점 복구는 여전히 WAL 아카이브가 담당한다. 둘을 함께 굴리면 백업 부담은 줄이면서 복구 지점의 세밀함은 그대로 유지한다. 다음으로 점검할 것은 전체 백업 주기와 증분 체인 길이를 복원 목표 시간(RTO)에 맞춰 잡는 일이다. 체인이 길수록 pg_combinebackup에 걸리는 시간도 늘어나므로, 복원 시간을 한 번 실측해 두고 주기를 결정한다.

자주 묻는 질문

summarize_wal을 켜려면 서버를 재시작해야 하나?

아니다. summarize_wal은 SIGHUP 파라미터라 ALTER SYSTEM SET summarize_wal = on 후 SELECT pg_reload_conf()만으로 반영된다. reload 직후 walsummarizer 프로세스가 기동한다. postgresql.conf나 서버 커맨드라인에서만 설정 가능하다는 문서 문구는 재시작 전용이라는 뜻이 아니라 reload로 반영된다는 의미다.

증분 백업 디렉터리만 가지고 바로 서버를 띄울 수 있나?

없다. 증분 백업은 변경 블록 조각이라 그 자체로는 완전한 클러스터가 아니다. pg_combinebackup으로 전체 백업과 체인상의 증분들을 모두 합쳐 합성 풀백업 디렉터리를 만든 뒤 그 위에서 기동해야 한다.

wal_level이 minimal이면 증분 백업이 되나?

안 된다. summarize_wal=on인 상태에서는 wal_level=minimal인 서버가 기동 자체를 거부한다. 서버 기동 후 minimal인 채로 summarize_wal을 켜면 summarizer는 돌지만 minimal로 생성된 WAL의 요약 파일 생성을 거부한다. 증분 백업을 쓰려면 wal_level을 replica 이상으로 둬야 한다.

증분 백업이 갑자기 실패하면 어디를 보나?

먼저 wal_summary_keep_time을 확인한다. 기본값 10일을 넘겨 기준 백업 시점의 WAL 요약이 삭제됐으면 증분이 성립하지 않는다. pg_available_wal_summaries()로 필요한 LSN 구간이 요약에 남아 있는지 보고, 넘긴 manifest가 올바른 기준 백업의 것인지, 체인 중간 백업이 빠지지 않았는지 점검한다.

증분 백업을 쓰면 WAL 아카이빙과 PITR은 버려도 되나?

아니다. 증분은 전체 백업을 가볍게 받는 수단일 뿐이고, 임의 시점 복구는 WAL 아카이브가 담당한다. 두 기능은 역할이 다르므로 함께 운영한다. 증분으로 백업 부담을 줄이고 WAL 아카이브로 복구 지점의 세밀함을 유지하는 구성을 권한다.

관련 글

댓글 0

로그인 후 댓글을 남길 수 있습니다.

아직 댓글이 없습니다.