Quipu-Log 교과서
파트 1 · 출발점: DB 없이, 파일로

02 · Quipu-Log 지도와 DB↔파일시스템 대응표

이 챕터는 이 책 전체의 지도입니다. Quipu-Log가 어떤 부품들로 이루어졌는지 5개 크레이트를 조감하고, 그보다 중요한 — DB가 당연하게 제공하던 개념들이 파일 위에서는 어떤 모습으로 나타나는지 — 대응표를 한 번에 보여드립니다. 이 표를 머릿속에 넣으면 뒤 챕터들이 훨씬 빨리 읽힙니다.

한 문장 요약

Quipu-Log는 DB 없이 파일만으로 WAL·인덱스·락·MVCC·파티션 삭제를 재현한다. DB 개념 → 파일 구현의 대응을 이해하면 이 라이브러리의 모든 설계 결정이 보인다.

5개 크레이트 한눈에 보기

Quipu-Log는 하나의 단일 크레이트가 아닙니다. 역할별로 5개 크레이트로 나뉩니다. 각각이 무슨 일을 하는지 먼저 보겠습니다.

quipu-core 저장 엔진 · 레지스트리 · 암호화 쿼리 · 리텐션 (동기 코어) quipu-middleware 비동기 파이프라인 · DLQ · 필터 권한(RBAC) · tower 레이어 · 샤드 라우터 quipu-server 독립 데몬 HTTP/JSON API + RBAC quipu-client 서버 모드 레퍼런스 클라이언트 재시도 · 백오프 · 디스크 스풀 quipu-mcp MCP 서버 — LLM 감사관 (query/history/verify)
화살표는 의존 방향이다. quipu-core가 모든 것의 기반 — 저장·암호화·쿼리를 담당하고, quipu-middleware가 그 위에 비동기 파이프라인을 얹는다.
크레이트역할핵심 타입
quipu-core동기 저장 엔진 — 세그먼트 파일, 레지스트리, 암호화, 리텐션, 쿼리, 머클 트리AuditStore, StoreConfig, Table<T>
quipu-middleware비동기 파이프라인 — 논블로킹 emit, DLQ, 필터, RBAC, tower 레이어, 샤드 라우터AuditPipeline, AuditHandle, AuditLayer
quipu-server독립 데몬 — 토큰 인증 HTTP/JSON API, 쓰기 전용 모드HTTP 핸들러, 설정 파일
quipu-client서버 모드 레퍼런스 클라이언트 — 재시도, 지수 백오프, 디스크 스풀QuipuClient, Backoff, Spool
quipu-mcpLLM 감사관 — MCP 프로토콜로 LLM이 query·history·verify 호출MCP 툴 핸들러

임베디드 모드 vs 서버 모드

Quipu-Log를 쓰는 방법은 크게 두 가지입니다.

임베디드 모드: quipu-core + quipu-middleware를 여러분의 Rust 서비스에 라이브러리로 추가합니다. 감사 저장소가 서비스 프로세스 안에서 실행됩니다. 별도 데몬, 네트워크, DB가 필요 없습니다. Rust 서비스 한 개에 감사 로그가 필요할 때 가장 간단한 선택입니다.

서버 모드: quipu-server를 독립 프로세스로 실행하고, 여러 서비스(언어 무관)가 HTTP/JSON API로 기록합니다. 한 곳에서 여러 서비스의 감사 기록을 모을 때, 또는 Rust 이외 언어 서비스에서 쓸 때 선택합니다.

DB ↔ 파일시스템

관계형 DB에도 비슷한 구분이 있습니다. SQLite(임베디드)처럼 프로세스 안에서 돌거나, PostgreSQL(서버)처럼 별도 프로세스로 돌거나. Quipu-Log도 같은 선택지를 제공합니다 — 다만 내부 저장 엔진은 파일 위에 직접 구현되어 있습니다.

이 책의 뼈대: DB↔파일시스템 대응표

이제 이 챕터의 핵심입니다. DB를 써온 독자라면 다음 개념들을 이미 압니다: WAL, 인덱스, 락 매니저, MVCC, 파티션 삭제, 체크섬. Quipu-Log는 이것들을 DB 엔진 없이 파일 위에서 직접 구현합니다. 대응 관계를 한 번에 보겠습니다.

DB 개념Quipu-Log 파일 구현다루는 장
WAL (Write-Ahead Log)
트랜잭션 의도를 먼저 기록하는 순차 파일
append-only 세그먼트 파일
WAL이 곧 데이터베이스. 본체(B-tree) 없음.
7장
데이터 파일 / 테이블스페이스
테이블 데이터를 담는 파일 집합
세그먼트 파일 묶음 (Table<T>)
seg-0000000000.log, seg-0000000001.log...
8장
페이지 체크섬 / torn page 탐지
디스크 비트 오류·부분 쓰기 탐지
프레임 CRC32
[len][crc32][ts][payload] — 모든 레코드마다
9장
락 매니저
동시 쓰기 충돌 방지
OS 파일 락 (File::try_lock)
루트 디렉토리의 LOCK 파일 — 두 번째 프로세스가 열면 즉시 오류
13장
MVCC (다중 버전 동시성 제어)
읽기와 쓰기가 서로 안 막히게
읽기 스냅샷 (ReadSnapshot)
인메모리 인덱스를 클론 — 불변 세그먼트 + 인덱스 복제
14장
B-tree 보조 인덱스
특정 컬럼으로 빠른 조회
인메모리 레지스트리 인덱스 + 디스크 토큰
재시작 시 재구축; 블라인드 인덱스로 암호화 필드 검색
15장 26장
파티션 삭제 (partition drop)
오래된 파티션을 파일 통째 삭제
세그먼트 unlink
sealed 세그먼트 파일을 통째로 삭제 — O(1), 행 단위 재작성 없음
17장
WAL replay / 크래시 복구
정전 후 로그를 재실행해 복구
세그먼트 skim + 꼬리 truncate
CRC 실패 지점까지 유효, 나머지는 잘라낸다. redo-only.
12장

이 표가 이해되면, 뒤 챕터들은 "DB에서 X라는 개념을 파일로는 Y로 구현했구나"라는 흐름으로 읽힙니다. 막힐 때마다 이 표로 돌아오세요.

저장소 레이아웃: 실제 파일 구조

Quipu-Log 스토어를 열면 루트 디렉토리 아래 다음과 같은 구조가 생깁니다.

crates/quipu-core/src/store.rs — AuditStore 레이아웃 주석root/
  meta/          type schemas + custom column registry (replayed on open)
  logs/          AuditLog rows
  relations/     log -> target-entity-version relations
  registry/<t>/ one versioned registry table per entity/actor type
  access/        meta-audit (opt-in)
  LOCK           advisory OS lock file

각 디렉토리는 Table<T> 하나에 대응합니다 — 즉, 세그먼트 파일 여러 개로 이루어진 append-only 로그 하나. DB로 치면 테이블 하나가 테이블스페이스(파일 집합)에 저장되는 것과 같습니다. 18장에서 포맷 버저닝까지 포함해 자세히 다룹니다.

DB ↔ 파일시스템

DB에서는 데이터 딕셔너리(시스템 카탈로그)가 테이블·컬럼 정보를 관리한다. Quipu-Log에서는 meta/ 디렉토리가 그 역할을 한다 — 타입 스키마 정의가 append-only로 기록되고, 재시작 시 순서대로 재실행(replay)된다. DB의 DDL 로그와 같은 원리다.

스스로 확인

① quipu-core와 quipu-middleware의 역할 차이를 한 문장씩 말해보세요.
② DB의 "파티션 drop"이 Quipu-Log에서는 어떻게 구현되나요? 왜 "행 단위 DELETE + vacuum"보다 효율적인가요?
③ DB의 MVCC와 Quipu-Log의 읽기 스냅샷은 어떤 문제를 공통으로 해결하나요?