본문 바로가기
Amazon Web Services

PostgreSQL 17 네이티브 증분 백업 - pg_basebackup --incremental로 뜨고 pg_combinebackup으로 복구본 합성하기

아무로레이·2026년 9월 1일·조회 1

EC2에서 직접 굴리는 PostgreSQL의 백업 스크립트를 손보다가, 그동안 pg_basebackup으로 매번 전체본을 통째로 떠오던 게 눈에 걸렸다. DB가 수백 GB로 커지면 이 전체 백업 한 번이 스토리지와 시간을 크게 잡아먹는다. 그래서 예전에는 pgBackRest 같은 외부 도구를 붙여 증분을 뜨곤 했는데, PostgreSQL 17부터는 이 기능이 코어 안으로 들어왔다. 이번 글은 그 네이티브 증분 백업을 실제로 돌려본 기록이다.

정리부터 하자면, PostgreSQL 17의 증분 백업은 서버에서 summarize_wal을 켜 두고, pg_basebackup --incremental=이전_backup_manifest로 이전 백업 이후 바뀐 블록만 떠서 용량과 시간을 줄이는 방식이다. 증분본은 그 자체로는 복구할 수 없고, pg_combinebackup으로 전체 백업과 합쳐 복구용 전체본을 만들어야 데이터 디렉터리로 쓸 수 있다. 아래에서 개념, 서버 준비, 전체와 증분 백업, 합성, 검증 순서로 살펴본다.

1. 증분 백업이 무엇이고 PostgreSQL 17에서 왜 생겼나

증분 백업은 직전 백업 이후에 바뀐 데이터 블록만 저장하는 백업이다. 전체 백업이 모든 파일을 그대로 복사하는 것과 달리, 변경분만 담으므로 백업 크기가 작고 완료도 빠르다. 대신 복구할 때 전체본과 증분본을 다시 합쳐야 한다.

여기서 핵심 장치가 WAL 요약(WAL summary)이다. WAL은 PostgreSQL이 모든 변경을 먼저 기록하는 트랜잭션 로그인데, PostgreSQL 17은 이 WAL을 훑어 "어느 릴레이션의 어느 블록이 바뀌었는지"를 요약 파일로 만들어 pg_wal/summaries 디렉터리에 쌓아 둔다. 이 일을 하는 백그라운드 프로세스가 WAL summarizer다. 증분 백업을 요청하면 서버는 이 요약을 참고해 바뀐 블록만 골라 보낸다.

공식 문서는 이 점을 분명히 한다. 필요한 요약 파일이 없으면 증분 백업 시도는 실패한다. "요약 파일은 직전 백업의 시작 LSN부터 이번 백업의 시작 LSN까지의 모든 LSN을 덮어야 한다"는 게 요구 조건이다. LSN은 WAL 상의 위치를 가리키는 로그 시퀀스 번호다.

2. 서버 준비: summarize_wal 켜기

WAL summarizer는 기본으로 꺼져 있다. summarize_wal의 기본값이 off라서, 이걸 켜지 않으면 요약 파일이 쌓이지 않고 증분 백업도 안 된다. 다행히 이 파라미터는 sighup 컨텍스트라 재시작 없이 설정 리로드만으로 적용된다.

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)

WAL summarizer 프로세스가 떴는지도 확인해 두면 깔끔하다.

$ ps -ef | grep 'walsummarizer' | grep -v grep
postgres  4123  4110  0 10:02 ?  00:00:00 postgres: walsummarizer

주의할 조건이 하나 있다. wal_levelminimal이면 summarize_walon으로 둬도 summarizer가 요약 파일을 만들지 않는다. 증분 백업을 쓸 서버라면 wal_levelreplica 이상이어야 한다.

요약 파일 보관 기간도 같이 챙긴다. wal_summary_keep_time의 기본값은 10일이다. 이 값은 전체 백업과 그에 딸린 증분 백업 사이에 벌어질 수 있는 시간보다 넉넉하게 잡아야 한다. 요약이 먼저 지워지면 증분 백업이 실패하기 때문이다. 주 단위로 전체를 뜨고 매일 증분을 뜬다면 10일도 빠듯할 수 있으니 여유 있게 늘려 둔다.

sarc=# ALTER SYSTEM SET wal_summary_keep_time = '30d';
ALTER SYSTEM
sarc=# SELECT pg_reload_conf();

3. 기준이 될 전체 백업 한 번 뜨기

증분은 항상 어떤 기준 백업을 참조한다. 그 기준의 시작점이 전체 백업이다. 평소대로 pg_basebackup으로 전체본을 뜬다. 버전 번호는 저장소 상태에 따라 다를 수 있다.

$ pg_basebackup --version
pg_basebackup (PostgreSQL) 17.5
$ pg_basebackup -h 127.0.0.1 -U repl -D /backup/full_0901 -c fast -P
 512000/512000 kB (100%), 1/1 tablespace

백업 디렉터리 안에 backup_manifest가 생겼는지 본다. 이 매니페스트가 다음 증분 백업의 기준 파일이 된다.

$ ls /backup/full_0901/backup_manifest
/backup/full_0901/backup_manifest

매니페스트는 WAL 파일을 뺀 백업 내 모든 파일의 크기, 마지막 수정 시각, 체크섬을 담는다. --no-manifest로 생성을 끌 수도 있지만, 그러면 이 백업을 기준으로 삼는 증분을 못 뜬다. 증분 체인의 출발점이 될 전체 백업에서는 매니페스트를 끄지 마라.

4. 증분 백업 뜨기

이제 변경분만 뜬다. -i(또는 --incremental)에 직전 백업의 backup_manifest 경로를 넘긴다. 이 매니페스트는 서버로 업로드되고, 서버는 그 이후 바뀐 블록만 담은 증분 백업을 돌려준다.

$ pg_basebackup -h 127.0.0.1 -U repl \
    -D /backup/incr_0902 \
    --incremental=/backup/full_0901/backup_manifest \
    -c fast -P
 41216/41216 kB (100%), 1/1 tablespace

전체본이 500MB대였는데 증분본은 수십 MB 수준으로 떨어지는 걸 볼 수 있다. 실제 절감폭은 그날 얼마나 많은 블록이 바뀌었느냐에 달려 있어 환경에 따라 다르지만, 변경이 적은 날일수록 증분본은 작아진다.

여기서 한 번 걸리기 쉽다. summarizer가 아직 최근 WAL을 요약하지 못했거나 필요한 요약이 이미 지워졌으면 다음처럼 실패한다.

pg_basebackup: error: could not initiate base backup:
  ERROR:  WAL summaries are required on timeline 1 from ... but no summaries
  for that timeline and LSN range exist

서버는 없는 요약 파일이 나타날 때까지 기다려 주기도 한다. summarizer가 뒤처진 경우라면 잠시 뒤 다시 시도하면 된다. 하지만 wal_summary_keep_time이 지나 요약이 삭제됐다면 그 기준으로는 더 이상 증분을 못 뜬다. 이때는 전체 백업부터 다시 떠야 한다.

다음 증분을 또 뜰 때는 기준을 방금 뜬 증분본의 매니페스트로 바꾼다. 이렇게 하면 전체 하나에 증분이 사슬처럼 이어지는 체인이 된다.

$ pg_basebackup -h 127.0.0.1 -U repl \
    -D /backup/incr_0903 \
    --incremental=/backup/incr_0902/backup_manifest \
    -c fast -P

5. pg_combinebackup으로 복구용 전체본 합성하기

증분본은 그대로는 복구에 쓸 수 없다. 문서에도 못을 박아 뒀다. 증분 백업은 직접 복원할 수 없으며 pg_combinebackup으로 앞선 백업들과 합쳐야 한다. 이 도구는 전체본과 그 뒤로 이어진 증분본들을 받아 하나의 합성 전체본(synthetic full backup)을 만들어 낸다.

인자로 넘기는 백업 디렉터리 순서가 중요하다. 오래된 것부터 최신 순으로, 즉 전체본을 맨 앞에, 복원하려는 마지막 증분본을 맨 뒤에 둔다. 출력 위치는 -o로 지정하며 이 옵션은 필수다.

$ pg_combinebackup \
    /backup/full_0901 \
    /backup/incr_0902 \
    /backup/incr_0903 \
    -o /restore/pgdata_0903

실행 전에 어떤 작업이 벌어질지 미리 보고 싶으면 -n(dry-run)을 붙인다. 파일을 만들지 않고 예정된 동작만 출력한다.

$ pg_combinebackup -n \
    /backup/full_0901 /backup/incr_0902 /backup/incr_0903 \
    -o /restore/pgdata_0903

결과로 나온 /restore/pgdata_0903은 완전한 데이터 디렉터리다. 여기에 알맞은 postgresql.conf와 복구 설정을 얹고 인스턴스를 띄우면 그 시점의 DB가 올라온다. 이 합성 전체본을 다시 다음 pg_combinebackup의 입력으로 넣을 수도 있다.

체인 무결성은 반드시 지켜야 한다. 중간 증분본을 하나라도 빼면 복원은 실패한다. pg_combinebackup은 넘긴 백업들이 올바른 체인을 이루는지는 확인하지만, 각 백업 파일이 손상 없이 온전한지까지 검사하지는 않는다.

6. 백업 무결성은 pg_verifybackup으로 따로 검사

합성이 체인의 논리적 정합성만 본다면, 파일 자체가 멀쩡한지는 pg_verifybackup이 매니페스트의 체크섬과 대조해 확인한다. 백업을 떠 둔 직후, 그리고 복원 직전에 한 번씩 돌려 두면 마음이 놓인다.

$ pg_verifybackup /backup/full_0901
backup successfully verified

증분본도 같은 방식으로 검사할 수 있다. 각 백업 디렉터리를 개별로 검증하면 된다.

7. 실무에서 걸리는 지점들

RDS에서는 이 방법을 못 쓴다. 이 절차는 EC2 등에서 직접 운영하는 PostgreSQL을 대상으로 한다. Amazon RDS나 Aurora는 관리형이라 서버 파일시스템과 슈퍼유저 접근을 열어 주지 않으므로 pg_basebackup으로 base backup을 뜨는 방식이 아니라 자체 스냅샷과 PITR을 쓴다. 네이티브 증분 백업은 서버를 스스로 굴릴 때의 선택지다.

체크섬 상태를 바꿨다면 새 전체본을 떠라. pg_combinebackup은 페이지 체크섬을 다시 계산하지 않는다. 체크섬을 켜거나 끄는 변경 뒤에 옛 체크섬 상태의 백업을 섞어 합성하면 결과물에 잘못된 체크섬이 남을 수 있다. 이럴 때는 증분을 이어 붙이지 말고 전체 백업을 새로 뜨는 게 맞다.

요약 보관 기간과 백업 주기를 맞춰라. 4번에서 본 실패는 대부분 wal_summary_keep_time이 백업 간격보다 짧아서 생긴다. 전체를 뜨는 주기, 증분을 뜨는 주기, 요약 보관 기간을 한 축에 놓고 요약이 항상 살아 있도록 잡는다.

테이블스페이스가 있으면 -T로 재배치한다. 원본과 다른 경로에 복원할 때 pg_combinebackup -T 옛경로=새경로로 테이블스페이스 위치를 옮긴다.

정리

PostgreSQL 17의 증분 백업은 외부 도구 없이 코어만으로 백업 시간과 용량을 줄인다. 순서는 간단하다. 서버에서 summarize_wal을 켜고 wal_summary_keep_time을 백업 주기에 맞춰 잡은 뒤, pg_basebackup으로 전체본을 한 번 뜨고, 이후에는 직전 백업의 backup_manifest--incremental에 넘겨 변경분만 뜬다. 복원할 때는 pg_combinebackup으로 전체본과 증분본들을 오래된 순서대로 합쳐 전체본을 만들고, pg_verifybackup으로 무결성을 확인한다. RDS가 아닌 EC2 자체 운영 환경이라면 지금 백업 스크립트에 바로 얹어 볼 만하다.

자주 묻는 질문

summarize_wal을 켜려면 PostgreSQL을 재시작해야 하나?

아니다. summarize_wal은 sighup 컨텍스트라 재시작 없이 설정 리로드만으로 적용된다. ALTER SYSTEM SET summarize_wal = on 후 SELECT pg_reload_conf()를 실행하면 WAL summarizer가 뜬다. 다만 wal_level이 minimal이면 켜 둬도 요약 파일이 생성되지 않으니 replica 이상이어야 한다.

증분 백업본만으로 바로 복구할 수 있나?

없다. 증분 백업은 직접 복원할 수 없다. pg_combinebackup으로 기준이 된 전체 백업과 이어진 증분 백업들을 오래된 순서대로 합쳐 합성 전체본을 만든 다음, 그 디렉터리를 데이터 디렉터리로 사용해야 한다.

증분 백업이 'WAL summaries are required' 오류로 실패한다. 왜 그런가?

필요한 WAL 요약 파일이 pg_wal/summaries에 없기 때문이다. summarizer가 아직 최신 WAL을 요약하지 못했다면 잠시 뒤 재시도하면 된다. 하지만 wal_summary_keep_time이 지나 요약이 이미 삭제됐다면 그 기준으로는 증분을 뜰 수 없고, 전체 백업부터 다시 떠야 한다.

Amazon RDS에서도 pg_basebackup --incremental을 쓸 수 있나?

쓸 수 없다. RDS와 Aurora는 관리형이라 서버 파일시스템과 슈퍼유저 접근을 제공하지 않아 pg_basebackup으로 base backup을 뜨는 방식 자체가 막혀 있다. 대신 자동 스냅샷과 특정 시점 복구(PITR)를 쓴다. 네이티브 증분 백업은 EC2 등에서 직접 운영하는 PostgreSQL의 선택지다.

pg_combinebackup으로 합치면 백업 파일 손상까지 걸러 주나?

아니다. pg_combinebackup은 넘긴 백업들이 올바른 체인을 이루는지는 확인하지만 각 백업이 온전한지는 검사하지 않는다. 파일 무결성은 pg_verifybackup으로 매니페스트 체크섬과 대조해 따로 확인해야 한다.

관련 글

댓글 0

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

아직 댓글이 없습니다.