아키텍처
GritDB는 트랜잭션 엔진(PostgreSQL 17.11)과 분석 엔진(GritDB 엔진), 두 엔진으로 동작합니다. 분석 엔진은 PLUG · UNIFY · BURST로 되어 있고, PLUG가 트랜잭션 엔진과 연결됩니다. 두 엔진은 서버 한 대에서 함께 실행되고, 응용 프로그램에는 데이터베이스 하나로 보입니다. 도입 방식은 두 가지입니다. 운영 DB 옆에 분석계로 붙이거나, 한 데이터베이스로 씁니다.
GritDB
PLUG 트랜잭션 엔진과 연결
UNIFY 하이브리드 저장 · 읽기
BURST 최적화 · 병렬 실행
grit_admin이 두 엔진과 카탈로그 프로세스를 함께 띄우고 지켜봅니다.
두 엔진
트랜잭션 엔진
PostgreSQL 17.11
SQL 접속 지점입니다. 쓰기와 트랜잭션, 등록하지 않은 테이블, 분석 엔진이 실행하지 못하는 조회를 처리합니다. 데이터는 행 단위로 저장합니다.
분석 엔진
GritDB 엔진 · GritSurfer
PLUG · UNIFY · BURST 세 부분으로 되어 있습니다. PLUG가 트랜잭션 엔진에서 변경과 분석 세션의 조회를 받고, UNIFY가 변경을 저장하고, BURST가 조회를 실행합니다.
쿼리 경로 보기쿼리 경로 접기
- 일반 세션 (기본값)
- 모든 쿼리를 트랜잭션 엔진이 실행합니다.
- 분석 세션
- 서브쿼리, CTE, 뷰 안에서도 등록한 테이블만 읽는 SELECT 문은 한 행 조회라도 분석 엔진이 실행합니다. PLUG가 이 조회를 받아 BURST로 넘깁니다. 기본 제공이 아닌 함수나 연산자를 쓰는 조회, 결과 열이 1.1이 받는 15가지 형식 밖인 조회, 커서로 읽는 조회는 분석 엔진이 실행하지 못합니다. 이런 조회는 메시지 없이 트랜잭션 엔진이 실행합니다.
분석 세션은 접속을 시작할 때 접속 옵션으로 켭니다(예: libpq 접속 문자열 options='-c gritsurfer_session_mode=surfer'). 접속한 뒤에는 바꿀 수 없고, 계정이나 데이터베이스의 기본값으로도 켤 수 없습니다. 분석 세션에서는 문장 힌트(/*+ engine=pg */ 또는 /*+ engine=burst */)로 엔진을 지정할 수 있습니다. 어느 엔진이 실행하는지는 분석 세션에서 EXPLAIN으로 확인합니다. 분석 엔진이 실행하는 조회는 EXPLAIN 결과 첫 줄에 engine: GritBurst가 나옵니다.
프로세스 구성 보기프로세스 구성 접기
grit_admin
감독 프로세스
두 엔진과 카탈로그 프로세스를 순서대로 띄우고 지켜봅니다. 기동은 gritdb-start, 정지는 gritdb-stop 명령으로 합니다.
postgres
트랜잭션 엔진
PostgreSQL 17.11에 GritSurfer의 확장(gritsurfer)을 올린 프로세스입니다. 확장에는 PLUG의 트랜잭션 엔진 쪽 연결과 테이블 등록 함수가 있습니다.
grit_catalog_process
카탈로그 프로세스
GritDB 카탈로그를 맡습니다. 등록 테이블과 열 기반 파일의 정보를 읽고 씁니다. 트랜잭션 엔진이 준비된 뒤에 뜹니다.
grit_surfer_process
분석 엔진
GritDB 엔진입니다. PLUG의 분석 엔진 쪽 연결과 UNIFY, BURST가 이 프로세스 안에서 실행됩니다.
도입 방식
분석계로 붙이기
1.1에서 권하는 방식
운영 DB 내장 복제 · CDC · ETL GritDB 리포트 · BI 도구
운영 DB는 그대로 두고, 변경을 GritDB에 보냅니다. 운영 DB가 PostgreSQL이면 PostgreSQL 내장 복제로, 다른 데이터베이스면 PostgreSQL을 대상으로 쓰는 CDC · ETL 도구로 보냅니다. GritDB의 트랜잭션 엔진이 그 쓰기를 받고, 분석 엔진의 PLUG가 이어받습니다. 리포트 · BI 도구는 GritDB에 접속하고 접속 옵션으로 분석 세션을 켭니다. 쓰기와 최신 값 조회는 운영 DB에서 합니다. GritDB 쪽에서 복제를 적용할 때도 쓰기마다 분석 엔진의 수신 확인을 기다립니다. 하지만 운영 DB의 업무 트랜잭션은 그 확인을 기다리지 않습니다.
한 데이터베이스로 쓰기
트랜잭션과 분석을 함께
응용 프로그램 GritDB
응용 프로그램이 GritDB에 직접 쓰고 조회합니다. QuickStart대로 설치하면 이 구성이 됩니다. 쓰기는 트랜잭션 엔진이, 분석 세션의 조회는 분석 엔진이 맡습니다. 1.1에서는 등록한 테이블의 쓰기마다 분석 엔진의 수신 확인을 기다리므로, 운영 업무에는 분석계로 붙이는 방식을 권합니다.
분석계로 붙이는 과정은 제품 홈의 시연 영상에서 볼 수 있습니다.
운영 DB에 생기는 일
분석계로 붙일 때 운영 DB에서 달라지는 것과 분석계가 멈췄을 때 살펴볼 것을 정리했습니다.
- 설정할 때 (PostgreSQL)
- wal_level을 logical로 바꾸고 publication을 만듭니다. wal_level을 바꾸면 운영 DB를 한 번 재시작해야 합니다. REPLICATION 권한과 게시한 테이블을 읽을 권한이 있는 복제 계정이 필요하고, GritDB 서버에서 오는 접속도 pg_hba.conf와 방화벽에서 허용해야 합니다. GritDB에서 subscription을 만들면 운영 DB에 복제 슬롯이 하나 생기고, 처음 한 번 초기 복사로 테이블 전체를 읽습니다. 초기 복사 동안에는 운영 DB에 긴 읽기 트랜잭션이 열려 있어 정리(VACUUM)가 늦어집니다. 그래서 큰 테이블은 한가할 때 붙입니다. 초기 복사 동안에는 테이블 복사용 슬롯과 복제 접속이 잠시 더 생겼다가 저절로 지워지므로, 운영 DB의 max_replication_slots와 max_wal_senders에 여유를 둡니다. 이 둘도 재시작해야 바뀌므로 wal_level을 바꿀 때 함께 정합니다. 기본 키가 없는 테이블은 publication에 넣기 전에 REPLICA IDENTITY를 정합니다. 정하지 않으면 운영 DB에서 그 테이블의 수정과 삭제가 오류로 멈춥니다.
- 평소
- 운영 DB는 commit한 변경을 WAL에서 꺼내 GritDB로 보냅니다(논리 디코딩). 무거운 리포트 질의는 운영 DB가 아니라 GritDB가 실행합니다.
- 분석계가 멈추면
- 복제 슬롯 때문에 운영 DB가 WAL을 지우지 않아 디스크 사용량이 늘어납니다. 운영 DB의 max_slot_wal_keep_size로 상한을 두면 디스크는 지킬 수 있습니다. 하지만 상한을 넘으면 복제 슬롯이 무효가 되어 다시 쓸 수 없고, 분석계의 테이블을 처음부터 다시 복사해야 합니다.
- 치울 때
- GritDB에서 subscription을 지우면 운영 DB의 복제 슬롯도 함께 지워집니다. 운영 DB의 pg_replication_slots에서 슬롯이 사라졌는지 확인합니다. 운영 DB에서 바꾼 wal_level, max_replication_slots, max_wal_senders, publication, 복제 계정, 접속 허용, REPLICA IDENTITY는 그대로 남으므로 필요하면 되돌립니다. 앞의 세 설정을 되돌리면 재시작이 한 번 필요하고, 접속 허용은 설정을 다시 읽으면 바뀝니다.
- 지켜볼 것
- 운영 DB의 pg_replication_slots에서 슬롯 상태(wal_status)와 슬롯이 붙잡은 WAL 양을 봅니다. WAL 양은 현재 WAL 위치에서 restart_lsn을 뺀 값입니다. 디스크 여유도 함께 봅니다.
- 분석 결과에 보이기까지
- GritDB가 받은 변경은 자체 시험에서 보통 12초 뒤에 분석 세션의 조회 결과에 보였고, 100번 중 99번은 22초 안에 보였습니다. 여기에 운영 DB에서 GritDB로 복제되는 시간이 더해집니다. 최신 값이 꼭 필요한 조회는 운영 DB에서 합니다.
- 다른 데이터베이스 (CDC · ETL 도구)
- 운영 DB 쪽 설정과 부담, 멈췄을 때의 동작은 그 도구를 따릅니다.
PLUG: 트랜잭션 엔진과 잇는 연결 엔진
PLUG는 분석 엔진(GritSurfer) 안에서 트랜잭션 엔진과 연결되는 엔진입니다. 1.1에서 PLUG가 하는 일은 네 가지입니다.
- 접속 연결: 트랜잭션 엔진의 접속마다 연결 통로를 엽니다. 내장 복제를 적용하는 작업자의 접속도 포함합니다.
- 변경 전달: 등록한 테이블의 입력, 수정, 삭제를 쓰는 시점에 받아 UNIFY로 넘깁니다. 쓰기마다 분석 엔진의 수신 확인을 받습니다.
- 조회 전달: 분석 세션의 조회를 BURST로 넘기고, 결과를 트랜잭션 엔진으로 돌려줍니다. 응용 프로그램은 같은 접속으로 결과를 받습니다.
- 복구: 분석 엔진을 다시 띄우면, GritDB의 복구용 복제 슬롯(gritsurfer_slot)이 남겨 둔 WAL에서 변경을 이어받습니다.
UNIFY · BURST
변경 저장
조회
1.1의 조회는 열 기반 파일을 읽습니다. 메모리에 쌓인 행은 열 기반 파일로 옮겨진 뒤 조회에 보입니다.
UNIFY · BURST 자세히 보기UNIFY · BURST 자세히 접기
UNIFY
하이브리드 저장 엔진
메모리에는 행으로, 디스크에는 열 기반 파일로 저장합니다. PLUG로 받은 입력, 수정, 삭제를 메모리에 행으로 쌓았다가 열 기반 파일로 옮기고, 수정과 삭제도 파일에 반영합니다. 조회 때는 열 기반 파일에서 필요한 열만 읽어 BURST로 넘깁니다. 조건에 맞지 않는 행 묶음은 묶음마다 적어 둔 최솟값 · 최댓값을 보고 읽지 않습니다. 변경은 행으로 받고 분석은 열로 읽는 이 구조가 트랜잭션과 분석을 한 데이터베이스에서 처리하는 바탕입니다.
BURST
최적화 · 병렬 실행 엔진
분석 세션의 조회를 분석에 맞는 실행 계획으로 다시 세우고, UNIFY가 읽어 온 데이터를 여러 CPU 코어에서 병렬로 처리합니다. 행을 하나씩 처리하는 트랜잭션 엔진과 달리, 값을 수천 개씩 묶어 한 번에 계산합니다.
BURST가 분석 세션의 조회를 빠르게 처리하는 방법은 네 가지입니다.
- 묶음 단위 계산: 값을 수천 개씩 묶어 한 번에 계산합니다. 행마다 실행 단계를 오가지 않고, 같은 계산을 묶음 전체에 이어서 합니다.
- 병렬 실행: 조회 하나를 여러 CPU 코어가 나눠 실행합니다. 데이터를 작은 묶음으로 나눠 코어마다 읽기부터 조인과 집계까지 맡기고, 마지막에 결과를 합칩니다.
- 분석용 실행 계획: 조건으로 먼저 걸러 처리할 데이터를 줄입니다. 상위 몇 건만 필요한 조회(ORDER BY … LIMIT)는 전체를 정렬하지 않고 필요한 만큼만 남깁니다.
- 서브쿼리 펴기: 바깥 행마다 다시 실행해야 하는 서브쿼리(상관 서브쿼리)를 조인으로 바꿔 한 번에 처리합니다.
같은 서버 사양에서 22개 분석 질의 시간을 잰 결과는 TPC-H 벤치마크 기반 분석 성능 비교에 있습니다.
1.1에서 알아 둘 것
- 서버 한 대에 두 엔진을 함께 둡니다. 1.1에는 GritDB 자체의 이중화와 자동 전환(failover)이 없습니다. 분석계로 붙인 GritDB는 서버를 잃어도 운영 DB에서 다시 받을 수 있습니다. 먼저 잃은 서버가 운영 DB에 남긴 복제 슬롯을 운영 DB에서 직접 지웁니다. 이 슬롯이 남아 있으면 운영 DB가 WAL을 지우지 않습니다. 그다음 새 서버에 다시 붙여 처음부터 복사합니다.
- 분석 엔진은 열 기반 파일에 저장된 데이터를 읽습니다. 방금 commit한 변경은 자체 시험에서 보통 12초 뒤에 분석 세션의 조회 결과에 보였고, 100번 중 99번은 22초 안에 보였습니다. 분석계로 붙였으면 운영 DB에서 복제되는 시간이 더해집니다. 최신 값이 꼭 필요한 조회는 일반 세션에서 하고, 분석계로 붙였으면 운영 DB에서 합니다.
- 분석 세션은 읽기 전용으로 시작합니다. 쓰기는 일반 세션에서 합니다.
- 1.1의 분석 세션은 행 단위 보안(RLS) 정책과 보안 장벽 뷰(security_barrier)의 보호를 적용하지 않습니다. RLS를 건 테이블은 등록하지 않고, RLS로 나눠 보여야 하는 데이터는 일반 세션에서 조회합니다. 읽으면 안 되는 계정이 있는 테이블과 일부 열만 읽게 한 테이블도 등록하지 않습니다.
- 1.1은 들어오는 접속도, 운영 DB에 붙는 복제 접속도 암호화(TLS)하지 않습니다. 운영 DB, 리포트 · BI 도구와 GritDB는 같은 사설망 안에서 연결합니다. 암호화 접속만 받도록 설정된 운영 DB에는 붙일 수 없습니다.
- 분석할 테이블은 비어 있을 때 등록합니다. 등록 전에 있던 행은 분석 엔진으로 옮기지 않습니다. 분석계로 붙일 때는 빈 테이블을 등록한 뒤 subscription을 만듭니다. 운영 DB에 이미 있던 행은 subscription의 초기 복사로 들어와 분석 엔진에도 저장됩니다. 등록 조건은 REPLICA IDENTITY FULL 설정과 지원하는 열 형식입니다.
- 지원하는 열 형식은 boolean, smallint, integer, bigint, real, double precision, numeric, date, time, timestamp, timestamptz, interval, char, varchar, text의 15가지입니다. uuid, bytea, json, jsonb, 배열처럼 그 밖의 형식인 열이 있는 테이블은 등록되지 않습니다.
- 금액처럼 정확해야 하는 열은 정밀도를 정한 numeric(p, s)로 만들고, p는 38 이하로 둡니다. 정밀도를 정하지 않은 numeric은 분석 엔진에서 근삿값으로 계산합니다.
- 등록하거나 해제한 뒤에는 그 테이블을 쓰는 접속을 다시 엽니다. 연결 풀과 복제 작업자의 접속도 다시 엽니다.
- 1.1에서는 등록한 테이블에 한 트랜잭션으로 쓰는 행 수에 상한이 있고, 이 상한은 서버 메모리에 따라 다릅니다. 분석계의 초기 복사는 테이블 하나가 한 트랜잭션이고, 운영 DB의 큰 배치도 마찬가지입니다. 큰 테이블과 큰 배치는 사전 상담에서 확인합니다.
- 등록한 테이블의 TRUNCATE와 ALTER TABLE은 1.1의 분석 엔진에 반영되지 않습니다. GritDB에서는 이 두 명령을 쓰지 않습니다.
- 분석계로 붙였으면 운영 DB에서 한 TRUNCATE도 내장 복제로 넘어오지만, 분석 엔진에는 반영되지 않습니다. 운영 DB에서 TRUNCATE하면 GritDB 쪽에서 그 테이블을 다시 받습니다. 절차는 기술 지원에서 안내합니다.
- 운영 DB의 테이블 구조 변경(DDL)은 내장 복제로 넘어오지 않습니다. 운영 DB에서 열을 바꾸면 복제가 멈추거나 값이 어긋나므로, GritDB 쪽에서 그 테이블을 다시 받습니다.
- CDC · ETL 도구로 붙일 때도 GritDB에 테이블을 먼저 만들어 등록한 뒤 초기 적재를 시작합니다. 등록하거나 해제한 뒤에는 도구의 적용 프로세스를 다시 시작합니다. DDL 복제처럼 도구가 PostgreSQL 대상에서 지원하지 않는 기능은 GritDB에서도 지원하지 않습니다.
- GritDB의 wal_level은 logical로 고정되어 있습니다. 분석 엔진을 다시 띄울 때 PLUG가 WAL에서 변경을 이어받는 데 이 설정을 씁니다.
- 기본 키가 없는 테이블을 publication에 넣으면 운영 DB에서 그 테이블의 수정과 삭제가 오류로 멈춥니다. 넣기 전에 REPLICA IDENTITY를 정합니다. GritDB 쪽 테이블에도 운영 DB와 같은 기본 키를 둡니다. 기본 키가 없으면 수정과 삭제의 복제가 멈추거나 느려집니다.
- 데이터는 모두 datafiles 디렉터리 한 묶음에 있습니다. 백업, 이동, 삭제는 이 묶음 단위로 하고, 묶음은 설치한 경로에 둡니다. 다른 경로로 옮기면 열 기반 파일을 잃습니다.
설치와 운영 절차는 QuickStart에 있습니다.
GritDB를 직접 확인해 보세요
사전 상담이나 PoC를 요청하시면 담당자가 연락드립니다.