본문으로 건너뛰기

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

모든 태그 보기

Azure HorizonDB 공개 프리뷰

· 약 6분

Microsoft가 Build 2026에서 Azure HorizonDB를 공개 프리뷰로 내놓았어요. compute와 storage를 분리한 scale-out 구조 위에 벡터 검색과 in-database 모델 호출을 얹은 PostgreSQL 호환 관리형 데이터베이스예요.

작년 12월 Ignite에서 early preview로 처음 모습을 비친 뒤, 2026-06-03 Build 발표로 공개 프리뷰에 들어갔습니다. 같은 시기 AWS는 Aurora DSQL을 정식 출시했고, Google은 AlloyDB를 계속 키우는 중입니다. 클라우드 3사가 약속이라도 한 듯 "PostgreSQL 호환"을 새로 짓고 있습니다.

발표를 사실 단위로 끊어 보면

발표를 사실 단위로 끊어 정리합니다. 1차 출처는 Microsoft 공식 블로그Azure 블로그의 Build 2026 데이터베이스 발표입니다.

  • HorizonDB는 PostgreSQL 호환 관리형 데이터베이스입니다. 기존 Azure Database for PostgreSQL과 별개의 새 서비스로 출발했습니다.
  • compute와 storage를 분리하고, 공유 storage 위에서 scale-out하는 구조입니다. Microsoft는 "compute와 storage를 완전히 분리했다"고 적었습니다.
  • scale-out compute는 primary와 replica 노드를 합쳐 최대 3,072 vCore까지, auto-scaling 공유 storage는 최대 128TB까지 지원한다고 밝혔습니다.
  • 다중 zone에 걸쳐 sub-millisecond commit latency를 낸다고 주장합니다.
  • 트랜잭션 워크로드 기준 오픈소스 PostgreSQL 대비 최대 3배 throughput을 주장합니다. Microsoft가 든 예시는 self-managed 4,200 TPS 대비 HorizonDB 11,000+ TPS입니다.
  • AI 쪽으로는 DiskANN 기반 벡터 검색, pgvector, pg_textsearch를 묶은 hybrid search, 그리고 SQL에서 모델을 직접 호출하는 azure_ai extension을 얹었습니다.

공개 프리뷰는 일부 region에서 먼저 열렸습니다. Australia East, Central US, Sweden Central, West US 2, West US 3에서 시작하고, East US, Canada Central, Japan East, Korea Central 등은 곧 추가된다고 밝혔습니다. AI 모델 관리 기능은 별도로 limited preview 단계입니다.

storage 계층을 새로 짠 아키텍처

HorizonDB가 내세우는 핵심은 storage 계층 재설계입니다. Microsoft는 이를 "database-as-logs" 설계라고 부르는데, 트랜잭션을 공유 WAL storage에 직접 commit하는 방식입니다. compute 노드는 상태를 로컬에 묶어두지 않고, 영속성은 분리된 공유 storage가 책임집니다.

이렇게 분리하면 운영 관점에서 두 가지가 달라집니다. 첫째, write latency를 낮추고 commit을 다중 zone에 걸쳐 처리하면서도 sub-millisecond를 노립니다. 둘째, failover가 예측 가능해집니다. compute 노드가 죽어도 데이터는 공유 storage에 남아 있으므로, 새 노드가 같은 storage를 붙잡으면 됩니다. 데이터를 통째로 옮기는 과정이 빠지기 때문입니다.

PostgreSQL 호환의 의미도 짚어야 합니다. HorizonDB는 PostgreSQL 엔진 위에서 storage 계층을 갈아끼운 형태에 가깝습니다. planner, executor, SQL 문법, extension 생태계 같은 PostgreSQL 상단은 그대로 두고, heap과 WAL이 디스크에 닿는 아래쪽을 클라우드 native storage로 바꾼 구조입니다. 그래서 기존 드라이버, ORM, extension을 그대로 쓰면서도, 단일 인스턴스 PostgreSQL의 storage 한계를 우회하려 합니다.

AI 기능 중 눈에 띄는 건 azure_ai extension입니다. 모델 추론을 PostgreSQL 엔진 안으로 끌어들여 SQL에서 함수로 호출하게 합니다. 임베딩 생성이나 추론을 위해 애플리케이션이 외부 모델 서비스로 따로 나갔다 오는 orchestration 계층을 줄이려는 의도입니다. 벡터 검색은 Microsoft의 DiskANN을 써서 메모리와 디스크를 함께 활용하고, 필터를 건 그래프 탐색도 빠르게 처리한다고 주장합니다.

Aurora DSQL/AlloyDB와의 구도

"PostgreSQL 호환을 새로 짓는다"는 한 문장으로 묶이지만, 세 제품이 노리는 지점은 조금씩 다릅니다. 그대로 같은 칸에 놓고 비교하면 오해가 생깁니다.

항목Azure HorizonDBAWS Aurora DSQLGoogle AlloyDB
상태공개 프리뷰(2026-06)정식 출시(2025-06 GA)정식 출시
호환 기준PostgreSQL 호환PostgreSQL 16 호환PostgreSQL 완전 호환(18 GA)
구조compute/storage 분리 scale-out컴포넌트 분리 active-active 분산 SQLcompute/storage 분리(log 기반)
강점sub-ms commit, AI 내장무한 확장, 다중 region 쓰기분석 columnar engine, HTAP
호환성 제약프리뷰, 검증 진행 중foreign key/일부 타입 미지원, 재시도 로직 필요표준에 가까움
주 경쟁 상대단일 PG 한계를 넘는 관리형 PG분산 SQL(Spanner/CockroachDB)Aurora/관리형 PG

Aurora DSQL은 결이 가장 다릅니다. query processor, adjudicator, journal 같은 컴포넌트를 쪼개 독립 확장하는 active-active 분산 SQL이고, sharding 없이 읽기/쓰기를 따로 확장한다고 내세웁니다. 대신 10,000 row 트랜잭션 제한, foreign key/일부 타입 미지원, optimistic concurrency에 따른 애플리케이션 재시도 로직 같은 제약이 따라붙습니다. 분류상 Spanner/CockroachDB 쪽 분산 SQL과 경쟁합니다.

AlloyDB는 Aurora와 같은 칸에 있는, compute/storage를 분리한 관리형 PostgreSQL입니다. 가장 큰 차별점은 columnar engine입니다. 분석 쿼리에서 오픈소스 PostgreSQL 대비 최대 100배 빠르다고 주장하며 HTAP를 노립니다. PostgreSQL 18도 이미 GA에 올렸습니다.

HorizonDB는 이 둘 사이 어딘가에 있습니다. Aurora DSQL처럼 호환성을 깨면서까지 분산 SQL로 가지 않고, AlloyDB처럼 compute/storage 분리에 머무르되, 차별점을 sub-millisecond commit과 AI 내장 쪽으로 잡았습니다. 정리하면 셋 다 "단일 인스턴스 PostgreSQL의 storage/확장 한계"라는 같은 문제를 풀되, AWS는 분산 일관성, Google은 분석, Microsoft는 AI 워크로드라는 서로 다른 입구로 들어간 셈입니다.

기존 Azure Database for PostgreSQL과 무엇이 다른가

이미 Azure Database for PostgreSQL flexible server를 쓰고 있다면, 당장 옮길 이유는 없습니다. HorizonDB는 별개의 새 서비스이고 아직 프리뷰입니다. 프로덕션 SLA, 모든 region, 익숙한 운영 도구가 다 갖춰지기 전까지는 검증 대상으로 보는 게 맞습니다.

차이를 운영 관점에서 추리면 이렇습니다.

  • storage 확장: flexible server는 단일 인스턴스 모델이라 storage/IOPS에 인스턴스 단위 상한이 있습니다. HorizonDB는 공유 storage를 최대 128TB까지 auto-scaling으로 키운다고 주장합니다. 한 데이터베이스가 수십 TB로 커지는 워크로드라면 이 차이가 큽니다.
  • 읽기 확장과 failover: scale-out compute와 공유 storage 분리는 replica 추가와 failover를 가볍게 만듭니다. 데이터를 통째로 옮기지 않고 같은 storage를 붙잡는 구조이기 때문입니다.
  • AI 워크로드: 벡터 검색과 in-database 모델 호출이 엔진에 들어 있어, 임베딩/검색을 별도 서비스로 빼지 않고 SQL 안에서 처리하려는 설계입니다. RAG나 agent용 데이터 계층을 PostgreSQL 한 곳에 모으려는 경우 매력이 있습니다.

반대로 신중하게 볼 점도 있습니다. 3배 throughput, sub-millisecond commit 같은 숫자는 모두 Microsoft가 자기 벤치마크로 든 주장입니다. 워크로드, region, 구성에 따라 결과는 달라지므로, 옮기기 전에 자기 데이터로 직접 측정하는 게 맞습니다. extension 호환 범위, 기존 flexible server에서의 마이그레이션 경로, 백업, PITR, 모니터링 도구가 어디까지 따라오는지도 프리뷰 기간에 확인할 항목입니다.

큰 그림에서 보면, 클라우드 벤더가 PostgreSQL 호환을 새로 짓는 흐름은 PostgreSQL이 사실상 관리형 데이터베이스의 공통 인터페이스가 됐다는 신호입니다. 엔진은 같은 PostgreSQL을 쓰되 storage와 확장 계층을 각자 새로 짜고, 그 위에 AI, 분석, 분산이라는 차별점을 얹습니다. DBA 입장에서는 PostgreSQL 한 가지 언어로 여러 벤더의 관리형 제품을 평가할 수 있다는 뜻이고, 동시에 "호환"이라는 단어 뒤에 숨은 제약을 제품마다 따져야 한다는 뜻이기도 합니다.

HorizonDB는 아직 프리뷰예요. 하지만 방향은 분명해요. Microsoft는 PostgreSQL 위에 storage를 갈아끼우고 AI를 엔진 안으로 끌어들이는 길을 택했고, 이 선택이 Aurora DSQL/AlloyDB와 나란히 놓이면서 "PostgreSQL 호환을 새로 짓는" 3파전이 한층 또렷해졌어요.

AlloyDB AI 에이전트 연동

· 약 6분

Google Cloud가 2026년 6월 2일 AlloyDB Remote MCP Server를 정식 출시(GA)했어요. AI 에이전트가 AlloyDB(PostgreSQL 호환) 데이터베이스에 표준 프로토콜로 직접 붙어 SQL을 실행하고 인스턴스를 관리할 수 있게 됐어요.

여기서 눈여겨볼 단어는 GA입니다. 프리뷰 단계의 실험 기능이 아니라 production에 올려도 된다는 신호이며, 곧 실무 환경에서 에이전트가 운영 데이터베이스에 접근하는 구성이 현실이 된다는 뜻입니다. 운영자와 DBA 입장에서는 "AI가 우리 DB에 직접 붙는다"는 상황을 이제 설계 대상으로 다뤄야 합니다.

표준 프로토콜 하나로 붙는다

MCP(Model Context Protocol)는 LLM이 외부 데이터/도구에 일관된 방식으로 연결되도록 만든 오픈 표준입니다. 모델마다, 도구마다 제각각이던 연동 방식을 하나의 규약으로 묶는다고 보면 됩니다. 에이전트는 MCP 서버가 노출하는 도구(tool) 목록을 받아 보고, 그중 필요한 것을 골라 호출합니다. "데이터베이스에 질의해줘"라는 요청이 들어오면, 에이전트가 MCP 서버의 SQL 실행 도구를 호출하는 식입니다.

AlloyDB Remote MCP Server는 이 규약을 AlloyDB에 입힌 것입니다. Google Cloud의 관리형 인프라 위에서 동작하고, HTTP 엔드포인트 하나를 노출합니다.

https://alloydb.googleapis.com/mcp

"Remote"라는 이름이 붙은 이유가 여기 있습니다. 예전 MCP 연동은 보통 로컬에서 stdio 스트림으로 도는 서버를 띄워 쓰는 방식이었습니다. 이번 GA는 그 서버를 Google Cloud가 직접 관리형으로 호스팅합니다. 운영자가 별도 서버를 배포하거나 패치할 필요 없이, 인증된 에이전트가 원격 엔드포인트로 붙습니다.

노출하는 도구는 크게 두 갈래입니다.

갈래대표 도구하는 일
데이터베이스execute_sql, execute_sql_read_onlySQL 실행 (쓰기/읽기 전용)
데이터베이스export_data, import_data데이터 반출/반입
사용자 관리create_user, list_users, get_user데이터베이스 사용자 관리
인스턴스 관리create_instance, update_instance, get_instance인스턴스 생성, 변경, 조회
클러스터 관리create_cluster, restore_cluster, create_backup클러스터/백업 관리

주목할 점은 도구가 단순 조회에 그치지 않는다는 것입니다. SQL 실행은 물론이고 인스턴스 변경, 데이터 반출입, 백업 생성과 클러스터 복원까지 포함합니다. 에이전트가 마음만 먹으면 운영 작업 상당수를 직접 수행할 수 있는 범위입니다. 그만큼 권한 경계가 중요해집니다.

읽기 전용 도구가 별도로 있다는 점도 눈여겨볼 만합니다. execute_sql은 쓰기까지 가능하지만, execute_sql_read_only는 수정/삭제를 막습니다. 에이전트가 의도치 않게 데이터를 바꾸는 사고를 도구 수준에서 차단하는 장치입니다.

인증/권한 모델

에이전트가 어떻게 인증하고 무엇까지 할 수 있는지가 운영의 핵심입니다. AlloyDB Remote MCP Server는 공유 비밀번호나 API 키를 쓰지 않습니다. 실제로 공식 문서는 "이 서버는 API 키를 받지 않는다"고 못박습니다.

인증은 OAuth 2.0 bearer 토큰으로 합니다. 에이전트는 Google Cloud IAM 신원으로 발급받은 토큰을 HTTP Authorization 헤더에 실어 보냅니다. 모든 Google Cloud 신원이 인증 주체가 될 수 있습니다.

권한은 IAM 역할로 갈립니다. 도구가 요구하는 역할이 작업 종류에 따라 다릅니다.

작업필요 역할
인스턴스/사용자 생성roles/alloydb.admin
SQL 실행 (쓰기 포함)roles/alloydb.admin 또는 roles/alloydb.databaseUser
읽기 전용 SQLroles/alloydb.viewer, roles/alloydb.databaseUser, roles/alloydb.admin
인스턴스/사용자 목록 조회roles/alloydb.viewer

OAuth 스코프는 https://www.googleapis.com/auth/alloydb가 기본입니다. 즉 에이전트가 할 수 있는 일의 상한은 그 에이전트에 붙은 IAM 역할이 결정합니다. 비밀번호를 공유하던 시절처럼 "DB에 붙을 수 있으면 전부 다 된다"가 아니라, 신원별로 역할을 좁혀 부여하는 구조입니다.

여기서 DBA가 정확히 이해해야 할 분리가 하나 있습니다. 에이전트가 들고 오는 IAM 신원과 실제 데이터베이스 내부의 사용자 권한은 별개 층위입니다. IAM 역할은 "이 에이전트가 AlloyDB API를 호출할 수 있는가"를 가릅니다. 그 호출이 데이터베이스 안에서 어떤 테이블/스키마까지 읽고 쓰는지는 데이터베이스 자체의 GRANT/REVOKE로 통제합니다. Google Cloud는 IAM으로 에이전트를 특정 테이블, 스키마, 뷰에 한정할 수 있다고 안내하는데, 실제 운영에서는 IAM 역할 부여와 데이터베이스 권한을 양쪽 다 좁혀야 의미가 살아납니다.

통제 지점을 어디에 두나

AI 에이전트가 production 데이터베이스에 직접 붙는다는 건, 사람 손을 거치지 않은 호출이 운영 작업을 일으킬 수 있다는 뜻입니다. 통제 지점을 정리합니다.

에이전트는 사람과 다르게 행동합니다. 잘못된 판단으로 DELETEDROP을 내릴 수 있고, 프롬프트 조작에 넘어가 의도하지 않은 질의를 던질 수도 있습니다. 권한, 감사, 입력 검증을 사람 DBA보다 더 촘촘하게 잡아야 하는 이유입니다.

에이전트마다 별도 IAM 신원을 부여하고 작업에 꼭 필요한 역할만 붙입니다. 조회만 하는 에이전트에 roles/alloydb.admin을 주는 일은 없어야 합니다. 최소 권한의 기본값은 roles/alloydb.viewer 수준에서 시작해 필요할 때 올립니다.

분석/조회가 목적이라면 execute_sql_read_only만 쓰도록 제한합니다. 쓰기가 가능한 execute_sql은 명확히 필요한 경우에만, 권한을 좁힌 별도 신원에 한정합니다. update_instance, restore_cluster, import_data 같은 도구는 데이터베이스의 형상 자체를 바꾸므로, 에이전트가 이런 도구에 닿을 이유가 없다면 IAM 역할에서 해당 권한을 빼 원천 차단합니다.

모든 질의, 동작, 도구 호출은 Cloud Audit Logs에 남습니다. 어떤 신원이 언제 무슨 도구를 호출했는지 추적할 수 있습니다. 단순히 켜두는 데서 끝내지 말고 비정상 패턴(대량 반출, 권한 밖 시도)에 대한 알림까지 엮어야 통제가 완성됩니다.

Google Cloud는 Model Armor라는 선택적 보호 계층도 제공합니다. 프롬프트 injection을 거르고 데이터 반출을 막는 용도입니다. 에이전트가 외부 입력을 받는 구성이라면 이 계층을 검토할 가치가 있습니다.

앞서 짚었듯 IAM만으로는 부족합니다. 데이터베이스 안에서도 에이전트용 role을 만들어 접근 가능한 스키마/테이블을 GRANT로 한정합니다. IAM과 데이터베이스 권한이 모두 좁아야 실효가 있습니다.

결국 권한 모델은 데이터베이스가 더 이상 사람만 붙는 곳이 아니라는 전제에서 다시 짜야 합니다. 사람은 실수해도 속도가 느리지만, 에이전트는 잘못된 동작을 빠르게 반복합니다.

흐름과 권한 경계

에이전트 요청이 데이터베이스에 닿기까지의 경로와, 그 위에 놓인 두 겹의 권한 경계를 도식으로 정리합니다.

위쪽 IAM 검사는 "이 신원이 이 도구를 호출할 자격이 있는가"를 가르는 1차 경계입니다. 통과해도 데이터베이스 안에서 GRANT로 정해진 범위를 벗어나면 2차 경계에서 막힙니다. 두 경계를 모두 통과한 작업만 실행되고, 그 흔적은 빠짐없이 감사 로그에 남습니다. DBA가 손볼 지점은 결국 이 두 경계의 폭과 마지막 로그를 읽어내는 체계입니다.

마치며

AlloyDB Remote MCP Server GA는 "AI 에이전트가 데이터베이스에 직접 붙는" 구성이 실험을 넘어 production 선택지가 됐다는 신호입니다. 편의는 분명합니다. 자연어로 질의하고, 스키마를 자동으로 파악하고, 운영 작업까지 위임할 수 있습니다.

그만큼 DBA가 쥐어야 할 통제도 늘었어요. 비밀번호 공유가 IAM 신원으로 바뀌고 사람의 클릭이 에이전트의 도구 호출로 바뀌는 동안, 권한은 더 좁게, 감사는 더 촘촘하게 가져가야 해요. 데이터베이스에 새 문이 하나 열렸으니, 그 문의 자물쇠와 출입 기록을 챙기는 일이 다음 차례예요.


출처:

PG19 온라인 체크섬 전환

· 약 8분

PostgreSQL 19에서 data_checksums가 또 하나의 재시작 파라미터에서 벗어났어요. 이제 실행 중인 클러스터에서 재시작도 정지도 없이 page checksum을 켜고 끌 수 있어요. SQL 함수 하나를 실행하면 background worker가 모든 page를 다시 쓰면서 checksum을 입히고, 그동안 클러스터는 평소처럼 트래픽을 받아요.

이 글은 The Build의 Christophe Pettus(크리스토프 페투스)가 정리한 "All Your GUCs in a Row: data_checksums"를 한국어로 풀고, 13년에 걸친 data_checksums의 진화사와 PostgreSQL 19가 정확히 무엇을 바꿨는지를 DBA 시선으로 봅니다. 그리고 "온라인"이라는 단어가 "공짜"나 "즉시"를 뜻하지 않는다는 점까지 함께 짚습니다.

dbalog에는 PostgreSQL 19의 "재시작 없이 바꾼다" 계열 글이 이미 두 편 있습니다. wal_level이 고정값에서 동적 floor로 바뀐 이야기autovacuum_worker_slots로 worker 수를 재시작 없이 조절하는 이야기입니다. data_checksums의 온라인 전환은 그 흐름 위에 올라가는 또 한 칸입니다.

data_checksums가 무엇을 막아주나

data_checksums는 page 단위 checksum 기능을 켜는 read-only GUC입니다. 켜져 있으면 PostgreSQL은 data page를 디스크에 쓸 때마다 checksum을 계산해 page 안에 함께 적고, 그 page를 다시 읽어 올릴 때 checksum을 검증합니다.

값이 맞지 않으면 PostgreSQL은 깨진 데이터를 그대로 돌려주지 않고 error를 냅니다. 여기서 막아주는 대상은 silent data corruption, 즉 조용히 번지는 손상입니다.

  • bit rot, 디스크 위 데이터가 시간이 지나며 미세하게 망가지는 현상
  • 고장 직전의 디스크가 슬그머니 잘못된 비트를 돌려주는 경우
  • "썼다"고 응답해 놓고 실제로는 쓰지 않은 storage layer의 거짓말

이런 손상은 error 없이 흘러갑니다. checksum이 없으면 PostgreSQL은 깨진 page를 멀쩡한 데이터로 믿고 그대로 읽어 들이고, 그 위에 연산을 쌓습니다. 문제를 알아챌 무렵엔 이미 backup에까지 손상이 번진 뒤입니다.

검증에 실패하면 PostgreSQL은 pg_stat_databasechecksum_failures 카운터를 올립니다. DBA는 이 값을 모니터링해 손상이 처음 감지된 시점을 잡아낼 수 있습니다.

비용은 어떻습니까. 2013년 도입 당시엔 checksum 계산 부담이 켤 가치가 없을 만큼 크다고 봤습니다. 그래서 기본값이 off였습니다. 그 뒤로 하드웨어가 좋아지면서 오버헤드는 한 자릿수 퍼센트 초반대까지 내려왔고, 손상을 조기에 잡는 가치에 비하면 충분히 감당할 만한 수준이 됐습니다.

과거엔 켜기가 왜 고통이었나

문제는 비용이 아니라 켜는 방법이었습니다. PostgreSQL 18까지 data_checksums를 켜는 길은 둘뿐이었고, 둘 다 운영 클러스터에는 무겁습니다.

첫째, initdb 시점에 정하는 것입니다. 클러스터를 처음 만들 때 checksum을 켜두면 그 클러스터는 평생 켜진 상태로 삽니다. 깔끔하지만 시점이 고약합니다. 이미 몇 년째 돌고 있는 운영 클러스터에는 적용할 길이 없습니다. "처음부터 켰어야 했다"는 후회만 남습니다.

둘째, pg_checksums로 오프라인 전환하는 것입니다. PostgreSQL 12에서 추가된 이 명령은 멈춰 있는 클러스터의 checksum 설정을 바꿔줍니다. 강조점은 "멈춰 있는"입니다.

# 반드시 클러스터를 먼저 정지한 상태에서 실행
pg_ctl -D /var/lib/pgsql/data stop
pg_checksums --enable -D /var/lib/pgsql/data
pg_ctl -D /var/lib/pgsql/data start

pg_checksums는 모든 heap과 index page를 한 장씩 읽어 checksum을 계산해 다시 씁니다. 멀티 테라바이트 클러스터라면 이 작업만 몇 시간이 걸립니다. 그리고 그 몇 시간 내내 클러스터는 내려가 있어야 합니다.

DBA에게 이건 사실상 "큰맘 먹고 잡는 점검 시간"입니다. 서비스 중단 공지를 내고, 새벽 시간을 확보하고, 작업이 예상보다 길어질 경우까지 대비해야 합니다. 그래서 많은 운영 클러스터가 checksum의 가치를 알면서도 "지금 켜기엔 다운타임이 부담"이라는 이유로 off인 채 남았습니다.

PostgreSQL 18에서 한 발 나아가긴 했습니다. initdb의 기본값이 checksum 켜짐으로 바뀌어, 새로 만드는 클러스터는 별도 조치 없이 checksum을 켠 채 출발합니다. 하지만 이는 새 클러스터 이야기입니다. 이미 돌고 있는 클러스터의 고민은 그대로였습니다.

PostgreSQL 19의 온라인 전환

PostgreSQL 19는 마지막 매듭을 풉니다. 클러스터를 멈추지 않고 재시작도 없이 SQL 함수 호출만으로 checksum을 켜고 끕니다. 새로 들어온 함수는 둘입니다.

pg_enable_data_checksums(cost_delay integer DEFAULT 0, cost_limit integer DEFAULT 100)
pg_disable_data_checksums()

켜는 동작은 이렇게 실행합니다.

SELECT pg_enable_data_checksums();

이 함수는 곧바로 반환됩니다. 밀리초 단위입니다. 하지만 그 시점에 checksum이 다 입혀진 것은 아닙니다. 실제 작업은 background에서 비동기로 흐릅니다.

내부 동작은 이렇습니다. background worker launcher가 데이터베이스마다 per-database worker를 띄웁니다. 이 worker는 storage를 가진 모든 relation의 buffer를 dirty로 표시합니다. dirty page는 디스크로 다시 쓰일 때 checksum을 계산해 함께 적게 됩니다. 모든 데이터베이스의 모든 relation이 처리되고 나면, 그제야 data_checksums 상태가 on으로 넘어갑니다.

OS의 process 목록에서도 이 launcher와 worker가 보입니다.

postgres: datachecksum launcher
postgres: datachecksum worker

진행 중에 data_checksums가 가질 수 있는 상태는 다음과 같습니다.

상태의미
offchecksum 꺼짐
inprogress-on켜는 중, page 재작성 진행 중
on켜짐, 모든 page 처리 완료
inprogress-off끄는 중

SHOW로 현재 상태를 확인합니다.

SHOW data_checksums;
-- 진행 중: inprogress-on
-- 완료 후: on

끄는 동작도 같은 방식입니다.

SELECT pg_disable_data_checksums();

이 모든 과정에서 클러스터는 멈추지 않습니다. 읽기도 쓰기도 평소처럼 받습니다. PostgreSQL 19에서는 다운타임이 사라졌습니다.

전환 흐름 비교

오프라인 전환과 온라인 전환의 차이를 한눈에 보면 이렇습니다.

PostgreSQL 18 이하의 경로는 정지-작업-재기동이라는 다운타임 구간을 통과해야 합니다. PostgreSQL 19는 그 구간 자체가 없습니다. 작업은 가동 중인 클러스터 위에서 background로 흐릅니다.

상태 전이로 보면 켜는 과정은 다음과 같이 움직입니다.

여기서 DBA가 기억할 점이 하나 있습니다. inprogress-on은 "켜지는 중"이지 "켜짐"이 아닙니다. 모든 page가 처리되기 전까지는 on으로 넘어가지 않습니다.

DBA 관점에서 보는 온라인 전환의 시간과 비용

함수가 밀리초 만에 반환된다고 해서 작업이 끝난 것은 아닙니다. 이 지점에서 운영 실수가 갈립니다. Christophe Pettus는 이 작업의 무게를 "minor version 업그레이드와 전체 클러스터 VACUUM FULL 사이 어디쯤"으로 보고 계획하라고 권합니다.

기억할 점을 정리하면 이렇습니다.

진짜 작업은 background에서 진행됩니다. 함수 반환은 시작 신호일 뿐이며, 멀티 테라바이트 클러스터에서 모든 page를 재작성하려면 몇 시간이 걸립니다.

이 작업은 다른 작업과 자원을 다툽니다. page 재작성은 autovacuum, 평상시 워크로드, backup 작업과 디스크 I/O를 두고 경쟁합니다. burst IOPS를 쓰는 클라우드 인스턴스라면 burst 예산을 일찍 소진하고 throttle 구간에 들어갑니다.

중간에 끊으면 일부 page에는 checksum이 입혀지고 일부에는 입혀지지 않은 mixed state로 남습니다. 이 상태 자체는 안전하지만, 작업이 끝나기 전까지 data_checksumson으로 넘어가지 않습니다. 오래 머물 상태는 아닙니다.

그래서 켜는 함수에는 throttle 제어가 붙어 있습니다. cost_delaycost_limit은 autovacuum의 vacuum cost 의미를 그대로 따릅니다. worker가 cost_limit만큼 작업 단위를 쌓을 때마다 cost_delay 밀리초씩 쉬게 해서, 평상시 워크로드에 주는 압박을 낮춥니다.

-- worker가 자원을 덜 차지하도록 천천히 진행
SELECT pg_enable_data_checksums(cost_delay => 1, cost_limit => 3000);

운영 현장에서 잡을 체크리스트는 단순합니다.

  • 트래픽이 한가한 시간대를 골라 시작합니다.
  • autovacuum이 급한 작업을 들고 있지 않은지 확인합니다.
  • backup window와 겹치지 않게 합니다.
  • 진행 중에는 pg_stat_io로 I/O 부하를, replication을 쓴다면 replica lag을 함께 봅니다.

PostgreSQL 19의 이번 변화를 앞선 두 글과 나란히 놓으면 방향이 또렷합니다. wal_level은 재시작 파라미터에서 동적 floor로, autovacuum worker 수는 재시작 없이 조절 가능하게, 그리고 이제 data_checksums는 클러스터를 멈추지 않고 켜고 끄는 대상이 됐습니다. "운영 중에 바꾸려면 재시작/정지가 필요하던 설정"의 목록이 한 칸씩 줄고 있습니다.

다만 방향이 같다고 비용까지 같진 않습니다. wal_level의 effective level 전환은 다음 checkpoint면 끝나지만, data_checksums의 온라인 전환은 디스크 위 모든 page를 다시 쓰는 무거운 작업입니다. "재시작이 사라졌다"와 "부담 없이 켤 수 있다"는 다른 말입니다. 다운타임은 없앴지만, I/O 비용과 소요 시간은 그대로 DBA의 계획표 위에 남습니다.

정리

  • data_checksums는 page 단위 checksum으로 silent data corruption을 조기에 잡아주는 기능입니다. 실패는 pg_stat_database.checksum_failures로 드러납니다.
  • PostgreSQL 18까지는 initdb 시점에 고정하거나, 클러스터를 정지하고 pg_checksums로 오프라인 전환해야 했습니다. 운영 클러스터엔 다운타임이 부담이었습니다.
  • PostgreSQL 18부터 initdb 기본값이 켜짐으로 바뀌어, 새 클러스터는 별도 조치 없이 checksum을 켠 채 출발합니다.
  • PostgreSQL 19는 pg_enable_data_checksums() / pg_disable_data_checksums()로 가동 중인 클러스터에서 재시작 없이 켜고 끌 수 있게 했습니다. background worker가 모든 page를 다시 쓰며, 진행 중 상태는 inprogress-on / inprogress-off로 보입니다.
  • 다운타임은 사라졌지만 작업 자체는 무거워요. 멀티 테라바이트 클러스터에서 몇 시간이 걸리고 다른 I/O와 경쟁하므로, cost_delay / cost_limit throttle과 한가한 시간대 시작이 필요해요.

출처

pg_stat_statements 해설

· 약 9분

pg_stat_statements는 컬럼이 스무 개가 넘지만, DBA가 매일 보는 건 사실 대여섯 개뿐이에요. 나머지는 그 대여섯 개를 해석할 때 보조로 쓰이며, 이 글에서는 핵심 컬럼을 읽는 법과 이 확장의 내부 동작 때문에 가끔 데이터가 비어 보이는 이유를 운영 관점에서 정리해요.

같은 주에 boringsql와 pganalyze가 이 주제를 각각 깊게 다뤘습니다. 두 글을 PostgreSQL 공식 문서로 교차 확인하면서 한국어 실무 가이드로 다시 엮었습니다.

pg_stat_statements가 수집하는 것

pg_stat_statements는 공유 메모리에 있는 고정 크기 해시 테이블입니다. 개별 실행을 하나하나 기록하는 게 아니라, 같은 모양의 쿼리를 하나의 항목으로 묶어 누적 카운터를 갱신합니다.

여기서 "같은 모양"의 기준은 정규화(normalization)입니다. 상수를 떼어내고 $1, $2 같은 자리표시자로 바꾼 뒤, 파싱된 쿼리 트리의 해시값을 queryid로 삼습니다. 그래서 아래 두 쿼리는 하나의 항목으로 집계됩니다.

SELECT * FROM users WHERE id = 42;
SELECT * FROM users WHERE id = 99;

여기서 DBA가 미리 알아둬야 할 정규화의 성질이 몇 가지 있습니다.

  • queryid는 메이저 버전 사이에서 안정적이지 않습니다. 같은 SQL이라도 메이저 업그레이드 후, 혹은 다른 CPU 아키텍처에서 다른 값으로 해시될 수 있습니다. 여러 서버의 통계를 묶을 때 queryid를 영구 조인 키로 쓰면 안 됩니다.
  • OID 기반이라 이름 기반이 아닙니다. 테이블을 drop하고 다시 만들면 새 OID가 붙고, 그 결과 새 queryid가 생깁니다. 이전 통계는 고아로 남습니다.
  • 구조에 민감합니다. 테이블 alias가 다르거나, 컬럼 목록이 바뀌거나, LIMIT이 붙거나, 조건 순서가 달라지면 논리적으로 같은 쿼리가 여러 항목으로 쪼개집니다. ORM이 이런 변형을 대량으로 쏟아내면 항목이 수백 개로 흩어지기도 합니다.

또 하나, 중요한 동작상의 제약이 있습니다. pg_stat_statements는 ExecutorEnd 단계에서 통계를 기록합니다. 즉 정상적으로 끝난 실행만 집계됩니다. 타임아웃으로 끊기거나 중간에 abort된 쿼리는 흔적을 남기지 않습니다. 장애 시점에 문제를 일으킨 쿼리가 정작 이 뷰에 안 보이는 경우가 여기서 나옵니다.

DBA가 봐야 할 핵심 컬럼

전체 컬럼은 공식 문서에 다 있습니다. 여기서는 운영 중에 실제로 손이 가는 것만 추립니다.

컬럼의미언제 보나
calls실행 횟수빈도. 한 번 느린지, 자주 느린지 구분
total_exec_time누적 실행 시간(ms)서버 부하에 가장 크게 기여하는 쿼리 찾기
mean_exec_time평균 실행 시간(ms)한 번 실행이 비싼 쿼리 찾기
min/max/stddev_exec_time최소, 최대, 표준편차(ms)편차가 큰 쿼리 식별
rows반환/영향 행 수호출당 결과 규모 추정
shared_blks_hitbuffer cache 적중 블록 수캐시 효율
shared_blks_read디스크에서 읽은 공유 블록 수실제 I/O 부담
wal_bytes생성한 WAL 양(bytes)쓰기 부하/복제 부담

느린 쿼리를 찾을 때 mean과 total 구분하기

가장 먼저 정해야 할 건 정렬 기준입니다. mean_exec_timetotal_exec_time은 전혀 다른 질문에 답합니다.

  • total_exec_time이 큰 쿼리는 서버 전체 부하에 가장 많이 기여하는 쿼리입니다. 한 번은 1ms로 빨라도 하루에 수천만 번 실행되면 누적 시간이 1위가 됩니다. 서버가 바쁜 원인을 찾을 때는 이 값을 봅니다.
  • mean_exec_time이 큰 쿼리는 한 번 실행이 비싼 쿼리입니다. 빈도는 낮아도 실행할 때마다 사용자를 기다리게 만듭니다. 특정 화면이 느리다는 제보를 추적할 때 유용합니다.
-- 누적 부하 상위 10개
SELECT
queryid,
calls,
round(total_exec_time::numeric, 1) AS total_ms,
round(mean_exec_time::numeric, 2) AS mean_ms,
rows,
query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

calls를 항상 함께 봐야 둘을 헷갈리지 않습니다. total_exec_time이 높은데 calls도 높으면 "자주 불려서 누적된" 것이고, calls가 낮은데 total이 높으면 "한 번이 무거운" 것입니다.

평균에서 사라지는 분포

pg_stat_statements는 평균(mean)과 표준편차(stddev)만 유지하고, 개별 실행 시간은 즉시 버립니다. 그래서 분포의 모양을 알 수 없습니다.

예를 들어 99%는 1ms에 끝나지만 1%는 2초가 걸리는 쿼리가 있다면, 평균은 약 21ms 근처로 찍힙니다. 이 21ms는 어느 실행도 대표하지 못하는 숫자입니다. 정작 문제가 되는 2초짜리 1%는 나머지 99%에 희석돼 평균 뒤로 묻힙니다. 게다가 pg_stat_statements는 p99(실행의 99%가 그 안에 들어오는 시간, 상위 1%를 잘라낸 경계) 같은 percentile 값을 주지 않으니, 평균만 봐서는 이런 느린 실행을 따로 짚을 길이 없습니다. stddev_exec_time이 평균에 비해 유난히 크거나 max_exec_time이 평균과 크게 벌어져 있다면, 그 쿼리는 분포가 넓다는 신호이니 별도로 들여다볼 가치가 있습니다.

I/O 컬럼의 hit와 read 읽기

shared_blks_hitshared_blks_read는 짝으로 읽습니다.

  • shared_blks_hit은 buffer cache에서 바로 찾은 블록 수입니다. 빠릅니다.
  • shared_blks_read는 buffer에 없어서 디스크(또는 OS page cache)에서 읽어 온 블록 수입니다. 느립니다.

shared_blks_read가 크다는 건 그 쿼리가 실제 I/O를 많이 일으킨다는 뜻입니다. 작업 집합이 buffer pool보다 크거나, 인덱스 없이 큰 테이블을 스캔하고 있을 가능성이 있습니다. 두 값을 합친 대비 적중률을 보면 캐시 효율을 가늠할 수 있습니다.

읽기/쓰기에 걸린 실제 시간까지 보려면 shared_blk_read_time, shared_blk_write_time 컬럼을 봅니다. 단, 이 값은 track_io_timing이 켜져 있어야 채워지고, 꺼져 있으면 전부 0입니다.

temp_blks_read, temp_blks_written은 임시 파일 I/O입니다. 정렬이나 해시 조인이 work_mem을 넘겨서 디스크로 흘러넘쳤다는 신호이므로, 이 값이 큰 쿼리는 work_mem 조정이나 쿼리 재작성 후보입니다.

쓰기 부하를 보여주는 WAL 컬럼

wal_bytes, wal_records, wal_fpi는 그 쿼리가 만든 WAL 양을 보여줍니다. 쓰기가 많은 쿼리, 즉 replication 지연이나 디스크 쓰기 부하의 원인을 찾을 때 봅니다. wal_fpi(full page image)가 유난히 크면 checkpoint 직후의 첫 쓰기에서 페이지 전체가 WAL에 기록되는 패턴일 수 있습니다.

버전에 따른 total_time 분리

PostgreSQL 13에서 타이밍 컬럼 이름이 바뀌었습니다. 12 이하에서는 total_time, mean_time 한 묶음이었지만, 13부터 계획(planning)과 실행(execution)이 분리되어 total_plan_time/total_exec_time, mean_plan_time/mean_exec_time으로 나뉘었습니다. 12 이하를 대상으로 한 옛 쿼리는 13 이상에서 컬럼명을 바꿔줘야 동작합니다.

단, 계획 시간 컬럼(total_plan_time 등)은 pg_stat_statements.track_planning이 켜져 있어야 채워집니다. 이 설정의 기본값은 off입니다. 계획 시간이 전부 0으로 보인다면 이 설정부터 확인합니다.

PostgreSQL 17부터는 stats_since(항목 통계 수집이 시작된 시각)와 minmax_stats_since(min/max 통계 수집 시작 시각) 컬럼이 추가됐습니다. 어떤 구간을 측정할 때 그 사이에 eviction이나 리셋이 끼었는지 판단하는 데 씁니다.

해시 테이블이 가득 찰 때의 eviction과 dealloc

pg_stat_statements가 추적하는 서로 다른 쿼리 수에는 상한이 있습니다. pg_stat_statements.max이고 기본값은 5000입니다. 이 값은 서버 시작 시에만 설정할 수 있습니다.

서로 다른 쿼리 수가 이 상한을 넘으면 eviction(축출)이 일어납니다. 공식 문서는 "가장 적게 실행된(least-executed) 항목 정보를 버려서 새 항목 자리를 만든다"고 설명합니다. 내부적으로는 각 항목에 겉으로 드러나지 않는 usage 카운터가 있고, deallocation 시점에 모든 usage 값을 일정 비율 줄인 뒤 정렬해서 하위 일부를 버립니다. 이 정렬은 항목 수에 비례하는 작업이며, exclusive lock을 잡은 채로 진행됩니다.

그래서 pg_stat_statements.max를 무작정 키우는 건 공짜가 아닙니다. max가 클수록 deallocation 시점의 정렬 비용이 커지고, 그동안 lock 경합도 길어집니다.

축출이 일어났는지는 별도 뷰인 pg_stat_statements_info로 확인합니다. 이 뷰는 단 한 행이고 컬럼 두 개를 가집니다.

컬럼의미
deallocmax를 초과해 항목이 축출된 누적 횟수
stats_reset전체 통계가 마지막으로 리셋된 시각
SELECT dealloc, stats_reset FROM pg_stat_statements_info;

dealloc이 계속 올라간다면, 테이블이 쉼 없이 가득 차고 비워지는 중입니다. 이 상태에서는 자주 실행되지 않는 쿼리의 통계가 수시로 사라지므로 데이터를 신뢰하기 어렵습니다. ORM이 구조가 조금씩 다른 쿼리를 대량으로 흘려보내 해시 테이블을 가득 채우는 경우가 대표적입니다. 이때 실행 빈도가 낮은 항목이 먼저 축출되면서, 나중에 그 쿼리를 되짚어볼 단서 자체가 남지 않습니다.

대응은 두 갈래입니다. max를 적당히 늘리거나(정렬 비용 증가를 감수하고), 애초에 쿼리 변형 수를 줄이는 것입니다. 예컨대 길이가 제각각인 IN 목록은 PostgreSQL 18 이전까지 길이마다 별도 항목을 만들었는데, = ANY($1) 배열 바인딩으로 바꾸면 버전과 무관하게 하나의 항목으로 묶입니다.

아래 도식은 새 쿼리가 들어왔을 때 항목이 잡히고 축출되기까지의 흐름입니다.

운영 관점의 리셋 전략과 함정

단조 증가하는 누적 통계

뷰의 카운터는 마지막 리셋 이후로 계속 쌓입니다. 그래서 "지금 어떤 쿼리가 부하를 일으키는가"를 보려면 두 시점의 스냅샷을 떠서 빼는 수밖에 없습니다. 한 번 조회한 절댓값만으로는 한 달 전 배치 작업과 방금 들어온 트래픽이 뒤섞여 보입니다.

모니터링 도구들이 일정 간격으로 뷰를 떠다가 차분을 계산하는 이유가 이것입니다. 직접 차분을 계산할 때는 그 사이에 eviction이나 리셋이 끼면 음수가 나올 수 있으니, stats_since(17 이상)나 pg_stat_statements_infodealloc/stats_reset을 함께 확인해야 합니다.

리셋 함수

pg_stat_statements_reset()으로 통계를 비웁니다. 인자 없이 호출하면 전체를 리셋하고, 특정 대상만 비울 수도 있습니다.

-- 전체 리셋
SELECT pg_stat_statements_reset();

-- 특정 user / db / queryid만 리셋 (0은 "전체" 의미)
SELECT pg_stat_statements_reset(0, 0, :queryid);

minmax_only 인자를 true로 주면 min/max_exec_time, min/max_plan_time만 비웁니다. 평균과 누적은 살려두고 최소/최대만 다시 측정하고 싶을 때 씁니다. 기본값은 superuser만 실행할 수 있고, 필요하면 GRANT로 권한을 넘깁니다.

리셋 전략에는 정답이 없습니다. 흔한 선택은 두 가지입니다.

  • 리셋하지 않고 누적 + 차분. 모니터링 도구에 맡기는 방식. 장기 추세를 잃지 않습니다.
  • 정기 리셋(예: 배포/점검 전후). 특정 구간만 깨끗하게 보고 싶을 때. 단, 리셋 순간 이전 데이터는 사라지니 추세 분석은 포기합니다.

자주 밟는 함정 정리

  • 타임아웃/abort된 쿼리는 집계되지 않습니다. 장애 원인 쿼리가 뷰에 없을 수 있습니다.
  • 평균만으로 판단하면 드물게 튀는 느린 실행을 놓칩니다. max_exec_time/stddev로 분포를 함께 의심합니다.
  • dealloc이 오르는 상태에서는 통계가 불완전합니다. 먼저 그것부터 해결합니다.
  • 계획 시간(*_plan_time)이 0이면 track_planning이 꺼진 것입니다.
  • I/O 시간(shared_blk_read_time 등)이 0이면 track_io_timing이 꺼진 것입니다.
  • queryid는 메이저 버전/아키텍처 간에 달라질 수 있어 영구 키로 부적합합니다.

정리

pg_stat_statements는 컬럼이 많아 보여도 DBA의 시선은 결국 몇 갈래로 좁혀져요. 부하의 원인은 total_exec_time, 느린 한 방은 mean_exec_time으로 찾고 둘 다 calls로 맥락을 잡으며, I/O가 의심되면 shared_blks_read와 temp 블록을, 쓰기가 의심되면 wal_bytes를 봐요. 데이터가 비어 보이거나 음수가 나오면 pg_stat_statements_infodeallocstats_reset을 먼저 확인하면 되고, 이 정도만 손에 익히면 대부분의 쿼리 튜닝은 이 뷰 하나에서 출발할 수 있어요.


참고한 출처:

PostgreSQL 파일 디스크립터

· 약 6분

튜닝 한 줄로 max_connections를 1만까지 올린 인스턴스가 어느 날 통째로 죽어요. 원인은 쿼리도 디스크도 아니고, DBA가 평소 신경 쓰지 않는 OS limit, file descriptor예요. 연결 풀러 없이 연결 수만 키운 구성은 file descriptor 고갈이라는 단 하나의 벽에 부딪혀 무너져요. 이 글에서는 그 메커니즘과 대응을 한 번에 정리해요.

PostgreSQL의 프로세스 모델과 file descriptor

PostgreSQL은 연결 하나마다 OS 프로세스 하나를 띄우는 process-per-connection 모델입니다. 클라이언트가 접속하면 postmaster가 backend 프로세스를 fork하고, 그 backend가 해당 세션의 모든 작업을 담당합니다. 스레드 풀로 연결을 다중화하는 일부 다른 데이터베이스와 결정적으로 다른 지점입니다.

여기서 핵심은 backend 프로세스 하나가 여러 개의 file descriptor를 동시에 들고 있다는 점입니다. file descriptor(이하 fd)는 프로세스가 열어둔 파일, 소켓, 파이프를 가리키는 OS 차원의 정수 핸들입니다. 하나의 backend는 다음을 모두 fd로 잡습니다.

  • 클라이언트와 연결된 소켓
  • 읽고 쓰는 테이블/인덱스 파일 (PostgreSQL 내부 VFD 계층이 관리)
  • WAL 세그먼트
  • 정렬/조인 과정에서 만들어지는 임시 파일

그래서 fd 소비량은 연결 수에 딱 비례하지 않고, 그 연결이 무슨 일을 하느냐에 따라 출렁입니다. 놀고 있는 idle backend는 fd를 10개에서 15개 정도만 쓰지만, 여러 테이블과 인덱스를 동시에 건드리는 write backend는 50개에서 200개 이상까지 올라갑니다. 연결 1만 개가 전부 활성 상태로 무거운 쓰기를 돌리는 순간, fd 소비량은 산술적 예상치를 한참 넘어섭니다.

고갈 메커니즘과 증상

fd에는 두 겹의 한계가 걸려 있고, 둘 중 무엇에 먼저 닿느냐에 따라 증상이 달라집니다.

첫 번째는 프로세스 단위 한계인 RLIMIT_NOFILE입니다. ulimit -n으로 조회/설정하며, 프로세스 하나가 열 수 있는 fd 개수를 제한합니다. PostgreSQL의 max_files_per_process는 이 OS limit 안에서 backend 하나가 잡을 fd 상한을 한 번 더 좁히는 PostgreSQL 자체 파라미터입니다.

두 번째는 시스템 전체 한계인 fs.file-max입니다. 커널이 머신 전체에서 열 수 있는 fd 총량을 제어하며, 이 값에 도달하면 어느 프로세스가 요청하든 모든 open() 호출이 실패합니다. PostgreSQL뿐 아니라 그 위에 떠 있는 모든 프로세스가 동시에 영향을 받습니다.

연결 풀러 없이 max_connections를 과하게 올린 구성에서는 두 번째 한계에 먼저 닿기 쉽습니다. 이론상 최악의 소비량은 다음 곱으로 표현됩니다.

worst-case fd ≈ max_connections × max_files_per_process

max_files_per_process 기본값이 1,000이므로, max_connections를 10,000으로 잡으면 산술적 상한이 천만 단위로 뜁니다. 실제로는 모든 backend가 동시에 상한까지 fd를 사용하지는 않으니 평소에는 멀쩡합니다. 문제는 배치 잡이 한꺼번에 쓰기를 일으킬 때입니다. LWLock:BufferContent, LWLock:WALInsert, LWLock:WALWrite 같은 lock 경합으로 락 보유 시간이 길어지면 동시에 오픈된 fd가 쌓이고, 어느 순간 시스템 한계를 갑자기 넘깁니다.

이때 PostgreSQL 로그는 한꺼번에 죽지 않고 단계적으로 무너집니다.

out of file descriptors: Too many open files in system; release and retry
...
server process (PID XXXXX) was terminated by signal 6
...
failed to send SSL negotiation response: Broken pipe

처음에는 평범한 로그 사이에 "Too many open files"(OS 레벨로는 EMFILE/ENFILE) 메시지가 하나둘 섞이다가, fd를 못 잡은 backend가 signal 6(abort)으로 죽고, postmaster가 crash recovery에 들어가면서 살아 있던 연결까지 SSL 끊김으로 떨어집니다. 애플리케이션 쪽에서는 "Unable to create new connection" 같은 커넥션 풀 예외로 나타납니다. 즉 fd 고갈은 느린 성능 저하가 아니라 인스턴스 전체가 한 번에 내려앉는 장애로 드러납니다.

공식 문서도 같은 맥락을 짚습니다. max_files_per_process에 대해 "If you find yourself seeing 'Too many open files' failures, try reducing this setting"이라고 안내하고, kernel resource 항목에서는 시스템 전역 한계를 fs.file-max로 조정하라고 명시합니다.

ulimit, max_files_per_process, 연결 풀러로 대응하기

대응은 세 층위로 나뉩니다. 급한 불을 끄는 임시 조치와 구조를 바꾸는 근본 조치를 구분하는 것이 중요합니다.

대응무엇을 푸나성격부작용/한계
fs.file-max 상향시스템 전역 fd 총량 확대임시 (시간 벌기)근본 원인인 backend 수는 그대로
ulimit -n 상향프로세스당 fd 상한 확대임시/보완메모리 소비 증가, 한계만 미룸
max_files_per_process 조정backend 1개의 fd 상한 제어보완너무 낮추면 VFD 캐시 회전 잦아져 성능 저하, 재시작 필요
PgBouncer 등 연결 풀러backend 절대 수 감소근본풀러 운영/모드 이해 필요

1단계: 임시로 OS limit 넓히기

PgBouncer 도입 전까지 시간을 벌어야 한다면 시스템 전역 한계부터 올립니다.

# 현재 상태 확인
cat /proc/sys/fs/file-max # 시스템 최대치
cat /proc/sys/fs/file-nr # 현재 사용량: <할당> <유휴> <최대>

# 시스템 전역 한계 상향 (재부팅 후에도 유지)
sysctl -w fs.file-max=20000000
echo "fs.file-max = 20000000" >> /etc/sysctl.conf
sysctl -p

프로세스당 한계는 postgres 사용자에 대해 /etc/security/limits.conf(또는 systemd 유닛의 LimitNOFILE)에서 soft/hard를 함께 올립니다. soft 한계가 실제로 적용되는 값이고 hard 한계까지 사용자가 올릴 수 있으며, hard 한계 자체는 root만 바꿀 수 있습니다. 다만 이는 어디까지나 시간을 버는 조치입니다. backend 수가 그대로라면 한계를 올린 만큼 더 큰 폭으로 다시 터집니다.

2단계: max_files_per_process로 backend 소비 제한

OS 전역 한계를 못 건드리는 환경이라면, backend 하나가 잡는 fd를 PostgreSQL 쪽에서 좁힐 수 있습니다. 공식 문서가 안내하는 방식입니다.

# postgresql.conf — 재시작 필요
max_files_per_process = 1000 # 기본값. "Too many open files" 보이면 낮춰 본다

단, 이 값은 OS의 프로세스당 fd 한계를 넘을 수 없습니다. 그리고 너무 낮추면 backend가 파일을 자주 닫았다 여는 VFD 캐시 회전이 잦아져 성능이 떨어집니다. 어디까지나 OS 한계 조정과 짝을 이루는 보완책으로 봅니다.

3단계: 연결 풀러로 근본 대응

진짜 해법은 애플리케이션과 PostgreSQL 사이에 PgBouncer 같은 연결 풀러를 두는 것입니다. 풀러는 수천 개의 애플리케이션 연결을 실제 200~500개 backend로 다중화합니다. transaction 모드에서는 트랜잭션이 끝날 때마다 backend가 풀로 반환되므로, 1만 개 클라이언트가 붙어도 PostgreSQL이 실제로 띄우는 backend 수는 풀 크기로 묶입니다.

풀러를 앞에 세운 뒤에는 max_connections를 500~1,000 수준으로 되돌립니다. 그래야 backend가 무한정 쌓이는 구조 자체가 사라집니다. 한계를 넓히는 게 아니라, 한계에 도달할 일을 없애는 방향입니다.

DBA 체크리스트

장애가 터지기 전에 점검할 항목과, 터졌을 때 들여다볼 지점을 나눠 정리합니다.

평상시 점검:

  • SHOW max_connections; 값이 실제 동시 연결 수요 대비 과하게 크지 않은가
  • 애플리케이션과 PostgreSQL 사이에 PgBouncer 등 연결 풀러가 있는가
  • 풀러를 쓴다면 transaction 모드로 backend가 트랜잭션마다 반환되는가
  • fs.file-max와 postgres 사용자 ulimit -n이 워크로드 피크를 감당할 값인가
  • cat /proc/sys/fs/file-nr 첫 번째 값(할당된 fd)이 fs.file-max의 50~60%를 넘지 않는가

모니터링/알람:

  • file-nr 사용량이 fs.file-max의 일정 비율을 넘으면 알람이 울리는가
  • pg_stat_activity의 활성 연결 수가 배치 기준선(예: 1,000)을 넘으면 감지되는가
  • 배치 윈도우에는 watch -n 5 'cat /proc/sys/fs/file-nr'로 실시간 추적하는가

장애 발생 시 진단:

  • 로그에 "Too many open files in system"이 보이는가 — fd 고갈 확정
  • cat /proc/$(pgrep -o postgres)/limits | grep "open files"로 프로세스 한계 확인
  • pg_stat_activity를 state/wait_event별로 집계해 lock 경합 backend가 몰려 있는지 확인
SELECT count(*), state, wait_event_type, wait_event
FROM pg_stat_activity
GROUP BY state, wait_event_type, wait_event
ORDER BY count DESC;

정리하면, fs.file-maxulimit을 올리는 건 응급 처치이지 치료가 아니에요. fd 고갈의 뿌리는 backend 프로세스가 너무 많다는 데 있고, 그 수를 구조적으로 묶는 유일한 방법이 연결 풀러예요. 연결 풀러가 이번 주 계획에 없다면, 지금 넣어야 해요.

참고

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 구성과 아카이빙 흐름을 먼저 잡고 오는 편이 좋아요. 암호화 궁합은 그 위에 얹는 한 겹이에요.

참고

Neon 백엔드 플랫폼 확장

· 약 7분

짧게 먼저

2026-05-28, Neon(네온)이 "우리는 앱과 agent를 위한 boring backend를 만든다"는 글을 내고 같은 주 changelog로 세 가지 신규 서비스를 예고했어요. PostgreSQL 한 제품으로 출발한 회사가 자기 무기인 branch를 데이터베이스 밖으로 끌고 나가, 스토리지와 compute와 AI 라우팅까지 같은 모델로 묶기 시작했어요.

세 서비스는 오브젝트 스토리지(Object Storage), 서버리스 compute(Compute), AI Gateway입니다. 셋 다 아직 "coming soon"이지만 방향은 분명합니다. Neon은 더 이상 자기를 "서버리스 PostgreSQL"로만 규정하지 않습니다. PostgreSQL 30년 산업사 글에서 정리한 "클라우드 베어의 시대" 흐름이, 이번에는 PostgreSQL 회사 한 곳이 백엔드 플랫폼으로 몸집을 키우는 형태로 다시 나타났습니다.

예고된 세 가지 서비스

발표 내용을 사실 단위로 끊어 봅니다. 1차 출처는 Neon 공식 블로그(Bryan Clark, VP Product)와 changelog입니다.

서비스상태한 줄 정의핵심 성질
Database출시됨서버리스 PostgreSQLbranch/서버리스의 출발점
Auth출시됨내장 인증백엔드 기본 블록
Data API출시됨REST/HTTP 접근코드 없이 데이터 노출
Object Storagecoming soonDB와 함께 branch되는 S3 호환 스토리지DB/파일 상태를 branch마다 동기화
Computecoming soonDB 옆에 붙는 서버리스 compute인프라 관리 없이 함께 확장
AI Gatewaycoming soon모델 라우팅, 로깅, 비용 통제Databricks 인프라 위에 구동

세 신규 서비스를 묶는 한 문장은 Neon이 직접 말합니다. 모든 서비스가 "instant, branchable, serverless"라는 것입니다. branch가 DB만의 기능이 아니라 플랫폼 전체의 기본 동작이 된다는 선언입니다.

AI Gateway 쪽에는 숫자 하나가 붙습니다. Neon은 이 Gateway가 "Databricks에서 월 125조 토큰을 처리하는 같은 인프라 위에 올라간다"고 적었습니다. 2025년 5월 Databricks(데이터브릭스)가 Neon을 인수한 뒤, 모회사의 운영 규모를 그대로 끌어쓰는 자리입니다.

1초 만에 끝나는 branch의 원리

이 발표를 이해하려면 Neon의 branch가 어떻게 동작하는지부터 짚어야 합니다. 일반적인 PostgreSQL 호스팅에서 "테스트용 사본"을 만들려면 pg_dump로 받아 다른 인스턴스에 복원하거나, 스냅샷에서 새 볼륨을 띄웁니다. 데이터가 클수록 시간과 비용이 선형으로 늘어납니다.

Neon의 branch는 다릅니다. storage 계층에서 copy-on-write로 동작합니다. branch를 만드는 순간 데이터를 복사하지 않고, 부모 branch의 WAL 히스토리 특정 시점을 가리키는 메타데이터 포인터만 만듭니다. 페이지는 수정될 때 비로소 branch 쪽에 따로 기록됩니다. 그래서 branch 생성은 데이터 크기와 무관하게 O(1)이고, 1초 안에 끝납니다.

Neon은 이 branch가 하루에 수천만 개씩 생성된다고 밝혔습니다. 사람이 만드는 양이 아닙니다. CI에서 PR마다, agent가 작업마다 격리된 환경을 띄웠다 지우는 패턴이 깔려 있다는 뜻입니다. branch를 "만들고 쓰고 버리는" 일회성 자원으로 보는 시각이 이미 자리 잡았습니다.

branch가 DB 밖으로 나간다는 것

이번 발표가 겨냥한 지점이 여기입니다. branch가 데이터베이스 안에만 있으면 반쪽짜리입니다. 현실의 애플리케이션은 DB만으로 돌지 않습니다 — 업로드된 파일은 오브젝트 스토리지에 있고, 백그라운드 작업은 compute에서 돌며, AI 기능은 외부 모델을 호출합니다. DB만 branch되고 나머지가 production을 공유하면, 격리는 깨집니다.

예를 들어 보겠습니다. 결제 영수증 PDF를 S3에 올리는 기능을 고치는 중이라고 가정하겠습니다. DB는 branch로 격리했는데 스토리지는 production 버킷을 그대로 쓴다면, 테스트로 만든 가짜 영수증이 실제 버킷에 섞입니다. compute도 마찬가지입니다. branch DB를 바라봐야 할 워커가 production 큐를 집어 들면 격리가 무의미해집니다.

Neon의 답은 단순합니다. branch를 만들 때 DB뿐 아니라 스토리지/compute가 함께 갈라지게 합니다. 오브젝트 스토리지는 "DB와 함께 branch되어 모든 branch에서 데이터와 스토리지가 동기 상태를 유지"하고, compute는 "DB 옆에 배치되는 서버리스" 형태로 같이 따라옵니다.

같은 copy-on-write 사고를 백엔드 기본 블록 전체로 넓힌 것입니다. DB 한 줄만 격리하던 환경이, 이제 파일과 연산까지 통째로 격리되는 환경으로 넓어집니다.

직접 굴리는 조합과 갈리는 지점

운영자 시각에서 차이를 표로 정리합니다. 비교 대상은 "직접 굴리는 PostgreSQL + 별도 오브젝트 스토리지 + 별도 워커"의 전통 조합입니다.

항목전통 PG 호스팅 조합Neon 백엔드 플랫폼
DB 사본 생성pg_dump/스냅샷, 크기에 비례branch, 1초/O(1)
스토리지 격리버킷 수동 분리/복사DB와 함께 자동 branch
compute 격리별도 인스턴스 프로비저닝DB 옆 서버리스 자동
AI 모델 호출직접 연동/자체 비용 추적Gateway가 라우팅, 로깅, 비용 통제
환경 단위DB, 스토리지, compute 각각branch 하나로 묶음
통합 책임운영자가 봉합플랫폼이 봉합

전통 조합은 각 계층을 운영자가 직접 잇습니다. 그만큼 통제권은 크지만, 환경 하나를 새로 깔 때마다 손이 많이 갑니다. Neon은 그 봉합을 플랫폼이 가져가는 대신 계층 선택의 자유를 줄입니다. 어느 쪽이 맞는지는 워크로드가 정하고, 여기에는 분명한 lock-in 비용이 따릅니다.

편의를 얻는 만큼 묶이는 비용을 계산한다

플랫폼이 편의를 가져가면 그만큼 묶이는 비용이 생깁니다. 운영자 관점에서 짚을 지점을 추립니다.

  • lock-in의 폭이 넓어집니다. DB만 Neon에 둘 때와, 스토리지, compute, AI 라우팅까지 둘 때의 이탈 비용은 다릅니다. branch가 묶어 주는 편의가 클수록, 빠져나올 때 풀어야 할 매듭도 많아집니다. PostgreSQL 30년 글에서 인용한 Christophe Pettus(크리스토프 페투스)의 한 줄, "이미 쓰는 데이터 플랫폼이 선택을 대신했다"가 여기에 그대로 적용됩니다.
  • AI Gateway는 표준 PostgreSQL 영역 밖입니다. 모델 라우팅/비용 통제는 PostgreSQL 호환성과 무관한 독자 기능입니다. 이 자리는 pg_dump나 logical replication으로 옮겨지지 않습니다. 의존하기 전에 대체 경로를 먼저 확인해야 합니다.
  • 세 서비스 모두 아직 예고 단계라는 점도 무게를 둡니다. 운영 결정은 정식 출시, SLA, 요금이 공개된 다음에 내려도 늦지 않습니다. 발표 시점에 확정된 것은 방향이지 가용성이 아닙니다.
  • AI Gateway가 모회사 인프라 위에 올라간다는 점은 규모의 강점이자 결합의 신호입니다. Neon Serverless PostgreSQL과 Databricks Lakebase(레이크베이스)가 같은 엔진을 공유한다는 구조도 함께 봅니다.

산업사 흐름에서 본 위치

PostgreSQL 30년 글은 2025년을 "클라우드 베어의 시대"로 불렀습니다. Databricks가 Neon을, Snowflake(스노우플레이크)가 Crunchy Data(크런치 데이터)를 가져간 분기입니다. 그 글의 진단은 "AI agent를 위한 PostgreSQL"이었습니다. Neon의 branch 모델이 agent가 매 작업마다 격리된 DB를 띄우기에 맞는다는 이유였습니다.

이번 발표는 그 진단의 다음 장입니다. Neon은 "agent를 위한 PostgreSQL"에서 "agent를 위한 백엔드 전체"로 범위를 넓혔습니다. 발표 글의 표현을 빌리면 "agent-native cloud는 마법보다 boring한 기본기 — 신원, 권한, 로그, 롤백, 비용 통제 — 가 먼저 필요하다". DB 회사가 백엔드 플랫폼을 지향할 때 내거는 명분이 바로 이 자리입니다.

이 흐름은 Neon만의 것이 아닙니다. Supabase(수파베이스)는 처음부터 PostgreSQL + 인증 + 스토리지 + 함수를 한 묶음으로 팔아 온 회사입니다. Neon이 늦게 같은 무대로 올라왔지만 무기는 다릅니다. Neon은 자기 고유의 branch 모델을 백엔드 전 계층에 바르는 방식으로 차별화를 시도합니다. PostgreSQL을 코어로 둔 회사들이 "DB 벤더"에서 "백엔드 플랫폼"으로 수렴하는 큰 그림은 같습니다.

정리

발표 전의 Neon은 자기를 서버리스 PostgreSQL로 규정했고 branch는 DB 안에만 있었습니다. 이번 발표 이후 그 회사는 백엔드 플랫폼을 지향하고, branch 범위는 스토리지와 compute까지 넓어지며, AI는 pgvector 같은 DB 내부 기능이 아니라 Gateway로 분리/외부화됩니다. 운영자 관점에서 보면 DB 한 계층에 대한 의존이 백엔드 여러 계층에 대한 의존으로 커집니다.

정리하면 Neon은 branch를 데이터베이스 밖으로 끌고 나갔습니다. 스토리지와 compute가 DB와 함께 갈라지면 환경 하나를 통째로 격리하는 일이 명령 한 줄로 끝나는데, 이건 운영자에게 편의이자 결합입니다. 봉합 비용을 플랫폼에 넘기는 대신 계층 선택의 자유를 일부 내줍니다.

다만 세 서비스가 아직 예고 단계라는 점은 잊지 말아야 해요. 방향은 분명하지만 가용성, 요금, SLA는 아직이에요.

참고

PG19 Beta 핵심 변화 4가지

· 약 11분

Big 4를 한눈에

Christophe Pettus가 The Build에서 정리한 PostgreSQL 19 Beta Big 4에는 공통점이 있어요. 넷 다 피처 노트로 끝나지 않고 운영 시나리오를 바꾼다는 점이에요. 신규 syntax 한 줄에 그치지 않고, DBA의 메모리 계산식, 장애 시나리오, 튜닝 기본값을 다시 그리게 만들어요.

업데이트 (2026-06-04): PostgreSQL 19 Beta 1이 공식 릴리스됐습니다. 이 글이 예고한 Big 4는 모두 Beta 1에 그대로 담겼습니다: 64bit MultiXact members(Make multixid members 64-bit), 병렬 autovacuum worker(autovacuum_max_parallel_workers), UPDATE/DELETE FOR PORTION OF, JIT 기본 비활성화입니다. 정식 출시는 9월~10월 예정이며, 그사이 release candidate가 한 차례 이상 나옵니다.

PostgreSQL 19는 9월 정식 출시 예정입니다. 이번 글은 Pettus의 Big 4 큐레이션을 출발점으로 삼아, 거기에 DBA 점검 항목, 메모리 계산식, SQL 예시, 업그레이드 체크리스트를 보탠 글입니다. 네 가지 선정은 Pettus의 시각이고, 운영 점검, 메커니즘 해설, 업그레이드 절차는 기존 PG19 시리즈 5편이 다루지 않은 부분을 채우는 보완/확장입니다.

왜 이 Big 4인가

PostgreSQL 19의 변경 목록은 CommitFest 5회분의 수백 건입니다. 그중 DBA가 실제로 체감하는 변화는 보통 둘 중 하나입니다.

  • 장애 회피: 지금까지 운영 매뉴얼에 "이거 터지면 끝"으로 적혀 있던 시나리오가 사라집니다.
  • 튜닝 기본값 변경: 업그레이드 직후 워크로드 성격에 따라 plan 시간, 메모리, 비상 상황이 달라집니다.

Pettus가 꼽은 Big 4는 정확히 그 두 축에 들어갑니다. 새 syntax나 새 알고리즘이라기보다, 기존 운영 매뉴얼을 손보게 만드는 변경들입니다.

변경영향
64bit MultiXact members장애 회피"긴급 vacuum"이라는 운영 시나리오가 사라집니다
병렬 autovacuum 인덱스 worker튜닝 기본값 변경최악 메모리 사용량 식이 달라집니다
UPDATE/DELETE FOR PORTION OF신규 운영 영역row trigger/cascading FK 동작에 새 사각지대
jit = off (기본)튜닝 기본값 변경OLAP는 명시 활성화하지 않으면 회귀합니다

1. 64bit MultiXact members가 없앤 긴급 vacuum 시나리오

무엇이 바뀌었나

MultiXact 멤버 카운터가 32bit에서 64bit로 확장됐습니다. 4 billion(약 40억) 멤버 공간 고갈 시나리오가 사실상 사라집니다.

DBA가 왜 체감하나

PostgreSQL에는 DBA 사이에서 "이게 터지면 끝"으로 통하는 시나리오가 몇 개 있습니다. MultiXact wraparound는 거기 한참 머물러 있었습니다.

SELECT ... FOR SHARE, foreign-key check 같은 공유 row lock이 같은 행에 여러 트랜잭션에서 동시에 걸리면, PostgreSQL은 그 잠금 정보를 묶어서 MultiXact라는 별도 구조에 기록합니다. 각 MultiXact는 멤버 슬롯을 소비합니다. 그 멤버 카운터의 자료형이 PostgreSQL 19에서 처음으로 확장됐습니다.

구분타입최대값
기존 (PG 18 이하)uint32 (32비트)약 42억 9천만
변경 (PG 19~)uint64 (64비트)약 1844경

42억은 운영 부하가 큰 워크로드(공유 lock + FK check 누적)에서 실제로 도달할 수 있는 수치입니다. 1844경은 사실상 도달이 불가능한 영역으로 넘어갑니다.

주의: XID/mxid wraparound는 그대로다

DBA가 흔히 "wraparound"라고 묶어 부르는 경우는 사실 셋입니다. 이번 변경은 그중 하나에 한정됩니다.

wraparound 종류PG 19에서 변경운영 영향
MultiXact members 카운터uint32uint64사실상 해결
MultiXact ID (mxid)변경 없음 (32bit)autovacuum 의존, anti-wraparound vacuum 그대로
Transaction ID (xid)변경 없음 (32bit)autovacuum의 freeze 책임 그대로

PostgreSQL의 오래된 숙제인 XID wraparound와 mxid wraparound는 PostgreSQL 19에서도 살아 있습니다. autovacuum이 주기적으로 freeze를 수행해야 하는 이유가 정확히 이것입니다. 이번 글이 다루는 "해결된 wraparound"는 MultiXact members 카운터 하나뿐임을 분명히 해 둡니다.

64bit XID 확장은 2018년부터 PostgreSQL hackers 메일링 리스트에서 논의돼 왔습니다. Postgres Pro가 PostgreSQL 15 시기에 실험적 패치 시리즈로 동작 확인까지 갔지만, tuple 헤더 크기 증가, 모든 index format 재설계, WAL format 변경 같은 광범위한 ripple effect 때문에 main 브랜치 commit으로 이어지지 않았습니다. PostgreSQL 19에서도 같은 상태입니다. PostgreSQL의 가장 오래된 숙제 중 하나가 한 라운드 더 미뤄졌고, 그 사이 DBA는 autovacuum freeze 튜닝과 pg_visibility/pg_class.relfrozenxid 모니터링을 손에서 놓을 수 없습니다.

운영 영향은 이렇게 정리됩니다.

항목PG 18까지PG 19 Beta
MultiXact members 고갈 시새 트랜잭션 거부 + offline emergency VACUUM사실상 도달 불가
XID/mxid wraparoundautovacuum freeze로 방어그대로이며 모니터링을 유지합니다
운영 매뉴얼 항목MultiXact members 항목은 "이거 터지면 끝" 목록의 한 줄members 항목만 삭제 후보. XID/mxid는 유지

42억 한계에 도달하면 DBA가 마주하는 그림은 단순했습니다. 새 트랜잭션이 거부되고, 복구 경로는 offline emergency VACUUM 하나. Pettus의 한 줄이 이를 짚습니다.

"When exhausted, the system would refuse new transactions, and the only recovery path was an emergency VACUUM."

이론적으로 wraparound 수학은 2^64에서도 여전히 존재합니다. 다만 같은 워크로드를 우주의 나이만큼 굴려도 도달이 어렵습니다. 32bit 공간 도달 사례는 운영 사고 보고서들에 종종 등장했지만, 64bit는 실무 카탈로그에서 제외할 수 있습니다.

DBA가 할 일

  • 운영 매뉴얼/런북에서 "MultiXact wraparound" 비상 절차 항목을 "PG 19부터는 도달 불가"로 갱신
  • 단, PostgreSQL 18 이하 운영 중인 클러스터는 그대로 이 시나리오가 살아 있으니 모니터링 대시보드를 유지

Beta 1에는 이 부분을 보강하는 변경도 함께 들어왔습니다. multixact 활동을 보여 주는 pg_get_multixact_stats() 함수가 추가됐고, xid/multixact wraparound 경고 임계값이 기존 4천만에서 1억 건 남았을 때로 올라갔습니다(클라이언트와 서버 로그 양쪽에 경고). 여전히 살아 있는 xid/mxid wraparound를 그만큼 더 일찍 알아챌 수 있습니다.

2. 병렬 autovacuum 인덱스 worker와 메모리 계산식

무엇이 바뀌었나

새 GUC autovacuum_max_parallel_workers가 추가됩니다. autovacuum이 단일 테이블의 인덱스 정리를 여러 worker로 병렬 처리합니다. PostgreSQL 17에서 도입된 manual VACUUM의 병렬 인덱스 정리가 autovacuum 경로까지 확장됐습니다.

DBA가 왜 체감하나

인덱스가 많이 붙은 wide table을 운영해 본 사람은 압니다. autovacuum이 돌면 heap 정리는 빠른데 인덱스 정리 단계에서 한참 멈춰 있습니다. 단일 worker가 인덱스 N개를 순차로 도는 구조였기 때문입니다.

PostgreSQL 19에서는 같은 단계에 worker가 동시에 들어갑니다. wide-and-many-indexes 테이블의 autovacuum 시간이 줄어들고, vacuum 누적 부담이 풀립니다.

-- 새 GUC (값은 예시)
ALTER SYSTEM SET autovacuum_max_parallel_workers = 4;
SELECT pg_reload_conf();

주의: 최악 메모리 식이 달라진다

같은 변경이 운영 부담을 새로 만드는 지점도 있습니다. 각 병렬 worker는 자기 몫의 maintenance_work_mem을 따로 잡습니다.

항목PG 18까지PG 19 Beta
autovacuum 최악 메모리autovacuum_max_workers × maintenance_work_memautovacuum_max_workers × autovacuum_max_parallel_workers × maintenance_work_mem

autovacuum_max_workers=3, autovacuum_max_parallel_workers=4, maintenance_work_mem=1GB인 환경에서 최악 메모리 사용량은 3 × 4 × 1GB = 12GB가 됩니다. PostgreSQL 18까지의 3GB와 4배 차입니다.

DBA는 PostgreSQL 19 업그레이드 전에 세 가지를 확인합니다.

  1. maintenance_work_mem 현재 값
  2. autovacuum_max_workers 현재 값
  3. 위 두 곱에 새 GUC 곱을 더한 값이 시스템 메모리에 맞는가

maintenance_work_mem을 1GB 이상으로 키워 놓은 운영 환경(분석 워크로드/큰 인덱스 재정렬 빈도가 잦은 곳)은 특히 다시 계산해야 합니다.

"명백한 이득"이 보이는 경우는 한정적입니다. serial 인덱스 정리가 vacuum의 병목이던 wide table에서 가장 큰 폭으로 줄어듭니다.

DBA가 할 일

  • 업그레이드 전 메모리 식 재계산. RAM이 빠듯하면 autovacuum_max_parallel_workers를 기본보다 낮춰 시작
  • wide table/인덱스 다수 테이블에서 autovacuum 지속 시간 모니터링 (pg_stat_progress_vacuum)
  • 한꺼번에 너무 많은 worker가 깨어나 I/O 포화되지 않도록 autovacuum_vacuum_cost_limit 검토

3. UPDATE ... FOR PORTION OF, SQL:2011 시간 범위가 PostgreSQL로

무엇이 바뀌었나

시간 범위(period) 컬럼을 가진 테이블에서 부분 범위만 UPDATE 또는 DELETE할 수 있게 됐습니다. SQL:2011 표준 syntax입니다.

-- 가격 이력 테이블 (period 컬럼 사용 가정)
CREATE TABLE price_history (
product_id int,
price numeric,
valid_period daterange,
PERIOD FOR valid_period (valid_from, valid_to)
);

-- 2026-06-01 ~ 2026-06-15 구간만 가격 변경
UPDATE price_history
FOR PORTION OF valid_period
FROM DATE '2026-06-01' TO DATE '2026-06-15'
SET price = price * 0.9
WHERE product_id = 42;

이전에는 DBA가 직접 row를 자르고 새 row를 끼워 넣는 SQL을 손으로 썼습니다. PostgreSQL 19부터는 한 문장으로 끝납니다. 건드리지 않은 범위의 row는 자동으로 보존됩니다.

DBA가 왜 체감하나

가격 이력, 직원 직책 이력, 권한 이력, 보험료 이력처럼 시간 범위 컬럼을 두는 모델은 흔합니다. 매번 손으로 자르는 SQL을 짜는 대신 syntax 한 줄로 정리되는 경우가 늘어납니다.

다만 새 운영 사각지대도 함께 생깁니다.

주의: row trigger/cascading FK

Pettus가 직접 짚습니다.

"a FOR PORTION OF update can fire row triggers on rows that did not exist when the statement started."

(FOR PORTION OF UPDATE는 문이 시작될 때 존재하지 않던 row에 대해서도 row trigger를 발화시킬 수 있다.)

내부적으로 FOR PORTION OF는 원본 row를 잘라 새 row 두 개(또는 세 개)로 분리하고, 그중 하나에 UPDATE를 적용합니다. 그 결과 DELETE 트리거가 원본 row에, INSERT 트리거가 새 보존 row 둘에, UPDATE 트리거가 갱신된 부분 row에 각각 발화합니다.

cascading foreign-key 동작은 한 단계 더 복잡해집니다. parent 행의 시간 범위가 잘리면 child의 FK 동작이 어떻게 따라가는지 production에서 테스트하지 않고 올리면 사고 가능성이 큽니다. parent의 부분 UPDATE가 child를 DELETE해야 하는가, CASCADE해야 하는가, RESTRICT해야 하는가. 이런 운영 정책 결정이 SQL 한 줄 안에 묻혀 들어갑니다.

DBA가 할 일

  • FOR PORTION OF를 production에 올리기 전에 row trigger, FK, audit trigger 동작을 staging에서 전부 확인
  • 트리거가 row 단위로 카운트를 세는 코드(예: audit row 개수 검증)는 PostgreSQL 19에서 결과가 다를 수 있으니 재검토

4. jit = off 기본값, PostgreSQL 12 이후 처음의 방향 전환

무엇이 바뀌었나

Just-in-time compilation 기본값이 off로 바뀝니다. PostgreSQL 12에서 jit = on이 기본값으로 들어온 이후 처음 있는 방향 전환입니다.

DBA가 왜 체감하나

이 변경은 워크로드 성격에 따라 정반대 결과를 만듭니다.

워크로드PG 18까지PG 19 Beta
OLTP (짧은 쿼리 다수)JIT plan 오버헤드가 매 쿼리마다 누적plan 시간 단축, 응답성 개선
OLAP (긴 분석 쿼리)JIT 컴파일 후 실행 가속명시적으로 jit = on 안 켜면 회귀

Pettus는 OLAP 회귀의 크기를 한 줄로 묘사합니다.

"a six-minute report now takes nineteen."

(6분짜리 리포트가 19분 걸리게 된다.)

3배 회귀 사례를 예고하는 대목입니다. OLAP 클러스터를 PostgreSQL 19로 올리면서 jit = on을 명시 설정하지 않으면, 출시 직후 가장 먼저 받는 분기 보고서가 평소보다 한참 늦게 도착합니다.

DBA가 할 일

OLTP 클러스터는 그대로 두면 자연스럽게 plan 효율 개선합니다. 별도 설정 불필요. OLAP/분석 클러스터는 업그레이드 직후 ALTER SYSTEM SET jit = on; 실행합니다. 또는 분석 사용자의 ALTER ROLE ... SET jit = on;으로 user-level 지정. 혼합 워크로드는 pgBouncer 등의 connection pool에서 분석 트래픽 분리한 뒤 그쪽만 jit = on 적용

왜 방향이 바뀌었는가

PostgreSQL 12에서 JIT를 기본 활성화한 동기는 "분석 쿼리에서 측정 가능한 가속이 있다"였습니다. 하지만 운영 통계가 쌓이면서, OLTP가 절대 다수인 PostgreSQL 운영 현실에서 plan 시간 오버헤드 손실이 컴파일 가속 이득을 자주 초과한다는 점이 드러났습니다. 6년 만에 측정에 근거해 기본값을 되돌린 것입니다.

PostgreSQL 19 업그레이드 체크리스트 (이번 Big 4)

업그레이드 전 다음을 점검합니다.

점검 항목명령 / 확인
maintenance_work_mem 현재 값SHOW maintenance_work_mem;
autovacuum_max_workers 현재 값SHOW autovacuum_max_workers;
최악 메모리 사용량 재계산autovacuum_max_workers × autovacuum_max_parallel_workers × maintenance_work_mem
OLAP/혼합 워크로드 식별분석 ETL/BI 도구 사용 여부
시간 범위 컬럼 사용 테이블 식별\d+ 로 PERIOD 컬럼 점검
MultiXact 모니터링 운영 매뉴얼"PG 19부터 도달 불가" 주석

업그레이드 직후에는 다음을 즉시 확인합니다.

-- 1. autovacuum 동작 확인
SELECT * FROM pg_stat_progress_vacuum;

-- 2. JIT 설정 확인 (OLAP면 명시 on)
SHOW jit;

-- 3. 새 GUC 확인
SHOW autovacuum_max_parallel_workers;

정리

앞의 표에서 정리했듯 64bit MultiXact members는 최악 wraparound 시나리오를 제거하지만 PG 18 이하 클러스터 모니터링은 유지해야 하고, 병렬 autovacuum 인덱스 worker는 wide table autovacuum 시간을 단축하지만 최악 메모리 사용량 식이 달라집니다. UPDATE/DELETE FOR PORTION OF는 시간 범위 SQL을 한 줄로 정리하는 대신 row trigger/cascading FK 동작을 재검증해야 하고, 기본 jit = off는 OLTP plan 시간을 단축하지만 OLAP는 명시 활성화 안 하면 회귀합니다.

PostgreSQL 19는 화려한 신기능보다 운영 매뉴얼을 다시 쓰게 만드는 쪽에 가까운 릴리스예요. DBA 입장에서 이번 Big 4는 9월 정식 출시 전에 staging에서 한 번 돌려 보고, 메모리 식, 튜닝 기본값, 운영 매뉴얼 세 가지를 같이 갱신해야 해요.

기존 PostgreSQL 19 새 기능 총정리PostgreSQL 19 시리즈 4편이 "어떤 기능이 들어오는가"를 봤다면, 이번 글은 "어떤 운영이 달라지는가"를 봐요. 두 글을 같이 두면 PostgreSQL 19를 올리기 전 점검할 항목이 한곳에 모여요.

참고

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는 마이그레이션 압력 없이 한 분기 정도 더 호흡할 수 있어요.

참고

PostgreSQL 30년사

· 약 16분

들어가며

2025년 6월 2일, Snowflake(스노우플레이크)가 Crunchy Data(크런치 데이터)를 약 2억 5천만 달러에 인수했고, 2025년 5월에는 Databricks(데이터브릭스)가 Neon(네온)을 10억 달러 안팎으로 가져갔어요. Microsoft(마이크로소프트)는 자체 Postgres 변형 HorizonDB를 들고나왔어요. 2026년 5월 현재, "PostgreSQL을 쓴다"는 말은 점점 모호해졌어요. Snowflake Postgres인가, Lakebase인가, HorizonDB인가, 아니면 그냥 PostgreSQL인가요.

이 글은 30년에 걸친 PostgreSQL 회사들의 인수와 이별, 그리고 그 사이를 혼자 걸어온 컨설턴트/메인테이너들의 이야기입니다. 사실에 기반해 풀고, 마지막에는 다음 5년을 가늠해 보겠습니다.

한 장으로 보는 흐름

본문으로 들어가기 전, 큰 패턴을 표 하나로 깔아둡니다.

시기흐름대표 사건
1986~1999학교 프로젝트 → 오픈소스UC Berkeley POSTGRES, 1996 PostgreSQL
2002~2009PG 전용 회사 출현2ndQuadrant, EDB, PGX
2010~20151차 클라우드 인수Heroku→Salesforce, EMC→Greenplum
2016~20192차 인수 + 새 시장Microsoft→Citus, OpenSCG→AWS, Supabase/Aiven
2020~2023PG 회사들의 통합EDB→2ndQuadrant, Bain Capital→EDB
2024상실Simon Riggs 사망, xz backdoor, Greenplum closed-source
2025클라우드 베어 시대Databricks→Neon, Snowflake→Crunchy, HorizonDB
2026자금 단절의 그림자pgBackRest archive, 다중 스폰서 모델

표를 위에서 아래로 따라 읽으면 한 가지 패턴이 보입니다. PG 회사가 클라우드 회사에 흡수되는 주기가 점점 짧아집니다. Salesforce→Heroku에서 Microsoft→Citus까지 9년, Microsoft→Citus에서 Databricks→Neon까지 6년입니다.

이제 각 시기를 풀어씁니다.

Act 1. 1996~2010

학교 프로젝트가 살아남은 시기입니다.

PostgreSQL의 출발은 UC Berkeley(버클리)의 POSTGRES (1986)입니다. Michael Stonebraker(마이클 스톤브레이커)가 INGRES의 후속으로 시작한 프로젝트가 1995년 SQL 인터페이스를 도입하며 PostgreSQL이라는 이름을 얻었고, 1996년 첫 정식 릴리스가 나왔습니다. 이 시기 합류한 사람들이 이후 30년의 형태를 만들었습니다.

Tom Lane(톰 레인)은 1996년 무렵부터 활동했습니다 — PostgreSQL 역사에서 가장 많은 commit을 한 사람입니다. 17년간 Red Hat(레드햇)에서 일하다 Salesforce(세일즈포스)를 거쳐 2015년 Crunchy Data로 옮겼습니다. Crunchy는 그에게 PostgreSQL에 100% 시간을 쏟을 자리를 마련해 줬습니다.

Bruce Momjian(브루스 모미얀)은 PostgreSQL 거버넌스의 대변자입니다. 2006년 EDB(EnterpriseDB, 엔터프라이즈DB)에 합류해 지금까지 같은 자리에 있습니다. PostgreSQL 라이선스의 BSD-스타일 약속을 가장 자주 옹호하는 사람이기도 합니다.

1997년에는 Joshua Drake(조슈아 드레이크)가 미국 몬태나에 Command Prompt(커맨드 프롬프트)를 차렸습니다. 2026년 현재까지 살아남은 PostgreSQL 컨설팅 회사입니다.

회사 쪽 흐름은 두 갈래로 갈렸다:

EDB는 2004년 Andy Astor(앤디 애스터), Denis Lussier(데니스 루시에르), Paul T. Winn(폴 윈), Phillip Merrick(필립 메릭)가 설립했습니다. 처음부터 "엔터프라이즈용 PostgreSQL"을 표방했고 Oracle(오라클) 호환성에 무게를 뒀습니다.

2ndQuadrant(세컨드쿼드런트)는 2002년 Simon Riggs(사이먼 릭스)가 영국/이탈리아에 설립했습니다. 설립자가 PITR, Hot Standby, 동기화 replication을 만든 사람이라 회사 자체가 "코어 기능 공급자"였습니다.

2009년에는 Christophe Pettus(크리스토프 페투스)가 PGX(PostgreSQL Experts)를 차렸습니다. The Build(더 빌드) 블로그가 이 회사의 채널입니다.

이 시기 클라우드는 아직 변두리였습니다. 2010년 12월, Salesforce가 Heroku(헤로쿠)를 약 2억 1,200만 달러에 인수했습니다. Heroku는 그해 11월에 PostgreSQL을 도입했고, 다음 해 11월 "Heroku Postgres"를 분리 제품으로 내놨습니다. Ruby/Python 개발자가 PostgreSQL을 "기본"으로 받아들이기 시작한 순간이었습니다.

Act 2. 2011~2019

클라우드가 책을 다시 쓴 시기입니다.

이 시기 PostgreSQL 회사들은 두 가지 길을 갔습니다. 하나는 클라우드 벤더에 흡수되는 길이고, 다른 하나는 새로운 시장을 만드는 길이었습니다.

흡수된 쪽:

OpenSCG → AWS(2018년 4월경)는 Denis Lussier가 만든 마이그레이션 서비스 회사의 인수 사례입니다. 회사는 AWS의 Database Migration Service에 흡수됐습니다.

Citus Data(사이터스 데이터) → Microsoft(2019-01-24)는 Y Combinator(Y 컴비네이터) S11 출신 회사의 인수 사례입니다. 이 회사는 분산 PostgreSQL extension을 만들었습니다. Microsoft가 인수한 뒤 Azure Database for PostgreSQL Hyperscale (현 Cosmos DB for PostgreSQL)로 이름이 바뀌었으며, 금액은 공개되지 않았습니다.

EDB의 자본 회전도 이어졌습니다. 2014년 Peak Equity Partners(피크 에쿼티 파트너스), 2019년 Great Hill Partners(그레이트 힐 파트너스)가 차례로 EDB의 다수 지분을 가져갔습니다.

새로 만들어진 쪽:

Crunchy Data는 2012년 Bob Laurence/Paul Laurence(폴 로런스) 형제가 창업했으며, 규제 산업/연방 정부 시장에 무게를 뒀습니다. Timescale(타임스케일)은 2015년 PostgreSQL extension으로 시계열 워크로드를 잡았습니다. Aiven(아이븐)은 2016년 핀란드 출신 3인(Oskari Saarenmaa(오스카리 사렌마), Hannu Valtonen(한누 발토넨), Heikki Nousiainen(헤이키 노우시아이넨))이 만든 관리형 오픈소스 플랫폼입니다. 2022년 시리즈 D 2억 1,000만 달러까지 모았습니다. Supabase(수파베이스)는 2020년 Paul Copplestone(폴 코플스톤)/Ant Wilson(앤트 윌슨)이 설립했습니다. "Firebase(파이어베이스)의 오픈소스 대안"이라는 슬로건으로 시작했지만, 본질은 관리형 PostgreSQL + BaaS입니다.

이 시기 가장 묵직한 인물 이동은 Andres Freund(안드레스 프룬트)입니다. 그는 Microsoft Azure Postgres 팀으로 옮겨갔고, 2024년 3월 PostgreSQL을 Debian Sid에서 벤치마킹하다가 SSH 로그인이 500ms 늦은 것을 눈치챘습니다 — 그 흔적을 추적해 xz Utils backdoor를 발견했습니다. "역사상 가장 위험한 backdoor"라는 평가가 붙은 사건의 발견자가 PostgreSQL 커미터였다는 것은 우연이 아닙니다.

2014년에는 한국에서도 작은 움직임이 있었습니다. PostgreSQL Korea User Group이 EDB, 다우기술, 펜타시스템 협업으로 출범한 기록이 남아 있습니다.

Act 3. 2020~2024

통합과 상실의 시대입니다.

2020년 9월 30일, EDB가 2ndQuadrant 인수를 완료했습니다. 이로써 EDB는 "가장 큰 PostgreSQL 전용 회사"가 됐고, Simon Riggs는 EDB Fellow가 됐습니다. 한 시대가 다른 시대를 흡수한 순간이었습니다.

2021년에는 Neon이 설립됐습니다. 설립자는 Nikita Shamgunov(니키타 샴구노프)/Heikki Linnakangas(헤이키 린나캉가스)/Stas Kelvich(스타스 켈비치) 3인입니다. 서버리스 + 브랜칭 모델로 시작했고, 이 회사는 4년 뒤 Databricks의 손에 들어갔습니다.

2022년 6월, Bain Capital(베인 캐피털) Private Equity가 EDB의 다수 지분을 가져갔습니다. PostgreSQL 최대 후원사가 사모펀드의 자산이 된 셈입니다.

Simon Riggs는 2024년 3월 26일, 영국 Duxford 비행장에서 본인이 조종하던 Cirrus SR22-T 사고로 별세했습니다. PITR, Hot Standby, 동기화 replication을 만든 사람의 죽음을 PostgreSQL 커뮤니티는 길게 애도했습니다. 공식 부고는 postgresql.org에 남아 있습니다.

사흘 뒤인 3월 29일, Andres Freund가 xz Utils backdoor를 발견했습니다. 같은 주에 PostgreSQL은 한 사람을 잃었고, 또 한 사람의 발견은 리눅스 생태계 전체를 구했습니다.

Greenplum(그린플럼)의 운명도 이 시기에 결정됐습니다. 2010년 EMC가 인수했던 이 PostgreSQL 기반 MPP 데이터베이스는 Pivotal(피보탈)/VMware(VM웨어)/Broadcom(브로드컴)을 거쳤습니다. 2024년 5월, Broadcom이 Greenplum을 closed-source로 전환했습니다. 오픈소스 PostgreSQL 변형이 사유 제품이 된 첫 큰 사례입니다.

같은 시기 K8s 쪽에서는 CloudNativePG가 자라났습니다. EDB의 Gabriele Bartolini(가브리엘레 바르톨리니)가 이끄는 프로젝트로, 2025년 1월 CNCF Sandbox에 정식 진입했습니다. PostgreSQL이 CNCF 산하 데이터베이스가 된 첫 사례입니다.

Act 4. 2025~2026

클라우드 베어의 시대입니다.

2025년이 무겁습니다. 클라우드 베어 셋이 같은 분기에 PostgreSQL 회사를 다 가져갔습니다.

시점사건금액
2025-05-14Databricks → Neon약 10억 달러
2025-06-02Snowflake → Crunchy Data약 2억 5천만 달러
2025년 중반Microsoft → HorizonDB 발표 (자체 개발)

세 인수는 같은 방향을 가리킵니다. AI agent를 위한 PostgreSQL입니다. Neon은 서버리스 + 브랜칭 모델이라 agent가 매 작업마다 격리된 DB 인스턴스를 만들기에 적합합니다. Crunchy는 규제 산업 고객 기반과 안정적 코어 엔진을 가져왔습니다. HorizonDB는 wire 호환만 유지하고 스토리지는 Rust로 새로 짰습니다.

The Build 블로그의 Christophe Pettus는 이 셋을 한 줄로 정리했습니다.

"Pick the one whose adjacent data platform you already use, and do not pretend you have a choice you don't have."

선택은 이미 쓰고 있는 데이터 플랫폼이 정해 줬다는 뜻입니다. Snowflake 고객은 Snowflake Postgres를 쓰고, Databricks 고객은 Lakebase(레이크베이스)를 씁니다. 셋은 SQL과 기본 PostgreSQL 동작까지는 호환되지만, extension, logical replication, pg_basebackup, pgBackRest, Patroni는 통하지 않습니다.

Crunchy 인수는 빈말로 끝나지 않았습니다. Snowflake는 2026년 2월 24일 Snowflake Postgres를 정식 출시(GA)했습니다. Snowflake 콘솔에서 곧바로 Postgres 인스턴스를 만들고 관리할 수 있으며, AWS/Azure 일부 리전에서 먼저 풀렸습니다. Snowflake는 이를 "fork가 아니라" 기존 PostgreSQL 도구를 그대로 쓰는 lift-and-shift 호환 제품이라고 강조합니다. Crunchy의 엔진과 인력이 실제 상용 제품으로 녹아든 결과입니다.

같은 시기 Timescale은 2025년 6월 TigerData(타이거데이터)로 리브랜드했습니다. 시계열에서 벗어나 agent 데이터베이스를 표방합니다.

막간. 혼자 걸어온 사람들

회사 인수 흐름과 별개로, PostgreSQL 생태계에는 큰 회사 안에 들어가지 않고 30년 가까이 자기 일을 한 사람들이 있습니다.

Christophe Pettus는 2009년 PGX를 차렸습니다. The Build 블로그는 이 회사의 채널입니다. 2026년 5월 현재도 본인이 직접 CEO, 컨설턴트, 블로거 노릇을 합니다.

Markus Winand(마르쿠스 비난트)는 책 한 권(《SQL Performance Explained》), 웹사이트 둘(use-the-index-luke.com, modern-sql.com), 비엔나에서 진행하는 5일 기업 교육으로 일합니다. 이 셋이 그의 회사 전체입니다. "구루"라는 표현이 가장 어울리는 형태입니다.

Hironobu Suzuki(스즈키 히로노부)는 일본 출신으로, 현재 유럽에 거주합니다. 《The Internals of PostgreSQL》을 비롯해 PostgreSQL 책 4권 + MySQL(마이에스큐엘) 책 3권을 썼습니다. interdb.jp는 그의 평생 작업입니다.

Hubert Lubaczewski(후베르트 루바체프스키, 닉네임 depesz)는 explain.depesz.com을 13년째 혼자 돌립니다. PostgreSQL 버전별 "Waiting for…" 시리즈는 1차 자료입니다. 회사는 본인 이름을 그대로 쓴 DEPESZ SOFTWARE HUBERT LUBACZEWSKI (폴란드)입니다.

Joshua Drake는 1997년 Command Prompt를 차렸습니다. 26년 차 PostgreSQL 컨설팅 회사이며, United States PostgreSQL의 회장이기도 합니다.

그러나 2026년 4월, 이 흐름의 어두운 그림자가 드러났습니다. David Steele(데이비드 스틸)이 13년간 단독으로 유지한 pgBackRest의 archive를 선언했습니다. 이미 pgBackRest의 종료 글에서 한 편 정리한 사건입니다. Crunchy가 후원하다가 Snowflake 인수 이후 자금이 끊어졌고, 그는 13개월간 새 직장을 찾지 못했습니다.

며칠 뒤 Steele은 입장을 일부 바꿨습니다. 다중 스폰서 연합 펀딩으로 전환해 프로젝트를 이어 갈 가능성을 발표했습니다. 구체적 후원 기업명은 아직 공개되지 않았습니다. Christophe Pettus와 Gabriele Bartolini는 이 사건을 같은 문장으로 요약했습니다.

"Open source doesn't die. It gets unfunded."

이 문장은 오픈소스는 죽는 것이 아니라 자금이 끊길 뿐이라는 뜻입니다.

커미터들은 어디에 있는가

빅테크 흡수의 지도를 살펴봅니다.

2025년 기준 PostgreSQL 커미터 31명의 소속을 단순화해 정리하면 다음과 같습니다.

소속인원 (개략)대표 인물
EDB8~10Tom Lane(과거), Bruce Momjian, Robert Haas(로버트 하스)/Álvaro Herrera(알바로 에레라)/Andrew Dunstan(앤드루 던스턴)/Jacob Champion(제이콥 챔피언)/Masahiko Sawada(사와다 마사히코)
Microsoft5Andres Freund/David Rowley(데이비드 라울리)/Thomas Munro(토마스 먼로)/Melanie Plageman(멜라니 플레이지먼)/Daniel Gustafsson(다니엘 구스타프손)/Amit Langote(아미트 랑고테)
AWS2~3Peter Geoghegan(피터 게오게간)/Nathan Bossart(네이선 보사트)/Michael Paquier(미카엘 파키에)
Crunchy Data (→ Snowflake)2~3Tom Lane/Stephen Frost(스티븐 프로스트)/Joe Conway(조 콘웨이)
NTT/Fujitsu(후지쯔)/SRA OSS4Tatsuo Ishii(이시이 타츠오)/Fujii Masao(후지이 마사오)/Etsuro Fujita(후지타 에츠로)/Amit Kapila(아미트 카필라)
Supabase1Alexander Korotkov(알렉산더 코로트코프) (전 Postgres Professional(포스트그레스 프로페셔널))
독립/기타2~3Dean Rasheed(딘 라시드)/Jeff Davis(제프 데이비스)/Richard Guo(리처드 궈)

빅테크 흡수는 진행 중입니다 — Microsoft + AWS만 합쳐도 약 25%입니다. EDB가 약 30%이고, Crunchy는 이제 Snowflake 자회사입니다. 일본 NTT/Fujitsu 라인은 의외로 두텁습니다.

한국은 공식 커미터/코어 멤버 명단에서 확인되는 사람이 없습니다.

거버넌스

라이선스는 안전한지 살펴봅니다.

먼저 던질 질문이 있습니다. Redis(레디스)/MongoDB(몽고DB)는 라이선스를 일방적으로 바꿨습니다. PostgreSQL도 그렇게 할 수 있을까요.

답은 사실상 불가능합니다. 이유는 단순합니다. PostgreSQL의 코드 소유권이 30년 동안 수천 명의 기여자에게 분산돼 있습니다. 라이선스 변경에는 만장일치에 가까운 동의가 필요합니다. Redis/MongoDB는 단일 회사 소유여서 가능했습니다.

PostgreSQL의 BSD-style 라이선스는 명시적으로 "perpetually free and open source"를 약속합니다. 30년의 분산이 이 약속의 진짜 보증입니다.

위험은 다른 곳에 있습니다. 단일 메인테이너 도구의 자금 단절입니다. pgBackRest가 처음 보여줬고, 다음 사례가 어디서 나올지는 모릅니다.

향후 5년

2031년의 풍경을 그려 봅니다.

사실에서 추측으로 넘어갑니다. 추측이지만 근거를 함께 적습니다.

가능성 높음:

  1. PostgreSQL이 사실상 표준 RDBMS 지위를 굳힙니다. Stack Overflow(스택 오버플로우) 2025 조사에서 개발자 55.6%가 PostgreSQL을 쓴다고 답했습니다. AI workload (pgvector) + OLTP + Analytics를 한 엔진이 다 받는 모델은 경쟁자가 없습니다.

  2. "PostgreSQL"이라는 단어가 흐려집니다. 사용자는 "Postgres를 쓴다"고 말하지만 실제로는 Aurora, Lakebase, HorizonDB, Snowflake Postgres 중 하나를 쓰는 식이 됩니다. extension 호환성이 가장 먼저 깨집니다.

  3. AI agent가 PostgreSQL을 "skill"로 등록하는 패턴이 표준이 됩니다. Supabase의 ChatGPT 공식 앱, Microsoft의 MCP for PostgreSQL이 출발선입니다.

갈등 지점:

  1. 단일 메인테이너 도구의 줄도산. Barman은 EDB가 받아 안정적이지만, pgBackRest 사건은 다른 도구에도 일어날 수 있습니다. Cybertec(사이버텍)의 pg_timetable, depesz.com 같은 1인 운영 자원의 지속성을 묻는 시기가 옵니다.

  2. K8s 운영자(operator)의 표준 경쟁. CloudNativePG가 CNCF 산하 단일 표준으로 가려면 시간이 더 필요합니다. Crunchy PGO는 Snowflake 인수 이후 장기 전략이 불투명하고, Zalando(잘란도)/StackGres(스택그레스)는 각자 자리를 지키고 있습니다.

  3. PostgreSQL 코어팀의 빅테크 의존도. EDB, Microsoft, AWS, Snowflake가 커미터 절대다수를 고용하고 있습니다. 라이선스는 안전해도, 로드맵의 무게중심은 조용히 이동합니다.

작게 가능한 시나리오:

  1. OrioleDB 같은 새 storage engine이 코어에 들어갑니다. 현재 public beta입니다. Alexander Korotkov가 Supabase로 옮긴 뒤 Supabase가 후원합니다. 2028년 전후로 production 후보가 될 가능성이 있습니다.

  2. 벤더 중립 우산 조직이 생깁니다. Gabriele Bartolini와 ProOpenSource(프로오픈소스)가 제안한 모델입니다. Apache Software Foundation(아파치 소프트웨어 재단)/Codeberg e.V.(코드버그)처럼 PostgreSQL 도구의 거버넌스를 단일 회사에서 분리하는 흐름이며, 아직 제안 단계입니다.

닫으며

이 이야기에서 무엇이 남는지 생각해 봅니다.

PostgreSQL의 30년에는 두 줄이 동시에 흘러왔습니다. 한쪽에는 Heroku, Citus, OpenSCG, Crunchy, Neon, Timescale로 이어진 회사들의 인수와 흡수가 있고, 다른 쪽에는 Tom Lane, Bruce Momjian, Christophe Pettus, Markus Winand, David Steele처럼 코드와 책과 도구를 30년 가까이 자기 손으로 들고 있는 개인들이 있습니다.

2026년의 풍경은 회사 쪽이 훨씬 시끄럽지만, 무게는 결국 개인 쪽으로 다시 돌아오리라 봅니다. 클라우드 베어 셋이 같은 분기에 PostgreSQL 회사를 다 가져갔어도, Andres Freund가 SSH 로그인의 500ms 차이로 xz backdoor를 잡아낸 순간이 어느 회사의 분기 실적보다 더 오래 기억될 것입니다.

오픈소스는 죽지 않고 자금이 끊길 뿐이라는 말처럼, 다음 30년의 PostgreSQL은 결국 어떤 사람이 어디서 누구의 자금으로 일하느냐에 달려 있어요.

부록. 1986~2026 전체 연표

1980년대

  • 1986/UC Berkeley에서 POSTGRES 프로젝트 시작 (Michael Stonebraker)

1990년대

  • 1995/POSTGRES → PostgreSQL로 이름 변경. SQL 인터페이스 도입
  • 1996/PostgreSQL 6.0 첫 정식 릴리스. Tom Lane/Bruce Momjian 등 코어 합류
  • 1997/Joshua Drake, Command Prompt 설립 (미국 몬태나)

2000년대

  • 2002/Simon Riggs, 2ndQuadrant 설립 (영국/이탈리아)
  • 2004/EnterpriseDB (EDB) 설립
  • 2006/Bruce Momjian, EDB 합류
  • 2009/Christophe Pettus, PGX 설립

2010~2015

  • 2010/Citus Data 설립
  • 2010-07/EMC, Greenplum 인수
  • 2010-11/Heroku에 PostgreSQL 도입
  • 2010-12-08/Salesforce → Heroku 인수, 약 2억 1,200만 달러
  • 2011-11/Heroku Postgres 분리 제품 출시
  • 2012/Crunchy Data 설립 (Laurence 형제)
  • 2012/Greenplum, Pivotal로 재조직
  • 2014/Peak Equity Partners → EDB 다수 지분 인수
  • 2014/PostgreSQL Korea User Group 출범 (EDB, 다우기술, 펜타시스템)
  • 2015/Tom Lane, Crunchy Data 합류
  • 2015/Timescale 설립
  • 2015/Alexander Korotkov, Postgres Professional 공동 설립

2016~2019

  • 2016/Aiven 설립 (Saarenmaa, Valtonen, Nousiainen)
  • 2018-04경/AWS → OpenSCG 인수
  • 2019-01-24/Microsoft → Citus Data 인수
  • 2019/Great Hill Partners → EDB 다수 지분 인수

2020~2023

  • 2020/Supabase 설립 (Copplestone/Wilson)
  • 2020/VMware → Pivotal/Greenplum 인수
  • 2020-09-30/EDB → 2ndQuadrant 인수 완료
  • 2021/Neon 설립 (Shamgunov, Linnakangas, Kelvich)
  • 2022-05/Aiven 시리즈 D, 2억 1,000만 달러
  • 2022-06/Bain Capital → EDB 다수 지분 인수
  • 2023/Alexander Korotkov, Postgres Professional → Supabase
  • 2023-11/Broadcom → VMware 인수 (Greenplum 포함)

2024: 상실의 해

  • 2024-03-26/Simon Riggs 별세 (영국 Duxford, Cirrus SR22-T 사고)
  • 2024-03-29/Andres Freund, xz Utils backdoor 발견 (SSH 500ms 추적)
  • 2024-05/Broadcom, Greenplum closed-source 전환
  • 2024/Barman 유지보수, 2ndQuadrant → EDB 공식 이관 완료

2025: 클라우드 베어의 분기

  • 2025-01-21/CloudNativePG, CNCF Sandbox 진입
  • 2025-05-14/Databricks → Neon 인수, 약 10억 달러
  • 2025-06-02/Snowflake → Crunchy Data 인수, 약 2억 5천만 달러
  • 2025-06/Timescale → TigerData 리브랜드
  • 2025년 중반/Microsoft, HorizonDB 발표 (자체 개발)
  • 2025-10/Supabase 시리즈 E, 1억 달러, 프리머니 50억 달러 밸류에이션

2026: 균열의 신호

  • 2026-02-24/Snowflake Postgres 정식 출시(GA), Crunchy 엔진 기반, AWS/Azure 일부 리전
  • 2026-04-27/David Steele, pgBackRest archive 선언
  • 2026-04-30/Percona Community: "Open source doesn't die. It gets unfunded."
  • 2026-05 초/Steele, 다중 스폰서 연합 펀딩 모델 가능성 발표
  • 2026-05-12/The Build, "Picking the Lock-In You Want" 발표
  • 2026-05-13/PostgreSQL 2026년 5월 보안 업데이트 (CVE 5건, CVSS 8.8 × 3)

1차 출처

회사/인수:

커미터/인물:

컨설턴트/메인테이너:

클라우드 전략/미래: