본문으로 건너뛰기

"pgBackRest" 태그로 연결된 4개 게시물개의 게시물이 있습니다.

모든 태그 보기

prev-link 복구 오류

· 약 7분

secondary 하나가 복구를 못 끝내고 같은 로그만 뱉고 있었어요. WAL을 archive에서 한 번 당겨오고, 곧바로 record 하나를 읽다 실패하고, 다시 같은 파일을 당겨오는 흐름이 2초 간격으로 무한히 돌았어요.

2026-07-24 13:41:10 KST LOG: record with incorrect prev-link 67F/7BAB8 at 67F/40000028
2026-07-24 13:41:12 KST LOG: restored log file "00000068...0067F..." from archive
2026-07-24 13:41:12 KST LOG: record with incorrect prev-link 67F/7BAB8 at 67F/40000028
2026-07-24 13:41:15 KST LOG: restored log file "00000068...0067F..." from archive
2026-07-24 13:41:15 KST LOG: record with incorrect prev-link 67F/7BAB8 at 67F/40000028

디스크가 깨진 것처럼 보이지만 그건 아니었습니다. 이 메시지는 대부분 "여기가 이 timeline에서 유효한 WAL의 끝"이라는 신호입니다. 문제는 secondary가 그 끝에서 다음 timeline으로 못 건너가고 제자리를 맴돌았다는 점입니다.

이 로그가 정확히 어디서 나오나

두 줄은 서로 다른 주체가 찍습니다.

restored log file ... from archive는 recovery 중인 서버가 restore_command로 archive에서 WAL 세그먼트 하나를 가져왔다는 뜻입니다. 우리 환경은 pgBackRest가 archive 역할이라, 이 줄은 pgBackRest에서 세그먼트를 복원해 왔다는 기록입니다.

record with incorrect prev-link A at B는 WAL을 읽는 xlogreader가 찍습니다. PostgreSQL의 WAL record는 헤더에 xl_prev라는 필드를 들고 있는데, 바로 앞 record가 어디서 끝났는지를 가리키는 back-link입니다. reader는 record를 하나 읽을 때마다 "이 record의 xl_prev가 방금 내가 읽은 record의 끝과 같은가"를 확인합니다. 어긋나면 이 메시지를 남기고 그 자리를 유효한 WAL의 끝으로 간주합니다.

메시지의 두 LSN은 순서대로 이렇게 읽습니다. at 뒤(67F/40000028)가 문제의 record가 놓인 위치이고, 앞(67F/7BAB8)이 그 record에 적혀 있던 xl_prev 값입니다. 즉 67F/40000028에 있는 record는 자기 앞 record가 67F/7BAB8에서 끝났다고 주장하는데, reader가 실제로 그 지점까지 읽어온 맥락과 맞지 않는 것입니다.

여기서 위치 67F/40000028이 힌트를 줍니다. WAL 세그먼트는 기본 16MB이고, 오프셋 0x40000028은 세그먼트 경계에서 딱 0x28(40바이트) 들어간 자리입니다. 40바이트는 세그먼트 첫 페이지의 long page header 크기와 같습니다. 다시 말해 이 record는 어느 세그먼트의 맨 첫 record 자리에 있습니다. 그 자리의 xl_prev가 한참 앞인 67F/7BAB8(같은 논리 파일에서 500KB쯤 되는 지점)를 가리킨다는 건, 그 세그먼트 앞부분이 과거에 쓰이고 아직 새 내용으로 덮이지 않은 recycled 세그먼트의 잔재라는 신호에 가깝습니다. PostgreSQL은 성능을 위해 WAL 파일을 지우지 않고 이름만 바꿔 재사용하는데, reader가 그 옛 바이트열을 그럴듯한 record로 오독하면 이런 back-link 불일치가 나옵니다. xlogreader 소스메일링 리스트 논의에서도 같은 진단이 나옵니다.

어쩌다 이 상태가 됐나

먼저 분명히 해두면, 아래 순서는 사후에 되짚어 본 유추입니다. 운영 중 이것저것 만지다 이 상태에 도달했고, 어느 한 단계가 범인이라고 특정하지는 못했습니다. 다만 secondary가 이 지경이 되기까지 밟은 대략의 경로는 남겨 둡니다. HA는 pg_auto_failover로 묶여 있고 백업은 pgBackRest로 받는 환경이었습니다.

순서한 일부수 효과
1최초 primary/secondary 구성timeline 시작
2failover 발생옛 secondary 승격, timeline 증가
3옛 secondary 노드 drop구 노드 제거
4새 secondary add (pgBackRest 백업본으로 seed)과거 시점 데이터로 출발
5다시 failovertimeline 한 번 더 증가

failover는 standby를 primary로 승격시키면서 새 timeline을 엽니다. 이때 .history 파일이 만들어져 "몇 번 timeline은 어느 LSN에서 갈라져 나왔다"를 기록하고, 뒤따르는 standby는 이 history를 보고 분기 지점을 넘어 새 timeline의 WAL로 갈아탑니다. 갈아타려면 recovery_target_timeline이 최신을 따라가도록 서 있어야 하고, 분기 지점 이후의 WAL과 history 파일이 archive에 제대로 올라와 있어야 합니다.

이 증상 자체는 문서화가 잘 되어 있습니다. PostgreSQL 코어 개발자 Michael Paquier(미하엘 파키에)는 같은 로그를 두고 "현재 timeline에서 유효한 WAL의 끝을 가리키는 것이며, 과거에 recycled 세그먼트로 쓰였던 영역을 읽을 때 마주칠 수 있다"고 설명합니다. 같은 스레드에는 두 가지가 더 나옵니다. 하나는 이 오류가 archive_mode가 켜져 있을 때 주로 나타난다는 관찰이고, 다른 하나는 여러 번 승격을 거친 노드를 다시 붙일 때 반복해서 겪었다는 보고입니다. archive에서 WAL을 당겨오고, failover를 여러 번 돌린 우리 상황과 겹치는 대목입니다.

그 틀에 우리 경로를 얹으면 이렇게 읽힙니다. 과거 백업본에서 출발한 secondary가 두 번째 failover로 timeline이 또 올라간 뒤, 자기가 따라가던 timeline의 끝에 도달하고도 다음 timeline으로 건너갈 연결을 archive에서 매끄럽게 잇지 못한 것으로 보입니다. 분기 지점 근처 세그먼트에 recycled 잔재가 남아 있었고, reader가 그 자리를 67F/40000028의 깨진 record로 읽었다는 그림입니다. 단정이 아니라 관측된 증상과 문서화된 메커니즘을 맞춰 본 해석입니다.

왜 하필 무한 루프였나

멈추지 않고 도는 게 이 현상의 성격을 잘 보여줍니다.

recovery는 다음 WAL을 기다리다 restore_command를 다시 부르고, archive는 같은 세그먼트를 또 건네주고, reader는 같은 자리에서 같은 back-link 불일치를 만납니다. 넘어가야 할 새 timeline의 이력을 집어오지 못하는 한, 이 고리는 스스로 풀리지 않습니다. 로그의 LSN이 67F/40000028로 매번 똑같이 고정돼 있는 게 그 증거였습니다. 앞으로 나아가는 복구라면 LSN이 조금씩이라도 커집니다.

이 대목에서 disk corruption과 헷갈리기 쉬운데, 구분 기준은 단순합니다. 같은 세그먼트를 반복 restore하면서 같은 LSN에 멈춰 있으면 timeline 경계 문제이고, 서로 다른 위치에서 읽기 자체가 깨지면 그때 물리 손상을 의심합니다.

어떻게 걷어냈나

pg_rewind나 recovery_target_timeline=latest 조정으로 붙여보는 길이 먼저 떠오릅니다. 다만 메일링 리스트에도 나오듯 pg_rewind가 timeline 충돌은 정리해도 이 back-link 오류 자체를 없애주지 못하는 경우가 있습니다. 게다가 이 노드는 4번에서 이미 과거 백업본으로 새로 붙인 상태였습니다. 어중간하게 되살리기보다 현재 timeline 기준으로 깨끗이 다시 seed하는 편이 빨랐습니다.

그래서 pg_auto_failover의 노드 재구축으로 정리했습니다.

# 꼬인 secondary 노드를 데이터까지 완전히 제거
pg_autoctl drop node --destroy

# 현재 primary 기준으로 secondary 새로 구축
pg_autoctl create postgres

--destroy는 monitor에서 노드를 지우는 데 그치지 않고 데이터 디렉토리까지 함께 정리합니다. 이어서 pg_autoctl create postgres가 현재 primary의 최신 timeline을 기준으로 base backup을 다시 받아 복제를 새로 세웁니다. recycled 잔재를 담고 있던 옛 데이터가 통째로 사라지니 back-link 불일치도 같이 사라졌고, 복제는 정상으로 따라붙었습니다.

남는 메모

재구축이 정공법은 아닐 수 있습니다. 원인을 LSN 단위로 끝까지 파고들면 어느 failover에서 archive에 어떤 공백이 생겼는지 특정할 수도 있었을 것입니다. 다만 pg_auto_failover처럼 오케스트레이션이 노드 수명주기를 쥐고 있는 환경에서는 백업본에서 노드를 다시 붙이는 비용이 낮은 만큼, 포렌식보다 재구축이 대체로 실용적이었습니다.

정리하자면 이래요. standby가 archive만 반복해서 restore하면서 고정된 LSN에 record with incorrect prev-link로 멈춰 있으면, 물리 손상보다 timeline 경계를 못 넘은 상황을 먼저 의심하는 게 맞아요. 그리고 failover를 여러 번 돌리는 사이에 과거 백업본으로 노드를 되붙이는 조합은 timeline 이력이 엉키기 딱 좋은 지점이라, 그 앞뒤로는 archive에 history 파일과 분기 이후 WAL이 온전히 올라와 있는지 한 번 더 확인해 둘 만해요.

참고

pgBackRest와 pg_tde 백업

· 약 5분

데이터를 디스크에 암호화해서 저장하는 클러스터를 백업 도구가 제대로 다룰 수 있을까요? 결론부터 말하면, pg_tde로 암호화한 PostgreSQL 클러스터를 pgBackRest로 백업하고 복구하는 과정은 거의 대부분 투명하게 작동하지만, 암호화된 데이터를 백업 도구가 해석할 수 없다는 본질적 한계 때문에 몇 가지 검증/압축 옵션은 꺼야 해요.

Data Egret의 Stefan Fercot(스테판 페르코)가 pgBackRest and pg_tde 글에서 이 조합을 직접 검증했습니다. 이 블로그에서 다뤄 온 백업 시리즈의 곁가지로, 백업 도구와 암호화 extension의 궁합을 운영 관점에서 정리해 봐요.

pg_tde가 암호화하는 것

pg_tde는 Percona가 개발 중인 투명 데이터 암호화(Transparent Data Encryption) extension입니다. 이름 그대로 애플리케이션은 암호화 여부를 신경 쓰지 않고, 디스크에 저장되는 데이터(data at rest)만 암호화합니다. 암호화 대상은 크게 두 가지입니다.

  • 테이블 데이터(heap): tde_heap 접근 방식(access method)으로 만든 테이블. 기존 테이블은 ALTER TABLE ... SET ACCESS METHOD tde_heap으로 전환합니다. heap 테이블뿐 아니라 거기 딸린 index, TOAST, sequence까지 암호화됩니다.
  • WAL: pg_tde.wal_encrypt GUC를 켜면 WAL 세그먼트도 암호화됩니다. 이 설정은 서버 전역이라 재시작이 필요하고, 켠 시점 이후의 WAL write부터 암호화가 적용됩니다.

다만 모든 게 암호화되지는 않습니다. 시스템 카탈로그와 통계 데이터 같은 메타데이터는 아직 암호화 대상이 아닙니다. 이름 그대로 "데이터" 암호화에 초점이 맞춰져 있습니다.

키 구조는 2계층입니다. 실제 데이터를 암호화하는 internal key는 $PGDATA/pg_tde 아래에 로컬로 저장되고, 이 internal key를 다시 암호화하는 principal key는 외부 KMS에 둡니다. principal key는 데이터베이스당 하나입니다. 검증에서는 KMS로 OpenBao를 Docker로 띄워 썼고, root 자격증명이 아니라 secret/ 경로에만 읽기/쓰기 권한을 준 최소 권한 토큰을 발급해 사용했습니다.

pgBackRest가 암호화된 클러스터를 다루는 흐름

pgBackRest 입장에서 보면, pg_tde가 이미 암호화해 놓은 데이터 파일과 WAL을 그대로 받아 저장소로 옮깁니다. 백업 도구는 그 안을 들여다보지 않습니다. 암호화는 PostgreSQL 쪽에서 끝나 있고, pgBackRest는 암호화된 바이트 덩어리를 운반하는 역할입니다.

중요한 지점은 복구 이후입니다. pgBackRest가 복구해 놓은 PGDATA는 여전히 암호화된 상태입니다. 이걸 PostgreSQL이 다시 읽으려면 internal key를 풀 principal key가 필요하고, principal key는 외부 KMS에 있습니다. 즉 백업 파일만 들고 있어서는 복구한 클러스터를 기동할 수 없고, KMS 접근이 함께 살아 있어야 합니다.

검증 결과와 주의점

Fercot는 pgbench로 부하를 주면서 full 백업과 incremental 백업을 뜨고, pgbench_tellers에서 1,000건을 삭제한 뒤 named restore point로 시점 복구(PITR)를 실행해 삭제된 1,000건이 되살아나는 것까지 확인했습니다. WAL 세그먼트와 데이터 파일은 백업 저장소 안에서도 암호화된 채 유지됐고, 복구 과정에서 별도의 복호화 래퍼 없이 named restore point에 깔끔하게 도달했습니다.

다만 암호화 특성 때문에 꺼야 하는 설정들이 있습니다. 정리하면 다음과 같습니다.

설정이유
archive-header-checkn암호화된 WAL 헤더를 pgBackRest가 해석하지 못합니다.
checksum-pagen암호화된 page의 checksum을 검증할 수 없습니다.
compress-typenone암호화된 데이터는 무작위에 가까워 압축 이득이 거의 없습니다.
repo1-blocknblock 단위 incremental의 효율이 암호화로 무력화됩니다.

표의 항목들은 모두 같은 원인에서 나옵니다. pgBackRest는 암호화된 내용을 들여다볼 수 없으므로, 데이터 내부를 읽어야 성립하는 검증과 최적화가 작동하지 않습니다. 그래서 page checksum 검증과 WAL 헤더 검증을 끄고, 압축도 끄는 편이 낫습니다. 압축을 켜 두면 줄어들지도 않을 데이터를 압축하느라 CPU만 씁니다.

한 가지 더, incremental 백업 크기가 예상보다 컸습니다. block 단위 incremental은 변경된 블록만 골라 담아 용량을 아끼는데, 암호화된 데이터에서는 이 절감 효과가 크게 줄어듭니다.

WAL 암호화 관련: 과거 Percona 문서는 암호화 환경에서 비동기 아카이빙(archive-async=y)을 권하지 않았습니다. 그러나 이번 검증에서는 비동기 아카이빙이 문제없이 작동했습니다. 운영에서 적용하기 전에는 사용하는 pg_tde 버전 기준으로 한 번 더 확인하는 편이 안전합니다.

키 관리 관점: 백업과 복구가 투명하게 돈다고 해서 백업만으로 복구가 끝나는 것은 아닙니다. 복구된 PGDATA는 암호화 상태 그대로이므로, principal key를 보관한 KMS에 접근하지 못하면 클러스터를 기동할 수 없습니다. 백업 파일과 KMS 접근 권한을 함께 보존하고, KMS 자체의 가용성과 백업도 별도로 챙겨야 합니다. 백업 저장소 한쪽만 살아남는 시나리오도 복구 절차에 반드시 포함해 두는 편이 좋습니다.

저장소 암호화 중복: pgBackRest 자체에도 저장소 암호화 옵션(repo1-cipher-type)이 있습니다. pg_tde가 이미 데이터를 암호화한 뒤 넘겨주므로 저장소 암호화는 선택 사항입니다. 다만 시스템 카탈로그처럼 pg_tde가 암호화하지 않는 영역이 백업에 포함되는 점을 고려하면, 저장소 암호화를 한 겹 더 두는 선택도 합리적입니다.

검증에는 Percona Server for PostgreSQL이 쓰였습니다. pg_tde가 특정 패치에 의존하기 때문에 표준 PostgreSQL이 아닌 Percona 배포판이 필요하고, pgBackRest가 버전을 제대로 인식하도록 pg-version-force로 버전을 강제해야 했습니다.

운영 관점과 백업 시리즈 연결

백업 도구를 고를 때는 도구 자체의 기능만 보기 쉽지만, 실제 운영에서는 암호화, 복제, 버전 같은 주변 환경과의 궁합이 더 자주 발목을 잡습니다. 이번 검증의 의미는 "pg_tde를 켜도 pgBackRest를 그대로 쓸 수 있다"는 점을 확인했다는 데 있습니다. 암호화 때문에 백업 도구를 새로 고민할 필요는 없고, 검증/압축 옵션 몇 개를 끄는 선에서 정리됩니다.

대신 복구 절차의 무게중심이 옮겨 갑니다. 평소처럼 백업 무결성만 점검하는 데서 그치지 말고, principal key를 가진 KMS까지 포함한 복구 리허설을 정기적으로 돌려야 합니다. 암호화를 도입하는 순간, 백업 전략은 "데이터 백업"에서 "데이터 백업 + 키 관리"로 확장됩니다.

pgBackRest를 운영에 들이는 과정 자체가 처음이라면, 이 블로그의 pgBackRest 도입기에서 기본 stanza 구성과 아카이빙 흐름을 먼저 잡고 오는 편이 좋아요. 암호화 궁합은 그 위에 얹는 한 겹이에요.

참고

pgBackRest 컨소시엄 부활

· 약 8분

2026-05-19, Percona가 주도하는 6사 컨소시엄(AWS, Percona, Supabase, pgEdge, Tiger Data, Eon)이 pgBackRest의 후원을 공식화했고, David Steele(데이비드 스틸)은 메인테이너로 복귀해요.

한 사람이 13년 짊어진 모델이 22일 만에 여러 사람이 함께 짊어지는 모델로 바뀌었습니다. 그게 이번 사건의 진짜 줄거리입니다.

DBA 입장에서 결론은 짧습니다. 즉각 마이그레이션 압력은 사라졌고, PostgreSQL 19(2026-09 예정) 호환성도 컨소시엄이 책임집니다. 지난달 종료 발표 시점에 썼던 글의 결말이 한 달 만에 바뀌었습니다.

22일짜리 정세 변동

시점사건
2026-04-27David Steele이 GitHub 저장소를 archive 처리, "no longer maintained" 공식 선언
2026-04-28Percona 공식 입장 — 계속 사용 권장
2026-04-30본 블로그에서 종료 글 발행
2026-05-04저장소 archive 해제, README에 MAINTENANCE UPDATE 추가. Steele이 sponsor coalition 모색 의사 공식화. Supabase가 첫 명시 후원사
2026-05-19Percona가 주도하는 6사 컨소시엄 정식 발표 — AWS, Percona, Supabase, pgEdge, Tiger Data, Eon

22일입니다. 종료 발표를 알아채고 분노했다가 분석으로 넘어가는 사이클을 한 바퀴 다 돌 시간도 안 됐습니다. 그동안 PostgreSQL DBA 커뮤니티 안에서는 "진짜 멈추면 어떻게 되나"의 시뮬레이션이 활발했고, Barman으로의 마이그레이션과 CNPG의 plugin-barman-cloud, WAL-G 회의론 등이 한곳에서 다시 정리됐습니다. 결과적으로 그 압박이 후원사들의 의사 결정 속도를 끌어올린 그림입니다.

6사가 모인 계산

발표문은 회사 이름 외에 각자 동기를 길게 풀지 않았지만, 각 회사의 PG 사업 위치를 보면 그림은 그려집니다.

후원사PG 사업 위치pgBackRest 의존도
PerconaPG/MySQL 운영 컨설팅/매니지드 서비스표준 권장 백업 도구. 마이그레이션 시 가장 큰 운영 부담을 떠안는 위치
AWSRDS for PostgreSQL/Aurora PostgreSQL자체 백업 인프라가 있지만, 셀프매니지드 PG 고객의 백업 도구 생태계 일관성이 자사 마이그레이션 경로에 직결
Supabase매니지드 PostgreSQL BaaS백엔드 전체가 PostgreSQL 위에 있습니다. 백업 도구가 흔들리면 Free-tier 자동 백업/복원 SLA가 바로 흔들립니다
pgEdge분산 PostgreSQL멀티 리전 백업/PITR 표준이 그대로 pgBackRest입니다. 대체 비용이 가장 큽니다
Tiger DataTimescaleDB(시계열 PG 익스텐션)TimescaleDB 운영 매뉴얼이 pgBackRest를 기본 가정으로 합니다
EonPG 백업/DR SaaS제품 자체가 pgBackRest 위에 얹혀 있습니다

요약하면 pgBackRest를 잃었을 때 가장 비싸게 무는 회사들이 모였습니다. 단독 후원사 모델은 시장 한 곳에서 손해를 보는 회사가 비용을 다 짊어지는 구조였고, 컨소시엄 모델은 시장 전체에서 손해를 보는 회사들이 N분의 1로 나누는 구조입니다. Crunchy Data가 한 명을 13년 받쳐 줬다면, 이제는 6사가 함께 받칩니다.

Percona CEO **Peter Farkas(피터 파카스)**의 발표문 한 줄이 이를 그대로 짚습니다.

"pgBackRest has been our recommended backup solution/tool for years... coordinating with other companies to keep it healthy was a straightforward decision."

(pgBackRest는 우리가 수년 동안 권장해 온 백업 도구다. 이 도구를 건강하게 유지하기 위해 다른 회사들과 손을 잡는 결정은 어려운 결정이 아니었다.)

Percona에서 PostgreSQL P&E를 이끄는 **Kai Wagner(카이 바그너)**는 여기에 한마디 더 보탰습니다.

"Open source stays open. That's not a slogan. It's how we make decisions when situations like this come up."

("오픈소스는 열려 있다"는 슬로건이 아니다. 이런 상황이 닥쳤을 때 우리가 결정을 내리는 방식이다.)

읽는 사람에 따라 마케팅으로 받아칠 수도 있습니다. 다만 22일 만에 6사가 실제로 모였다는 사실이 그 슬로건을 한 번은 받쳐 줬다는 점은 분명합니다.

단독 메인테이너에서 다중 메인테이너로

이번 컨소시엄 발표에는 자금만큼 중요한 두 번째 줄기가 있습니다. Percona가 새 메인테이너 onboarding을 명시적으로 책임진다는 점입니다.

"Percona engineering involvement to onboard a new maintainer."

13년 동안 코드 리뷰, 릴리스, 이슈 트리아지를 거의 한 사람이 처리한 프로젝트였습니다. 지난달 종료 글에서 정리한 구조적 함정이 정확히 그 지점입니다. 자금이 모여도 한 사람이 다시 떠안는 구조라면 같은 위기가 5년 뒤 그대로 반복됩니다.

이번 발표에서 공식화된 변화는 셋입니다. 첫째, Steele이 메인테이너로 복귀합니다. 후원 자금으로 dedicated time을 확보했습니다. 둘째, 단일 후원사 의존 모델을 해체하고 컨소시엄 모델로 전환합니다. 한 회사의 매각이나 예산 삭감 한 번으로 프로젝트가 흔들리지 않게 됩니다. 셋째, 추가 메인테이너를 영입합니다. Percona가 엔지니어링 리소스를 들여 후속 메인테이너를 onboarding합니다.

세 번째 항목이 가장 묵직합니다. 단독 메인테이너가 후원만 받는다고 지속가능성 문제가 사라지지 않는다는 인식을, DBA 커뮤니티 바깥에서도 받아들인 결과이기 때문입니다. 메인테이너가 한 명에서 둘, 둘에서 셋으로 늘어나는 구간을 실제로 통과해야 위기 반복이 끊깁니다.

오픈소스 지속가능성 모델로서의 의미

pgBackRest 한 건의 부활로 보면 작은 사건이지만, 비슷한 구조의 위기는 곳곳에 있습니다. Linux 커널의 일부 파일시스템 메인테이너, Curl의 Daniel Stenberg, SQLite의 D. Richard Hipp, 그리고 PostgreSQL 안의 Barman 자체도 결국 한 회사(EDB) 한 줄로 묶여 있습니다.

이번 사건이 보여준 흐름은 셋입니다.

  • 단일 회사 후원 + 단일 메인테이너 모델은 매각 한 번으로 무너집니다. Crunchy Data 매각 이후 Steele의 후속 정착이 안정될 때까지 시간이 충분히 주어지지 않았습니다.
  • DBA 커뮤니티의 압박이 후원사 의사 결정 속도를 끌어올립니다. 종료 발표 직후 "진짜 멈추면 어떻게 되나"의 시뮬레이션이 빠르게 돌면서, 후원하지 않을 때의 운영 비용이 후원할 때의 자금 부담보다 크다는 계산이 빠르게 섰습니다.
  • 컨소시엄 모델 + 다중 메인테이너 영입이 새 표준이 될 수 있습니다. Eclipse Foundation/CNCF처럼 형식화된 거버넌스까지 가지 않더라도, 비공식 컨소시엄으로 출발해 단계적으로 자리를 잡아가는 그림이 자연스럽습니다.

순서를 보면 씁쓸한 구석이 있어요. 한 사람이 손을 놓고 22일이 지나서야 6사가 모였지만, 그가 13년 일하는 동안에는 한 회사만 받쳐 줬고, 컨소시엄 모델이 정말 새 표준이 되려면 위기가 터진 다음이 아니라 터지기 전에 모이는 회의가 필요해요.

DBA 입장에서 결정을 다시 풀어 봅니다

지난달 종료 글의 DBA 가이드는 다음 PostgreSQL 메이저까지 여유를 두고 점진적으로 Barman/CNPG plugin-barman-cloud로 마이그레이션을 검토하라고 권했습니다. 이제 그 결정이 풀립니다.

시나리오4/27 종료 발표 시점 권고5/19 컨소시엄 발표 이후 권고
pgBackRest 운영 중, 안정적PG 19 출시까지는 그대로 두고, 그 사이 대안 도구 PoC를 진행합니다그대로 유지합니다. 컨소시엄 발표로 보안/호환성 공급이 보장됐습니다
Barman 마이그레이션 진행 중계속 진행합니다진행 중인 마이그레이션은 마무리합니다. 굳이 되돌릴 이유는 없습니다
신규 클러스터 백업 도구 선정신규는 Barman 또는 plugin-barman-cloud를 권장합니다pgBackRest도 다시 선택지에 올립니다. 신규 도입 시 두 도구를 동급으로 비교합니다
CNPG 사용자plugin-barman-cloud를 유지합니다plugin-barman-cloud를 유지합니다(CNPG는 처음부터 Barman 라인업입니다)

신규 도입 시점에 가장 큰 차이가 생깁니다. 종료 발표 시점에는 "한 사람만 만지는 도구를 신규로 쓰겠다고 결정하기는 어렵다"가 권고였습니다. 컨소시엄 발표 이후에는 "6사가 함께 받치는 도구"로 그 결론이 갈렸습니다.

다음 분기점은 PostgreSQL 19

진짜 검증은 다음 메이저 출시입니다.

  • PostgreSQL 19(2026-09 예정)이 컨소시엄 체제의 첫 메이저 대응입니다. v2.59 또는 그 후속 릴리스에서 PG 19 공식 지원이 들어와야 합니다. 이게 제때 풀리면 컨소시엄 모델은 DBA 신뢰를 한 번 얻습니다.
  • 새 메인테이너 영입 시점도 관건입니다. Percona가 명시적으로 책임진 onboarding이 1~2년 안에 가시화돼야 합니다. 단순히 Steele 한 명 복귀로 끝나면 5년 뒤 같은 위기가 반복됩니다.
  • 추가 후원사 합류가 남습니다. 6사가 중심이지만 지속 가능성 차원에서는 더 두꺼워질 필요가 있습니다. EDB, Crunchy Data, Cloud Native(EnterpriseDB Postgres) 같은 큰 회사들이 어떻게 움직일지가 관전 포인트입니다.

정리

4월 27일 종료 발표 때 archive였던 저장소는 다시 active로 돌아왔고, 없던 메인테이너 자리는 Steele 복귀에 더해 신규 영입까지 예고됐습니다. 후원은 6사 컨소시엄이 떠안았고, 불확실하던 PostgreSQL 19 호환성도 컨소시엄이 책임집니다. 종료 발표 직후 점진 마이그레이션을 검토하라던 DBA 권고는, 이제 그대로 유지하되 신규 도입에서도 다시 후보에 올리는 쪽으로 바뀌었습니다.

13년 단독 시대가 22일 만에 6사 컨소시엄 시대로 넘어갔어요. 정세는 풀렸지만 컨소시엄 모델이 정말 지속 가능한지는 첫 번째 PostgreSQL 메이저 대응과 새 메인테이너 영입 시점이 결정하며, 그동안 DBA는 마이그레이션 압력 없이 한 분기 정도 더 호흡할 수 있어요.

참고

pgBackRest 종료와 대안

· 약 11분

2026-05-04 업데이트: pgBackRest는 사실상 부활 쪽으로 가닥이 잡혔습니다.

이 글을 올리고 며칠 지나지 않아 분위기가 뒤집혔습니다. 저장소 archive가 해제됐고("archived": false), 기본 브랜치가 eol로 바뀐 README 상단에 MAINTENANCE UPDATE 섹션이 새로 추가됐습니다. 그 안에서 David Steele(데이비드 스틸)이 직접 부활 의사를 밝혔습니다.

"It is clear that many pgBackRest users... would prefer the project to continue with me as the primary maintainer. ... This time pgBackRest will be funded by a coalition of sponsors so that a single acquisition will no longer affect my ability to continue work on the project."

(많은 pgBackRest 사용자가 내가 계속 메인테이너로 남아 주기를 바란다는 게 분명해졌다. ... 이번에는 한 회사 매각 한 번으로 프로젝트가 흔들리지 않도록 여러 후원사가 함께 자금을 댄다.)

골자는 세 가지입니다. (1) Steele의 메인테이너 복귀, (2) 단독 후원사(과거 Crunchy Data) 의존 모델을 깨고 sponsor coalition 모델로 전환, (3) 추가 메인테이너 영입 예정입니다. README에 명시된 현재 sponsor는 Supabase입니다. 정식 발표는 같은 주 안에 나올 예정으로 잡혀 있습니다.

본문은 2026-04-27 시점의 충격과 해석을 사료로 남기기 위해 그대로 둡니다. 운영자 입장에서 결론은 단순해졌습니다. 즉각 마이그레이션 압력은 약해졌고, 다음 PostgreSQL 메이저 업그레이드까지의 시간은 그대로입니다. 정식 발표가 나온 뒤 한 번 더 들여다보면 됩니다.

여담 한 줄입니다. 후배가 그러더군요. "이래서 파업들을 하는 거라고." 농담이지만 묘하게 정곡을 찔렀습니다. 13년 일한 사람이 손을 놓고 나서야 비로소 자본이 모였기 때문입니다.

한 사람이 13년 지킨 백업 도구

PostgreSQL 운영을 좀 해본 사람이라면 pgBackRest라는 이름은 거의 반사적으로 익숙할 텐데요, 전체 / 차등 / 증분 백업, PITR, 병렬 압축/전송, S3, GCS, Azure 직결, 무결성 검증까지 PostgreSQL 백업에 필요한 거의 모든 항목이 한 도구로 깔끔하게 풀리는 사실상의 표준이었어요.

그 표준이 멈췄습니다. 2026년 4월 27일, 단독 메인테이너 David Steele(데이비드 스틸)이 GitHub 저장소를 archive 처리하면서 다음과 같이 공식 안내했습니다.

"After a lot of thought, I have decided to stop working on pgBackRest. I did not come to this decision lightly." — David Steele, pgbackrest GitHub README

13년입니다. 한 사람이 13년 동안 사실상 혼자 유지해 온 도구가 멈췄습니다.

개인적으로는 슬프면서도 "이게 그렇게 단순한 슬픔으로 정리될 일인가" 하는 생각이 들어요. 이 글에서는 사실관계, 다른 사람들의 해석, 대안 도구 비교, CNPG에서 Barman이 어떤 자리에 있는지, 그리고 운영자 입장에서 지금 무엇을 할지 정리합니다.

무슨 일이 있었는가

먼저 타임라인을 살펴보겠습니다.

시점사건
2013David Steele이 pgBackRest 시작 (Crunchy Data(크런치 데이터) 후원)
2024–2025Crunchy Data 매각, Steele이 후속 직장 / 독립 스폰서십 모색
2026-01-19마지막 릴리스 v2.58.0 ("Object Storage Improvements")
2026-04-27"no longer maintained" 공식 선언, 저장소 archive
2026-04-28Percona 공식 입장: 계속 사용 권장
2026-05-04저장소 archive 해제, README에 MAINTENANCE UPDATE 추가. David Steele 부활 의사 공식화, sponsor coalition 모델로 재구성 중

마지막 릴리스 v2.58.0은 PostgreSQL 18까지 공식 지원합니다. 즉 지금 운영 중인 클러스터의 백업이 당장 멈추는 건 아닙니다. 다만 다음 PostgreSQL 메이저(PostgreSQL 19, 2026-09 예정) 출시 이후 호환성/보안 패치 공급원이 사라진다는 점이 분기점입니다.

왜 이렇게 됐는가

단독 메인테이너 구조에 함정이 있었습니다.

13년간 코드 리뷰, 릴리스, 이슈 트리아지 거의 전부를 한 사람이 처리한 프로젝트였습니다. Crunchy Data가 Steele의 인건비를 받쳐주는 동안에는 그 모델이 굴러갔습니다. 매각 이후 후속 직장과 독립 후원 시도가 이어졌지만, 어느 쪽도 프로젝트를 제대로 유지할 만큼은 모이지 않았습니다.

"The person who makes sure your data survives a disaster did not make the cut." — Lætitia Avrot(레티시아 아브로), pgBackRest is dead. Now what?

(데이터 재해 복구를 책임지는 사람의 자리는 결국 잘려나갔다.)

이 한 문장이 사실 사건의 전부입니다. AI 붐을 따라 자본은 GPU와 추론 인프라로 흘러가고, "당신의 데이터가 재해 후에도 살아남게 해주는 도구"의 메인테이너 한 명을 살리는 것은 어느 회사의 우선순위에도 들어가지 못했습니다. Steele 본인은 절제된 톤으로 정리했습니다.

"Rather than do the work poorly and/or sporadically, I think it makes more sense to have a hard stop."

대충 유지하면서 사용자 신뢰만 갉아먹느니 깨끗하게 멈추겠다는 결정입니다. 비난할 자리는 아닙니다. 13년치 코드를 그렇게 마감할 수 있는 사람이 흔하지 않습니다.

같은 사건을 바라보는 네 가지 시선

며칠 사이에 정리된 PostgreSQL 생태계의 주요 입장을 표로 묶으면 다음과 같습니다.

출처입장 요약권장
Lætitia Avrot(레티시아 아브로) (MyDBA Notebook)"pgBackRest is dead." 신규 평가는 Barman, 기존 사용자는 시간 지날수록 위험 증가Barman 평가 시작
Christophe Pettus(크리스토프 페터스) (thebuild.com)"올바른 결정." OSS 인프라의 자본 부족이 본질적 문제WAL-G가 가장 유망한 대체
Gabriele Bartolini(가브리엘레 바르톨리니) (EDB / CNPG 창립자)"선순환의 단절." Barman과 pgBackRest는 철학적 의견차였다고 평가OSS 지속가능성 모델 자체를 재설계
Percona(페르코나) (공식 블로그)"현 상황은 우리 권장사항에 영향이 없다""Keep on using pgBackRest as you did!"

각 입장이 가리키는 곳이 조금씩 다른데, 그 차이가 오히려 흥미롭습니다. Avrot는 "지금 평가 단계라면 굳이 archived 도구를 신규 도입할 이유가 없다"는 운영자 시점에서 봅니다. Pettus는 *"오픈소스 인프라의 본질은 자본 문제이지 기술 문제가 아니다"*라고 한 단계 위에서 진단합니다. Bartolini는 자기 진영(Barman/CNPG)의 철학적 정당성을 곱씹으면서도 *"선순환이 끊긴 결과"*라며 더 큰 그림을 봅니다. Percona는 가장 보수적으로, 자기 고객에게 즉각 마이그레이션을 권하지 않습니다.

네 입장이 모순되지는 않습니다. 시간 축이 다를 뿐입니다. *"오늘 당장의 운영"*에는 Percona, *"다음 분기의 신규 도입"*에는 Avrot, *"내년의 기술 선택"*에는 Pettus, *"5년 뒤 OSS가 어떻게 살아남을까"*에는 Bartolini가 답합니다.

대안 도구 비교

운영자 입장에서 결정에 필요한 정보만 압축하면 다음과 같습니다.

도구메인테이너백업 모델PITR증분오브젝트 스토리지비고
Barman(바만)EnterpriseDB (활발)rsync / pg_basebackup 위임지원지원지원 (S3, Azure, GCS)CNPG가 채택. "복사는 PG에 위임, 오케스트레이션에 집중" 철학
WAL-GAiven 등 (활발)스트리밍 + 압축지원지원 (delta)지원클라우드 네이티브, MySQL, SQL Server, MongoDB도 지원
pg_basebackup + pg_combinebackupPG 코어PG 내장수동지원 (PG17+)해당 없음외부 의존 회피, 중소 규모
pgmoneta커뮤니티 (GSoC 활발)내장 + 인크리멘털지원지원부분신생, 검증 데이터 부족
pg_dump / pg_dumpallPG 코어논리 export해당 없음해당 없음해당 없음백업 도구 아님. 마이그레이션/스키마 덤프용

마지막 두 행이 좀 어색해 보이지만, Avrot가 원문에서 한 번 더 짚어준 부분이라 굳이 표에 남겼습니다.

"pg_basebackup is a clone tool, not a backup tool. pg_dump is an export tool."

(pg_basebackup은 클론 도구이지 백업 도구가 아니다. pg_dump는 export 도구다.)

PostgreSQL 입문자가 *"PostgreSQL에 기본으로 들어 있는 거 쓰면 되지 않나"*라고 생각하기 쉽지만, WAL 관리, 복구 명령, 무결성 검증 중 어느 것도 자체적으로 제공하지 않습니다. pg_basebackup으로 만든 base에 자체 WAL 보존/복구 스크립트를 얹는 방식은 곧 직접 만든 mini-Barman이 되며, 그러느니 진짜 Barman을 쓰는 게 낫습니다.

pg_basebackup + pg_combinebackup (PostgreSQL 17+) 조합은 블록 레벨 증분이 들어왔으므로 외부 도구를 도입하기 싫은 작은 클러스터에는 의미 있는 선택지입니다. 다만 오브젝트 스토리지 직결, 보존 정책, 병렬 복원 같은 운영 편의는 직접 짜야 합니다.

선택은 대체로 둘로 좁혀집니다.

베어메탈/VM 운영, EDB 중심 생태계, K8s 환경(CNPG)에는 Barman이 어울립니다. 멀티 클라우드 / 멀티 DB 엔진을 한 도구로 통일하거나 스트리밍 친화적인 구성을 원한다면 WAL-G가 어울립니다.

CNPG와 Barman

쿠버네티스에서는 이미 답이 나와 있습니다.

쿠버네티스에서 PostgreSQL을 운영 중이라면 이번 일에 가장 마음 편한 쪽입니다. CloudNativePG(CNPG)가 처음부터 Barman 진영에 서 있었기 때문입니다.

CNPG 공식 문서는 현재 백업 메서드를 세 가지로 명시합니다.

  1. plugin: CNPG-I 플러그인 기반 백업. 공식 권장 경로
  2. volumeSnapshot: Kubernetes CSI 볼륨 스냅샷
  3. barmanObjectStore: Barman Cloud 네이티브 통합. v1.26부터 deprecated

핵심은 1번입니다. 네이티브로 들어 있던 Barman Cloud 통합이 v1.26부터 deprecated 처리됐고, 공식 권장 경로는 Barman Cloud Plugin으로 옮겨갔습니다. 즉 코어와 백업 도구가 분리된 플러그인 구조로 진화 중입니다. pgBackRest는 CNPG 공식 문서에 등장하지 않습니다.

흐름을 그림으로 정리하면 다음과 같습니다.

Bartolini의 글에 이 분리의 철학이 잘 정리돼 있습니다.

"Barman delegates data copy mechanisms to PostgreSQL primitives and rsync, focusing instead on orchestration, retention, and recovery management."

(Barman은 데이터 복사 자체는 PostgreSQL의 기본 기능과 rsync에 위임하고, 자기는 오케스트레이션·보존·복구 관리에 집중한다.)

pgBackRest는 정반대 결정을 한 도구였습니다. 복사 메커니즘을 자기 안에 두고 끝까지 통제한다는 쪽입니다. 둘 중 어느 쪽이 옳다고 단정하긴 어렵습니다. 다만 K8s 오퍼레이터의 역할 분담 모델에는 역할을 잘게 쪼개고 위임하는 Barman 쪽이 잘 맞는다는 점이 결국 드러났습니다.

요약하면 이렇습니다.

  • 베어메탈/VM에서 pgBackRest를 쓰고 있었다면 다음 메이저 업그레이드 사이클에 Barman 또는 WAL-G로의 마이그레이션을 평가합니다.
  • K8s + CNPG 환경이라면 이미 Barman Cloud Plugin이 표준이므로 별도 의사결정이 거의 필요하지 않습니다.

운영자 입장에서 지금 무엇을 할 것인가

0. 호흡 한 번. 즉각 위험은 없다.
1. 인벤토리 — 어느 클러스터가 pgBackRest를 쓰는지
2. 다음 PostgreSQL 메이저 업그레이드 일정 = 분기점
3. 신규 클러스터 / 평가 단계는 Barman 또는 WAL-G로
4. K8s라면 CNPG + Barman Cloud Plugin
5. 단독 메인테이너 의존도가 높은 도구를 식별
6. 백업이 아니라 복구 — 정기 복구 리허설

조금 풀어 쓰면 다음과 같습니다.

  1. 즉시 교체할 필요는 없습니다. v2.58.0은 PostgreSQL 18까지 공식 지원하고, Percona가 *"계속 쓰라"*는 공식 입장을 냈습니다. 패닉 마이그레이션은 추가 사고를 만듭니다.
  2. 분기점은 다음 PostgreSQL 메이저 업그레이드 시점. PostgreSQL 19 이후 호환성/보안 이슈가 생겼을 때 아무도 책임지지 않습니다. 그 시점까지 마이그레이션 계획만 잡아두면 충분합니다.
  3. 신규로 도입한다면 archived 도구를 새로 들이는 건 합리적이지 않습니다. Avrot의 권고대로 Barman부터 평가합니다.
  4. K8s + CNPG 환경에서는 사실상 의사결정이 끝났습니다. Barman Cloud Plugin으로 가면 됩니다.
  5. 이번 사건의 일반화된 교훈. 운영 critical path에 단독 메인테이너 의존 도구가 또 어디에 있는지 한 번 훑어볼 가치가 있습니다. 같은 일이 다른 도구에서 다시 일어나지 말란 법이 없습니다.
  6. 백업이 아니라 복구가 본질입니다. 어느 도구로 옮기든, 옮긴 직후 복구 리허설을 한 번 돌려보지 않으면 실제로는 백업이 없는 것과 같습니다.

오픈소스 인프라의 자본 문제에 대한 단상

Bartolini는 글에서 "선순환(virtuous cycle)"이라는 표현을 썼습니다.

"Companies invest in engineers who build open-source software. That software creates production value. Those organizations purchase commercial support. Companies reinvest profits into engineering."

(회사가 엔지니어에 투자해 OSS를 만든다 → OSS가 운영 가치를 만든다 → 그 운영 가치가 상용 지원으로 환원된다 → 회사가 다시 엔지니어에 재투자한다.)

이 사이클은 어느 한 고리만 끊겨도 무너집니다. pgBackRest는 Crunchy Data의 후원이라는 한 고리에 매달려 있다가, 그 회사의 매각이라는 외생 변수 한 번에 끊겼습니다. 그 단계에서 커뮤니티 후원이 빈자리를 못 메웠다는 게 사건의 본질입니다.

오픈소스가 공짜라는 건 사용자 입장에서의 이야기입니다. 누군가는 그 비용을 치르고 있고, 그 비용 청구서가 어디에도 도착하지 않으면 결국 한 사람이 13년을 혼자 지키다가 손을 놓게 됩니다. 한 사람이 13년을 지킨 코드는 그 자체로 이미 자본 부족을 증명합니다.

Pettus의 한 줄이 이 단상을 닫기에 가장 정확합니다.

"This is not a problem with a technical solution. In the long run, it is the only important problem."

(이건 기술적 해법이 있는 문제가 아니다. 장기적으로 보면, 사실 그것만이 유일하게 중요한 문제다.)

정리

어제까지오늘부터
pgBackRest 상태사실상 표준archived (v2.58.0 동결)
단독 메인테이너David Steele 13년(미정, 포크 가능성 있음)
후원 모델Crunchy Data 단독 (~2024)후원 부재 → (2026-05-04) sponsor coalition 재구성 중 (현재: Supabase)
신규 평가 권장pgBackRestBarman (또는 WAL-G), 정식 발표 후 재평가
K8s 환경다양한 옵션 검토 가능CNPG + Barman Cloud Plugin
즉각 위험해당 없음없음 (다음 메이저 업그레이드까지)
장기 위험해당 없음PG 신버전 호환성/보안 패치 공급 단절

pgBackRest는 죽지 않았습니다. 다만 누군가의 13년이 끝났을 뿐이고, 우리는 그다음을 준비할 시간이 있습니다.

같은 일이 다음에 일어날 도구는 어디일까요. 그 질문이 이번 사건이 우리에게 남긴 진짜 숙제예요.

참고 자료