Postgres에 엄청난 신기능이 출시됩니다

BBetter Stack
컴퓨터/소프트웨어AI/미래기술

스크립트

00:00:00모든 것에 Postgres를 쓰라고 하던 개발자들의 말이 훨씬 더 옳았다는 사실이 드러났습니다.
00:00:04그래프 쿼리에 대한 네이티브 지원을 포함하는 다가오는 Postgres 19 버전과 함께 말이죠.
00:00:10정말 멋진 기능인데요. 그래서 오늘 영상에서는 Postgres 19의 주요 기능들을 살펴보고
00:00:16특히 그래프 쿼리를 더 자세히 알아보려고 합니다. 왜냐하면 이것이 우리가 쿼리를 설계하고
00:00:21Postgres를 사용하는 방식을 근본적으로 바꿀 수 있다고 생각하기 때문입니다.
00:00:30자, 첫 번째 기능은 on conflict do select라는 기능입니다. 행이 존재하지 않을 때만 삽입하고 싶고
00:00:35어느 쪽이든 그 행을 결과로 반환받고 싶을 때, 보통은 두 개의 쿼리가 필요했습니다.
00:00:40즉 삽입(insert)과 조회(select)인데 이는 아주 흔한 워크플로입니다. 그래서 예시를 보면
00:00:45users 테이블의 email과 name에 값을 삽입한다고 말하고 해당 값을 전달한 다음
00:00:50마지막에 on conflict for email do nothing returning star를 적습니다. do nothing은 행이 이미 존재할 때
00:00:56아무것도 반환하지 않으므로 select를 뒤에 붙이게 되지만, 이 둘은 원자적(atomic)이지 않습니다. 19 버전에서는
00:01:03단 하나의 쿼리로 이를 수행할 수 있습니다. users에 email과 name을 넣고 on conflict email do select
00:01:11returning star라고 적으면 됩니다. 그리고 동일한 쿼리에서 수정하고 싶다면 insert into users를 하고
00:01:16다시 값을 넣은 뒤 on conflict for email do select for update returning id and name을 쓸 수 있습니다. 단일 구문이므로
00:01:23원자적으로 작동하여 매번 삽입하거나 조회하게 되며, 이는 매우 흔한 유스케이스로서
00:01:29정말 유용할 것입니다. 다음은 그래프입니다만, 이 내용이 흥미로우셨다면
00:01:34betterstack을 구독하고 최신 기술 동향을 확인해 보세요. 앞서 말씀드린 것처럼
00:01:39이것이 제 생각에는 가장 핵심적인 기능입니다. 쇼핑몰을 위한 일반적인 스키마가 있다고 가정해 봅시다.
00:01:44고객, 주문, 상품이 있고 이들을 연결하는 두 개의 조인 테이블이 있는데, 특정 고객이
00:01:50실제로 어떤 상품을 구매했는지 알고 싶다고 해봅시다. SQL에서는 5개 테이블 전부를 가로지르는 조인 체인이 되는데
00:01:56여기서는 그럭저럭 관리할만 하지만 더 복잡한 관계에서는 금방 지저분해집니다. 그런데 이제는
00:02:02이 모든 것을 그래프로 쿼리할 수 있어서, 복잡한 조인 구문 대신 새로운 그래프 구문을 사용할 수 있습니다. 그리고
00:02:08특히 복잡한 조인에서 엄청난 이점을 보게 될 것입니다. 자, 데이터베이스 뷰어 안에 들어와 있습니다.
00:02:14상품, 주문, 이벤트 같은 모든 테이블이 있고 고객도 있으며
00:02:20이 모든 데이터를 연결하는 피벗 테이블도 있습니다. 주문 항목과 고객 주문 테이블이 있는데
00:02:25이제 이 모든 테이블을 대상으로 쿼리를 실행해 보겠습니다. 예를 들어서
00:02:30앨리스라는 유저가 있다고 하고, 앨리스가 주문한 모든 것을 알아내고 싶다고 해봅시다. 이를 위해서는
00:02:35그 모든 테이블을 연결하기 위해 여러 개의 서로 다른 조인 쿼리를 거쳐야 합니다. 그래서 4개의 개별 조인 문이
00:02:41포함된 이 쿼리를 실행하게 되는데, 작성하기에 엄청나게 어렵지는 않지만
00:02:46매우 지저분합니다. 하지만 이를 실행해보면 앨리스가 주문한 모든 것, 즉 기계식 키보드와 인체공학적 마우스를
00:02:51볼 수 있습니다. 하지만 이제 그래프 구문을 사용하면 이를 대폭 단순화할 수 있습니다.
00:02:57이 모든 것을 새로운 그래프 구문으로 교체하고 다시 실행하면
00:03:03동일한 결과가 나오는 것을 볼 수 있으며, 이 구조를 나열해 보면 가독성이 훨씬 좋아집니다.
00:03:07고객에서 고객 주문으로, 주문으로, 주문 항목으로, 상품으로 이어지는 것을 볼 수 있습니다. 따라서
00:03:13이 단순한 흐름을 따라가기만 하면 전체 그래프를 통과할 수 있으며, 제 생각에는 훨씬 더 읽기 쉽습니다.
00:03:19여러 열을 선택하고 싶을 때도 그렇게 할 수 있습니다. 상단에는 동일한
00:03:23그래프 쿼리가 있고, 하단에 열을 정의한 다음 표시하고 싶은 모든 열을 선택하면
00:03:27실행 결과가 하단에 나타납니다. 물론 애초에 그래프를 생성하지 않았다면 이 중 아무것도 작동하지 않으므로
00:03:32그 그래프를 생성하기 위해 사용한 쿼리는 여기에 있습니다. create property graph라고 말하고
00:03:37이름을 my shop으로 지정한 다음, 정점(vertex) 테이블을 개괄합니다. 고객, 주문, 상품이 될 것이며
00:03:42이것들이 실제로 데이터를 담고 있는 것들입니다. 그리고 간선(edge) 테이블이 있는데
00:03:47이는 실제로 연결을 만들어주는 것들, 즉 우리의 경우 피벗 테이블인
00:03:52고객 주문과 주문 항목이 됩니다. 이에 대한 구문은 매우 간단해서, 고객 주문의 소스는 고객이고
00:03:57목적지는 주문이며, 주문 항목의 소스는 주문이고 목적지는 상품이라고 말합니다.
00:04:02이것이 설정되면, 포스트그레스는 그래프 쿼리를 실행할 때마다 해당 관계가 어떻게 정의되었는지 인식하게 됩니다.
00:04:08이것이 작동하려면 그래프를 생성해야 하지만, 그렇다고 새로운 테이블 등을 만드는 것은 아닙니다.
00:04:14이미 가지고 있는 5개의 테이블을 가리키기만 하면 됩니다. 데이터를 실제로 담고 있는 3개는 정점이 되고
00:04:192개의 조인 테이블은 간선이 됩니다. 뷰와 매우 유사하게 작동하므로 이전 스키마는
00:04:23완전히 변경되지 않은 채 유지되고 그 위에 이 추가 기능이 얹어지는 것입니다. 따라서 여기서는
00:04:29create property graph를 선언하고 my shop이라고 부른 다음
00:04:35그 관계가 실제로 어떻게 작동하는지 기술하기 시작합니다. 바로 여기서 그래프를 위한 모든 작업을 수행하며
00:04:40이는 각 조인 구문에 비해 쿼리를 훨씬 더 가볍게 만들어 줄 수 있음을 의미합니다. 그렇다면 이것이 neo4j 대체재일까요?
00:04:45그래프 스토리지와 트래버설 성능 때문에 그래프 데이터베이스가 필요하다면, 아닙니다. 전용 그래프 데이터베이스가
00:04:52여전히 더 나은 선택일 것입니다. 하지만 SQL에서 10개의 테이블 조인을 작성하는 것이 고통스럽고 지저분해서
00:04:58이 기능을 원하신다면 확실히 큰 도움이 될 것이며
00:05:03비교했을 때 훨씬 더 만족스러울 것입니다. 세 번째 신기능은 repack인데
00:05:09디스크 공간을 다시 확보하는 것에 관한 기능입니다. 포스트그레스토어는
00:05:15절대로 행을 제자리에서(in-place) 업데이트하지 않고 새 버전을 쓴 뒤 이전 버전을 남겨두며, vacuum은
00:05:21그 죽은 공간을 재사용 가능하다고 표시만 하기 때문에 디스크 사용량이 실제로 줄어들지는 않습니다. repack은 낭비되는 공간 없이
00:05:27전체 테이블을 새로운 파일로 다시 작성하며, 그것이 바로 운영체제에 공간을 다시 돌려주는 방식입니다.
00:05:33실제로 vacuum full을 통해 이미 이 작업을 수행할 수 있었지만, 이는 전체 재작성 동안 테이블을 잠그므로
00:05:38대용량 데이터에는 절대 실행할 수 없었습니다. 이것이 바로 사람들이 pg_repack 같은 확장 프로그램을
00:05:42설치했던 이유입니다. 하지만 이제는 포스트그레스에 직접 내장되어 제공됩니다. 여기에 concurrently 키워드를 사용하면
00:05:49repack이 작동하는 동안에도 테이블을 읽고 쓸 수 있게 유지해 줍니다. 다만 한 가지 주의할 점은
00:05:54테이블의 두 번째 복사본과 그 모든 인덱스를 위한 충분한 여유 디스크 공간이 필요하다는 것입니다. 따라서 공간을 더 확보하려면
00:06:00여유 공간이 필요하므로, 이것이 pg_repack을 완벽히 대체하는 것은 아니지만 일반 테이블의 경우
00:06:06확장 프로그램 없이도 역할을 해냅니다. 자, 이제 19 버전의 남은 기능들에 대해 빠르게 짚어보겠습니다.
00:06:11첫 번째는 쿼리 힌트입니다. 포스트그레스는 쿼리를 실제로 어떻게 실행할지 스스로 결정하며
00:06:17시간이 지나면서 마음이 바뀔 수 있습니다. 따라서 1년 동안 잘 작동하던 쿼리가 갑자기 느려지고
00:06:22코드에는 아무것도 변경되지 않았을 때, pg_plan_advice라는 새 모듈을 사용하면 쿼리가 여전히 빠를 때의 플랜을 캡처하여
00:06:28고정함으로써 항상 그 상태를 유지할 수 있게 해줍니다. JIT는 이제 기본적으로 꺼집니다. 포스트그레스는 무거운 쿼리를
00:06:36머신 코드로 컴파일하지만, 플래너의 비용 견적을 바탕으로 언제 신경 쓸지 결정해 왔습니다. 릴리스 노트에 따르면
00:06:41그 비용 산정이 사실 신뢰할 수 없었기 때문에, 실제로 필요하지 않은 쿼리에서도 작동하고 있었다고 합니다.
00:06:46또한 이제 vacuum이 여러 워커를 통해 병렬로 인덱스를 정리할 수 있으므로 큰 테이블을 vacuum하는 데 소요되는 시간이 줄어듭니다.
00:06:52다만 이 기능은 직접 켜야 합니다. 열을 추가하여 select를 수행한 다음
00:06:58group by에도 동일한 열을 추가해야 할 때가 오면, 이 기능이 그 모든 것을 알아서 처리해 줍니다.
00:07:03그리고 copy 키워드로 이제 JSON으로 바로 내보낼 수 있게 되었습니다. 그동안 CSV로 덤프한 뒤
00:07:09나중에 변환해 왔다면 이제 그럴 필요가 없습니다. Postgres 19 베타 2가 7월에 출시되었고
00:07:15정식 릴리스는 9월에서 10월 사이로 예상되므로, 이전 버전을 사용 중이시다면 지금 베타 버전을 다운로드하여
00:07:21테스트해 볼 가치가 있습니다. 그리고 Postgres에 대해 더 자세히 알고 싶다면
00:07:25내구성 있는 워크플로를 Postgres 내부에 직접 구축해 주는 pg_durable 분석 내용을 확인해 보세요. 저는 betterstack의 워렌이었고
00:07:31시청해주셔서 감사하며 다음 영상에서 뵙겠습니다.

핵심 요약

Postgres 19는 on conflict do select, 네이티브 그래프 쿼리, 내장 repack 등 복잡한 워크플로를 단순화하는 강력한 신기능들을 도입한다.

하이라이트

  • Postgres 19 도입으로 삽입과 조회를 단일 구문으로 처리하는 on conflict do select 기능이 제공된다.

  • Postgres 19의 프로퍼티 그래프 쿼리 기능으로 복잡한 다중 테이블 조인을 단순한 그래프 구문으로 대체할 수 있다.

  • 내장된 repack 기능을 통해 디스크 공간을 운영체제에 반환하면서도 concurrently 키워드로 읽기 및 쓰기 작업을 유지할 수 있다.

  • 새로운 pg_plan_advice 모듈로 쿼리 실행 플랜을 캡처하여 고정할 수 있다.

  • Postgres 19 베타 2는 7월에 출시되었으며 정식 릴리스는 9월에서 10월 사이로 예정되어 있다.

타임라인

Postgres 19 원자적 삽입 및 조회 기능

  • 행이 없을 때 삽입하고 결과를 반환받는 기존 방식은 두 개의 쿼리가 필요했다.
  • Postgres 19의 on conflict do select 구문은 단일 쿼리로 이를 원자적으로 수행한다.
  • 동일한 쿼리 내에서 for update 등을 결합하여 수정 작업을 동시에 처리할 수 있다.

기존에는 행의 존재 여부에 따라 삽입과 조회를 분리하여 처리해야 하므로 원자성이 보장되지 않았다. Postgres 19에서는 on conflict do select returning star 구문을 통해 단 한 번의 쿼리로 이 과정을 안전하고 간결하게 처리할 수 있다.

프로퍼티 그래프 쿼리 기능

  • 여러 테이블을 거치는 복잡한 조인 체인을 새로운 그래프 구문으로 대체할 수 있다.
  • create property graph 명령어로 정점 테이블과 간선 테이블을 정의하여 관계를 구성한다.
  • 전용 그래프 데이터베이스를 완전히 대체하지는 않지만 SQL 조인의 복잡성을 크게 줄여준다.

쇼핑몰 스키마처럼 고객, 주문, 상품 등이 피벗 테이블로 연결된 구조에서 기존에는 수많은 조인 문을 작성해야 했다. Postgres 19의 그래프 쿼리는 기존 5개의 테이블 구조를 변경하지 않고 뷰처럼 상위에 얹어져 훨씬 직관적인 가독성과 단순한 흐름을 제공한다.

디스크 공간 확보와 repack 기능

  • 기존 vacuum은 죽은 공간을 재사용 가능하다고 표시만 할 뿐 디스크 사용량을 줄이지 못했다.
  • 내장된 repack 기능은 테이블을 새로운 파일로 다시 작성하여 운영체제에 공간을 돌려준다.
  • concurrently 키워드를 함께 사용하면 재작성 중에도 테이블의 읽기와 쓰기 작업이 유지된다.

포스트그레스토어의 특성상 행 업데이트 시 이전 버전을 남겨두기 때문에 디스크 공간 낭비가 발생한다. 기존 vacuum full은 테이블을 잠그는 문제가 있었으나, 내장된 repack은 충분한 여유 디스크 공간이 있다면 서비스 중단 없이 안전하게 공간을 확보할 수 있게 돕는다.

기타 주요 신기능 및 출시 일정

  • pg_plan_advice 모듈을 사용하여 빠른 실행 플랜을 캡처하고 고정할 수 있다.
  • JIT 컴파일은 신뢰할 수 없는 비용 산정 문제로 인해 기본적으로 비활성화된다.
  • Postgres 19 베타 2는 7월에 출시되었으며 정식 버전은 9월에서 10월 사이에 출시될 예정이다.

실행 플랜의 변동으로 느려진 쿼리를 고정하는 기능이 추가되었고, vacuum은 이제 여러 워커를 통해 인덱스를 병렬로 정리한다. 또한 copy 키워드를 통해 JSON으로 직접 내보낼 수 있는 기능 등이 포함된 Postgres 19의 정식 릴리스가 임박했다.

커뮤니티 글

모든 글 보기