콘텐츠로 이동

(KO) PostgreSQL Base Infrastructure — 섹션 개요

목차

여기는 base-infra 서브카테고리다. PostgreSQL의 다른 모든 서브시스템이 이미 존재한다고 가정하고 사용하는, 프로세스 안에서 사는 기반이다. 다른 서브카테고리와 달리 base-infra에는 단일 “기능”이 없다. 스토리지 엔진, 질의 파이프라인, 카탈로그, 트랜잭션 기계가 모두 호출하는 횡단 관심(cross-cutting facilities) 의 묶음이라는 점이다. 백엔드의 거의 모든 .c 파일을 열면 가장 먼저 여기에 손을 댄다. 메모리 컨텍스트 안에서 palloc하고, 오류 시 ereport하고, fmgr로 함수를 찾고, GUC를 읽고, 리소스 오너에 정리 작업을 등록한다.

구체적으로 이 서브카테고리는 src/backend/utils/ 아래에 뿌리를 둔 일곱 가지 시설을 소유한다.

  • 메모리 컨텍스트 (utils/mmgr/) — 계층적 할당기 트리다. CurrentMemoryContext를 대상으로 palloc/pfree를 호출하며, 하나의 MemoryContextMethods 가상 테이블 뒤에 네 가지 구현이 있다. AllocSet(범용 기본값, aset.c), Slab(고정 크기 청크, slab.c), Generation(FIFO에 가까운 수명, generation.c), Bump(밀집 배치, 개별 해제 없음 — REL_18에서 추가된 구현, bump.c)이 그것이다.
  • 오류 처리 (utils/error/) — elog/ereport 패밀리, 오류 심각도 수준, 그리고 C++ 예외 없이도 “어디서든 오류를 던지고 확실하게 정리한다”는 것을 가능하게 하는 setjmp/longjmp 비로컬 언와인딩(PG_TRY/PG_CATCH/PG_RE_THROW, PG_exception_stack)이다.
  • 함수 매니저 (utils/fmgr/) — fmgr를 말한다. pg_proc 카탈로그 행을 호출 가능한 FmgrInfo로 변환하고, V1 호출 규약(PG_FUNCTION_ARGS / FunctionCallInfo)을 정의하며, 집합 반환·복합 반환 함수를 위한 funcapi를 제공한다.
  • 데이터타입 라이브러리 (utils/adt/) — 약 118개 파일로 구성되며, 모든 내장 타입의 in/out/send/recv 함수와 연산자를 구현한다. numeric, varlena 텍스트, date/time, jsonb, 배열, 범위/다중범위(multirange), 네트워크 타입, 그리고 플래너가 읽는 선택도 추정기가 여기 들어 있다.
  • GUC 파라미터 (utils/misc/) — Grand Unified Configuration 시스템이다. 변수 정의(guc_tables.c), 우선순위 순으로 쌓인 소스 스택(postgresql.conf, 커맨드라인, ALTER SYSTEM, 역할별/데이터베이스별), check/assign/show 훅이 포함된다.
  • 리소스 오너 (utils/resowner/) — 메모리 컨텍스트 트리를 모델로 삼은 ResourceOwner 트리다. 버퍼 핀, 락 참조, 튜플 디스크립터, 유사 리소스를 추적해서, 오류 시에도 트랜잭션/질의 종료 시점에 반드시 해제한다.
  • dynahash (utils/hash/) — dynahash.c가 구현하는 체이닝 해시 테이블이다. 프로세스 로컬 테이블로도, 파티셔닝된 공유 메모리 모드로도 쓰이며, 버퍼 조회 테이블과 헤비웨이트 락 테이블이 후자의 사례다.

경계 — 여기에 없는 것들:

  • 튜플 정렬과 스필 (utils/sort/: tuplesort.c, tuplestore.c, logtape.c)은 트리 구조상 인접하지만 query-processing(postgres-tuplesort.md)에 속한다. 질의 실행 시설이지, 보편적 기반이 아니라는 점이다.
  • 인코딩 변환과 로케일/콜레이션 (utils/mb/, utils/adt/pg_locale*)은 i18n-text에 속한다. base-infra는 텍스트 데이터타입을 넘기기만 하고, 문자 집합·콜레이션 동작은 i18n-text가 담당한다.
  • 동적 공유 메모리와 공유 할당기 (utils/mmgr/dsa.c, freepage.c)는 server-architecture(postgres-shared-memory-ipc.md)에 속한다. base-infra는 프로세스 로컬 컨텍스트 트리를 소유하고, DSA는 그 공유 세그먼트 유사물로서 IPC 기반과 함께 문서화된다.
  • Portal 메모리 (utils/mmgr/portalmem.c)는 mmgr/ 아래에 있지만 query-processing(postgres-portals-prepared.md)에 속한다.
  • dynahash 위에 세워진 카탈로그 캐시 (relcache, catcache)는 system-catalog에 속한다. base-infra는 범용 해시 테이블 엔진만 소유하며, 카탈로그별 캐시는 소유하지 않는다.

일곱 가지 시설은 동등한 관계가 아니다. 계층을 이룬다. 메모리 컨텍스트와 오류 처리가 진정한 바닥이라는 점이다. 다른 모든 시설은 컨텍스트 안에서 할당하고, ereport로 오류를 던진다. 리소스 오너 트리와 dynahash는 그 한 단계 위에 자리한다. fmgr, adt 라이브러리, GUC는 나머지 엔진이 호출하는 애플리케이션 향 시설이다. 아래 다이어그램은 의존 방향(화살표는 “~위에 세워진 / ~를 호출한다”를 의미한다)을 나타내며, 노드 레이블은 각 박스를 소유한 모듈 문서를 가리킨다.

flowchart TB
  subgraph CALLERS["나머지 백엔드"]
    REST["스토리지 / 실행기 / 플래너 / 카탈로그 / 트랜잭션<br/>(다른 모든 서브카테고리)"]
  end

  subgraph APP["애플리케이션 향 기반"]
    FMGR["함수 매니저<br/>postgres-fmgr.md<br/>(pg_proc 행 -> 호출 가능 형태)"]
    ADT["데이터타입 라이브러리<br/>postgres-datatypes-adt.md<br/>(타입 I/O + 연산자)"]
    GUC["GUC 파라미터<br/>postgres-guc-parameters.md<br/>(설정 변수 시스템)"]
  end

  subgraph MID["추적 + 조회"]
    RESOWN["리소스 오너<br/>postgres-resource-owners.md<br/>(오류 시 핀/락 해제)"]
    HASH["dynahash<br/>postgres-dynahash.md<br/>(프로세스 로컬 + 파티셔닝 공유)"]
  end

  subgraph BOTTOM["진정한 바닥"]
    MCXT["메모리 컨텍스트<br/>postgres-memory-contexts.md<br/>(AllocSet / Slab / Generation / Bump)"]
    ELOG["오류 처리<br/>postgres-error-handling.md<br/>(elog/ereport, setjmp/longjmp 언와인드)"]
  end

  REST --> FMGR
  REST --> ADT
  REST --> GUC
  REST --> RESOWN
  REST --> HASH

  FMGR --> ADT
  ADT --> MCXT
  GUC --> MCXT
  RESOWN --> MCXT
  HASH --> MCXT

  FMGR --> MCXT
  FMGR --> ELOG

  MCXT -. "longjmp 언와인드가<br/>오류/중단 컨텍스트를 해제" .-> ELOG
  RESOWN -. "중단 시 컨텍스트 리셋과<br/>짝을 이루는 해제 순서" .-> MCXT

독자가 앞으로 계속 가져가야 할 세 가지 핵심 관계가 있다.

  • 할당과 오류 처리는 함께 설계됐다. palloc 실패 자체가 ereport(ERROR, ...)이고, 오류를 언와인드하는 longjmp는 쿼리별 컨텍스트 트리를 리셋·삭제하는 핸들러로 제어를 넘긴다. 이는 “자유롭게 할당하고, 오류 시 던지면, 서브트리 전체가 한꺼번에 회수된다”는 핵심 관용구가 된다. PostgreSQL C 코드가 개별 free를 거의 하지 않는 이유가 바로 이것이다.
  • 리소스 오너는 메모리 컨텍스트 트리를 의도적으로 모방한다. resowner README가 명시하듯, 둘 다 위에서 아래로 해제되는 부모/자식 포리스트이며, 중단 처리는 고정된 순서로 두 트리를 순회해 메모리와 그것이 보호하던 핀·락이 함께 내려간다.
  • fmgr는 adt 라이브러리로 가는 다리다. utils/adt/의 모든 내장 연산자와 타입 I/O 루틴은 FmgrInfo / FunctionCallInfo로 도달한다. fmgr는 간접 계층이고, adt는 그 뒤에 있는 함수들의 집합이다.

상호 참조 우선 원칙에 따라 — 아래에 있는 두 시설을 먼저 읽어야 그 위에 놓인 것들이 이해된다.

  1. postgres-memory-contexts.md — 할당기 트리. palloc/MemoryContextSwitchTo와 컨텍스트 수명 모델을 이해하기 전까지는 나머지가 성립하지 않는다.
  2. postgres-error-handling.mdelog/ereportPG_TRY/longjmp 언와인드. (1)과 함께 읽어야 한다. 둘은 함께 설계됐다는 점이다.
  3. postgres-resource-owners.md — 핀/락 정리 트리. (1)의 직접 유사체로 읽힌다. (1) 바로 다음에 읽는 것이 좋다.
  4. postgres-dynahash.md — 범용 해시 엔진. 분량이 짧고, 카탈로그 캐시·공유 락/버퍼 테이블에서 참조된다.
  5. postgres-fmgr.md — 카탈로그 함수가 C 호출이 되는 과정. 데이터타입 라이브러리의 입구다.
  6. postgres-datatypes-adt.md — fmgr로 도달하는 타입 라이브러리.
  7. postgres-guc-parameters.md — 설정 시스템. 대체로 독립적이므로 마지막에 읽어도 되고, 특정 파라미터를 쫓아 이 문서에 도착했다면 첫 번째로 읽어도 무방하다.

이하는 전향 참조다. 아래 모듈 문서들은 작성 예정이며, 요약은 예측값이다.

모듈 문서한 줄 범위
postgres-memory-contexts.md계층적 MemoryContext 할당기: palloc/pfree, MemoryContextSwitchTo, 컨텍스트 리셋/삭제 수명 주기, 하나의 가상 테이블 뒤에 있는 네 가지 구현 — AllocSet(기본값), Slab, Generation, Bump.
postgres-error-handling.mdelog/ereport 패밀리, 심각도 수준(DEBUGPANIC), errmsg/errcode/errdetail 빌더, PG_TRY/PG_CATCH/PG_RE_THROWPG_exception_stack을 이용한 setjmp/longjmp 언와인딩.
postgres-fmgr.md함수 매니저: pg_proc 행에서 FmgrInfo까지의 과정, V1 호출 규약(PG_FUNCTION_ARGS, FunctionCallInfo, PG_GETARG_*/PG_RETURN_*), 집합·복합 반환 함수를 위한 funcapi.
postgres-datatypes-adt.mdutils/adt/의 내장 데이터타입 라이브러리: numeric, varlena 텍스트, date/time, jsonb, 배열, 범위의 in/out/send/recv + 연산자 함수, 플래너가 사용하는 타입별 선택도 추정기.
postgres-guc-parameters.mdGUC 시스템: guc_tables.c의 변수 정의, 우선순위 순 소스 스택(postgresql.conf → 커맨드라인 → ALTER SYSTEM → 역할/데이터베이스), check/assign/show 훅, SETRESET/트랜잭션 롤백 의미론.
postgres-resource-owners.md버퍼 핀, 락 참조, 튜플 디스크립터, 플랜캐시 참조를 추적하는 ResourceOwner 트리. 오류 시 또는 질의/트랜잭션 종료 시 고정된 순서로 해제하며, 메모리 컨텍스트 트리를 모델로 삼는다.
postgres-dynahash.mddynahash.c: 프로세스 로컬(예: syscache 뒷받침)과 파티셔닝된 공유 메모리 모드(버퍼 조회 테이블, 헤비웨이트 락 테이블) 모두에 쓰이는 체이닝 해시 테이블 엔진. 요소/항목 레이아웃과 파티션 락킹 포함.

base-infra는 바닥이므로 거의 모든 것과 맞닿는다. 가장 직접적으로 넘겨주거나 소비되는 섹션들만 적는다.

  • server-architecture (postgres-overview-server-architecture.md) — 가장 가까운 이웃. 파티셔닝 모드의 dynahash가 헤비웨이트 락 테이블의 뒷받침이 된다. 그쪽의 DSA/동적 공유 메모리 할당기는 base-infra의 프로세스 로컬 컨텍스트 트리와 대응하는 공유 세그먼트 유사물이다(dsa.cmmgr/ 아래 있지만 IPC 기반과 함께 문서화된다). 리소스 오너는 그 서브시스템이 관리하는 버퍼 핀과 락을 해제한다.
  • query-processing (postgres-overview-query-processing.md) — 모든 표현식 호출에 fmgr를 소비하고, 타입 동작을 위해 adt 라이브러리를 쓴다. 구조적으로 base-infra 근처에 있지만 질의 실행에 속하는 스필 시설(postgres-tuplesort.md)과 포털 메모리를 소유한다.
  • system-catalog (postgres-overview-system-catalog.md) — relcache와 catcache는 dynahash 위에 세워지며, 백엔드별 메모리 컨텍스트 안에서 산다. base-infra는 범용 엔진을 소유하고, system-catalog는 카탈로그별 캐시와 그 무효화를 소유한다.
  • i18n-text (postgres-overview-i18n-text.md) — base-infra로부터 텍스트 데이터타입을 받아, base-infra가 의도적으로 다루지 않는 인코딩 변환(utils/mb/)과 콜레이션/로케일 프로바이더(utils/adt/pg_locale*)를 추가한다.
  • txn-recovery (postgres-overview-txn-recovery.md) — 그쪽의 중단 처리가 base-infra가 정의한 리소스 오너 해제와 쿼리별 컨텍스트 리셋을 구동한다. 오류 시 두 언와인드 경로가 맞물려 실행된다.