(KO) CUBRID 스토리지 엔진 — 섹션 개요
목차
이 섹션의 범위
섹션 제목: “이 섹션의 범위”CUBRID의 스토리지 엔진은 카탈로그·로케이터 아래, OS 파일시스템 위에 자리한 모든 부분을 가리킨다. OS 차원의 바이트 스트림 몇 줄을 받아 고정 크기 페이지로 잘라 두고, 그 페이지를 메모리에 캐시해 두며, 그 위에 가변 길이 사용자 레코드를 얹고, 레코드를 따라가는 정렬된 접근 경로를 짜고, 모든 바이트를 찢긴 쓰기(torn write), 더티 상태에서의 크래시, 그리고 (선택적으로) 디스크 도난으로부터 지키는 이 다섯 가지 일을 하는 계층이다. 로케이터와 카탈로그는 이 계층을 한 덩어리의 추상으로만 다룬다. heap 페이지나 B+Tree 리프를 달라고 부탁하면, 그것을 찾아 내놓는 일은 스토리지 엔진이 해 준다. 페이지가 어떻게 거기 와 있는지, 플러시할 때 어떻게 일관성을 지키는지, 정전을 어떻게 견디는지는 모두 이 섹션 안에서 처리되는 일이다.
위쪽 경계는 분명하다. heap과 B+Tree 변경은 locator_*_force(cubrid-locator.md)와 catalog_manager(cubrid-catalog-manager.md)를 거쳐 들어온다. WAL 레코드는 prior 리스트(cubrid-prior-list.md)와 로그 매니저(cubrid-log-manager.md)를 거쳐 빠져나간다. MVCC 가시성 판정은 cubrid-mvcc.md가 이 섹션의 heap 계층이 박아 둔 레코드 헤더를 읽고 내린다. 아래쪽 경계도 그만큼 분명하다. CUBRID 볼륨에 대한 모든 pread/pwrite는 디스크 매니저의 일이고, 엔진 안 다른 어떤 모듈도 데이터 파일에 직접 손대지 않는다. 그 사이에 들어가는 것이 이 섹션 9개 문서의 내용이다. 원래 열 번째였던 AREA 슬랩 풀은 락프리 자료구조와 함께 cubrid-overview-base-infra.md로 옮겨 갔다. 어떤 계층(파서, 옵티마이저, 실행기 등)이든 가져다 쓸 수 있는 메모리 할당자 부품이지 디스크 차원의 스토리지 계층이 아니기 때문이다.
계층 스택
섹션 제목: “계층 스택”스토리지 엔진은 이름표 붙이기가 깔끔할 만큼 분명한 층 구조를 갖는다. 각 층은 아래 층을 한 덩어리의 추상으로 다루고, 위로는 더 좁은 추상만 내보낸다. CUBRID의 어떤 읽기·쓰기 길을 따라가든, 이 층 구조를 잡아 두는 것이 첫 단계다.
flowchart TB
subgraph UPPER["상위 계층 (섹션 간 공유)"]
LOC["로케이터 / 카탈로그<br/>(cubrid-locator.md, cubrid-catalog-manager.md)"]
LOG["로그 매니저 + prior 리스트<br/>(cubrid-log-manager.md, cubrid-prior-list.md)"]
MVCC["MVCC + vacuum<br/>(cubrid-mvcc.md, cubrid-vacuum.md)"]
end
subgraph KEY["페이지 위의 키"]
BTREE["btree<br/>cubrid-btree.md"]
EHASH["extendible_hash<br/>cubrid-extendible-hash.md"]
end
subgraph REC["페이지 위의 레코드"]
HEAP["heap_manager<br/>(slotted page, MVCC 헤더)<br/>cubrid-heap-manager.md"]
OFLOW["overflow_file<br/>(대형 레코드 / OID 목록 체인)<br/>cubrid-overflow-file.md"]
end
subgraph EXT["볼륨 바깥의 데이터"]
LOB["LOB (BLOB / CLOB)<br/>(데이터 볼륨 밖 파일)<br/>cubrid-lob.md"]
end
subgraph CACHE["메모리 위의 페이지"]
PB["page_buffer<br/>(BCB 캐시, 3-zone LRU)<br/>cubrid-page-buffer-manager.md"]
DWB["double_write_buffer<br/>(찢긴 페이지 방지)<br/>cubrid-double-write-buffer.md"]
end
subgraph CRYPTO["페이지 단위 암호화"]
TDE["tde<br/>(AES/ARIA-256-CTR, MK → DEK)<br/>cubrid-tde.md"]
end
subgraph DISK["볼륨 & 파일 (OS 경계)"]
DM["disk_manager + file_manager<br/>(볼륨 / 섹터 / 파일 / 페이지)<br/>cubrid-disk-manager.md"]
VOLS[("OS 파일<br/>(_dbname / _dbname_t / _lgar*)")]
end
LOC --> HEAP
LOC --> BTREE
LOC --> LOB
LOG --> PB
HEAP --> OFLOW
BTREE --> OFLOW
HEAP --> PB
BTREE --> PB
EHASH --> PB
OFLOW --> PB
PB --> TDE
PB --> DWB
TDE --> DWB
DWB --> DM
PB -. 클린 페이지 읽기 .-> DM
DM --> VOLS
LOB -. 호스트 파일시스템 .-> VOLS
MVCC -. 레코드 헤더 읽기/쓰기 .-> HEAP
MVCC -. vacuum이 회수 .-> BTREE
다이어그램을 아래에서 위로 따라가며 각 층을 세부 문서와 짝지으면, 이 섹션의 일곱 갈래 구성이 한눈에 정리된다.
- 볼륨 & 파일 (
cubrid-disk-manager.md). OS 파일과 만나는 경계다. 볼륨은 OS 파일 한 개, 섹터는 연속된 64페이지로 디스크 매니저가 한 번에 잡는 할당 단위, 파일은 섹터 묶음, 페이지는 I/O 단위다(VPID = (volid, pageid)). 디스크 캐시는 영구용과 임시용을 갈라 둬서 임시 파일이 영구 공간을 갉아먹지 못하게 하고, 섹터를 두 단계로 예약하며, 볼륨을 언제 늘릴지 상황에 맞춰 결정한다. 파일 매니저는 예약된 섹터를 세 갈래의 확장 가능 데이터 표(Partial / Full / User)로 페이지로 풀어 준다. - 메모리 위의 페이지 (
cubrid-page-buffer-manager.md+cubrid-double-write-buffer.md). 페이지 버퍼는VPID → BCB → 인메모리 프레임을 버킷별 해시로 매핑한다. 그 위에 3-zone LRU가 굴러간다. 스레드별 private 리스트(쿼터를 조정할 수 있다)와 공유 리스트로 갈라져 있고, victim은 lock-free 큐를 거쳐 자고 있는 대기자에게 곧장 넘겨진다. BCB마다 사용자 정의 read/write/flush latch가 붙는다. 더티 페이지는 무엇이든 DWB를 거쳐야 밖으로 나간다. DWB는 홈 위치에 쓰기를 발행하기 전에 순차·고정 크기 볼륨에 페이지를 쌓아 두고fsync한다. 그래서 홈 자리에서 찢긴 쓰기가 일어나도, 로그 재생을 시작하기 전에 DWB 사본으로 복구가 끝난다. - 페이지 위의 레코드 (
cubrid-heap-manager.md+cubrid-overflow-file.md). heap 매니저는 가변 길이 사용자 레코드를 slotted 페이지에 얹고, 아홉 가지 레코드 종류(REC_HOME,REC_RELOCATION,REC_BIGONE,REC_NEWHOME, …)를 나눠 처리하며, 삽입·갱신·삭제·읽기를 그 위에 통과시킨다. MVCC 헤더(insert-MVCCID, delete-MVCCID, prev-version 체인)를 레코드 안쪽에 직접 박아 두기 때문에, 가시성 판정은 heap 페이지를 떠나지 않고 풀린다. 레코드가 어떤 heap 페이지에도 다 못 들어갈 만큼 커지면, heap이 오버플로 파일(FILE_MULTIPAGE_OBJECT_HEAP)에 넘기고 홈 OID에는 짧은 참조만 남긴다. 같은 오버플로 파일 모듈이 B+Tree 오버플로 키(FILE_BTREE_OVERFLOW_KEY)와, 리프 한 항목에 다 못 담는 키별 OID 목록까지 함께 처리한다. - 페이지 위의 키 (
cubrid-btree.md+cubrid-extendible-hash.md). B+Tree는 CUBRID의 주요 접근 경로다. slotted 페이지 노드, 비-leaf와 leaf에 따로 쓰는 레코드 포맷, 비-유니크 인덱스에서의 key‖OID 결합, 읽기 길의 latch-coupling, OID 접미사 차원에서 잡는 유니크 제약(중복이 쌓이면 키별 OID 목록 오버플로)이 핵심이다. extendible hash는 두 번째 on-page 구조다. 클래스 이름 → OID 조회, 카탈로그 → repr-id 조회, UPDATE/DELETE OID 중복 제거 표 등 내부 호출자 몇 군데가 쓴다. EHID 루트 디렉터리 파일이 포인터 수를 두 배씩 늘리며 자라고, 버킷 페이지는 slotted 구조에 이진 탐색 + 버킷 단위 local depth로 운영된다. - 볼륨 바깥의 큰 데이터 (
cubrid-lob.md). 행 옆에 둘 수 없을 만큼 큰 BLOB·CLOB 페이로드는 데이터 볼륨 바깥 파일(호스트 파일시스템 또는 오브젝트 스토어)로 빠진다. 행 안에는 로케이터 URI 문자열만 박힌다. TDES 위의 트랜잭션별 red-black 트리가 그 트랜잭션이 건드린 모든 로케이터를 추적하고, 커밋 / 롤백 한 자리에서 파일시스템 상태와 트랜잭션 결과를 맞춰 준다. - 암호화 (
cubrid-tde.md). TDE는 페이지 버퍼의 flush 직전 암호화 / read 직후 복호화 훅을 감싼다. 키 계층은 둘이다. 마스터 키(MK)는 데이터베이스 바깥 별도<db>_keys파일에 보관되고, MK가 데이터베이스마다 두는 데이터 암호화 키 셋(DATA, LOG, TEMP)을 감싸 둔다. 실제 바이트 단위 암복호화는 페이지마다의 nonce를 쓰는 AES-256-CTR 또는 ARIA-256-CTR이 한다(영구 페이지에는 LSA, 임시 페이지에는 원자 카운터, 로그 페이지에는 논리 pageid). TDE 플래그는 파일(테이블스페이스) 차원의 속성이고, 각 페이지의pflag비트로 그대로 전파된다.
이 다이어그램이 가르치는 가장 큰 한 가지 — 레코드 구조 계층은 디스크 매니저에 직접 접근하지 않는다, 반드시 페이지 버퍼를 거쳐야 한다. 이 한 줄이 페이지 버퍼가 WAL 순서를 강제할 수 있게 만드는 근거다. heap 페이지를 고치려는 측이 먼저 로그 레코드를 찍어 prior 리스트로 흘려 보내야 하고, 버퍼 매니저는 그 LSA가 영속화되기 전까지는 더티 페이지 flush를 거부한다. B+Tree, ehash, 카탈로그 변경 모두 같은 규칙을 받는다.
읽는 순서
섹션 제목: “읽는 순서”이 섹션 9개 문서는 비중이 다 다르고, 알파벳순이나 다이어그램 아래에서 위로 읽는 게 최선도 아니다. 아래 순서는 각 문서 뒤에 깔린 엔지니어링 무게에 맞춰 짠 것이다. 코드가 가장 두툼하게 박힌 곳에서 시작해, 거기서부터 가지를 쳐 가는 길이다.
cubrid-disk-manager.md— 가장 먼저. 이 섹션의 다른 모든 문서가 다시 쓰는 어휘(VPID, 섹터, 파일, 볼륨)가 여기서 정의된다. 또 위쪽 의존이 거의 없어서(OS 파일 하나와 페이지 크기만 주면 된다) 외따로 떼어 놓고 봐도 풀린다. 두 단계 섹터 예약과 영구/임시 분리는 특히 잘 잡아 둔다. 페이지 버퍼와 DWB에서 다른 이름으로 한 번 더 등장한다.cubrid-page-buffer-manager.md— 두 번째. 스토리지 엔진 엔지니어링 무게의 대부분이 이 문서에 들어가 있다. BCB 배열, private + 공유 리스트로 갈린 3-zone LRU, 자고 있는 대기자에게 victim을 곧장 넘기는 메커니즘, 사용자 정의 RW/flush latch — 모두 밀도 있는 주제다. 시간을 충분히 쓴다. 또한 이 섹션에서 위쪽 모든 계층(heap, btree, ehash, 카탈로그, 로그)이 모두 들르는 유일한 층이기도 하다. 한복판의 조정자.cubrid-double-write-buffer.md— 페이지 버퍼 바로 다음. 영속성 쪽의 짝꿍이다. DWB는 개념만 보면 단순하다(순차 staging 볼륨 +fsync+ 홈 쓰기). 다만 flush 길 안에서의 자리와 재시작 복구 절차는 페이지 버퍼의 flush 시퀀스를 머리에 넣지 않으면 잘못 읽기 쉽다.cubrid-heap-manager.md+cubrid-btree.md— 주요 레코드/키 접근 방식 두 가지를 나란히 본다. heap 매니저는 on-page 레코드 어휘와 MVCC 헤더 모양을, B+Tree는 latch-coupling 규율과 key‖OID 관례를 보여 준다. 둘은 오버플로 파일로 서로를 가리키므로 어느 쪽을 먼저 봐도 무방하지만, 짝으로 읽어야 행 한 줄이 어떻게 읽히는지가 이제 보인다는 모델이 만들어진다.cubrid-overflow-file.md— heap + btree 다음에 훑는다. 역할은 한 줄이다. 기본 슬롯이 모자랄 때 모두가 떨어지는 페이지 사슬. 무엇이 흘러드는지 모르고 들어가면 길을 잃는다.cubrid-extendible-hash.md— 필요할 때 본다. 호출자가 적다(클래스 이름 조회, repr-id 조회, OID 중복 제거). SELECT/UPDATE 핫패스에는 등장하지 않는다. 카탈로그, 스키마 리로드, 유니크 인덱스 유지 보수를 디버깅할 때 꺼내 본다.cubrid-lob.md— 필요할 때 본다. 대부분의 워크로드에는 LOB 컬럼이 없다. 있을 때는 이 문서가 곧 답이다.cubrid-tde.md— 필요할 때 본다. 암호화 길은 스토리지 엔진의 나머지 부분과 거의 직교한다. 잘 정해진 두 자리(flush 직전, read 직후)에 훅으로 끼우기 때문에, 다른 모든 것 위에 깔끔히 얹히고, 위에서 그린 읽기·쓰기 길 자체를 바꾸지 않는다.
1~4를 차례로 읽고 나면 페이지가 어떻게 읽히고 쓰이는지의 모델이 머리에 다 들어온다. 나머지 넷은 코어 길이 비껴가거나(LOB, ehash) 그 위에 투명하게 얹히는(오버플로, TDE) 곁가지를 하나씩 채운다.
섹션 안에서 가로지르는 관심사
섹션 제목: “섹션 안에서 가로지르는 관심사”세 가지 약속이 다이어그램의 모든 층을 가로질러 흐른다. 세부 문서마다 다시 발견하기보다, 섹션 차원에서 한 번 호명해 두면 좋다.
latch 규율. 페이지 버퍼는 BCB마다 사용자 정의 RW/flush latch를 내건다(PGBUF_LATCH_READ, PGBUF_LATCH_WRITE, PGBUF_LATCH_FLUSH). 스토리지 엔진 안에서 페이지 단위 latch는 이 하나뿐이고, 위쪽의 모든 레코드·키 계층은 페이지를 고치는 동안 이 latch를 잡고 있어야 한다. heap 매니저와 B+Tree가 같은 규율을 공유한다. heap insert는 대상 페이지에 WRITE를 잡고, 오버플로 헤드에는 READ를 걸 수 있다. B+Tree 하향은 비-leaf마다 READ를 잡고, 내려가면서 위쪽을 풀어 가다가(latch-coupling), leaf에서만 WRITE로 올린다. extendible hash도 디렉터리·버킷 페이지에 같은 도구를 쓴다. TDE는 암호화가 latch 아래 자리에서 자동으로 같은 규율을 물려받는다(BCB latch가 평문 프레임을 지키고, 암호 경계는 I/O 가장자리에 있다). 페이지 latch는 트랜잭션 락과 일부러 분리되어 있다. 짧게 잡고, BCB에 박혀 있고, isolation과는 무관하다. 자세한 내용은 cubrid-page-buffer-manager.md §Lock vs latch separation과 cubrid-lock-manager.md의 교차 참조를 본다.
WAL 참여. 이 섹션의 모든 스토리지 서브시스템은 ARIES 복구를 위한 로그 레코드를 적는다. 디스크 매니저는 섹터 예약과 볼륨 확장을 적고(RVDK_*), heap은 레코드 종류별 변경을 적고(RVHF_*), B+Tree는 노드 변경을 적고(RVBT_*), extendible hash는 디렉터리·버킷 변경을 적는다(RVEH_*). 오버플로 파일은 페이지 사슬 확장을 적고, LOB는 커밋 시 트랜잭션별 red-black 트리가 다시 굴려야 할 로케이터 상태 전이를 적는다. TDE도 간접적으로 참여한다. 페이지마다의 nonce가 결국 로그 매니저가 찍는 LSA이기 때문이다. 강제는 페이지 버퍼가 한다. 마지막 변경 로그 레코드의 LSA가 영속화되기 전에는 더티 페이지 flush를 거부한다. 실제 로그 인프라는 이 섹션 바깥의 cubrid-log-manager.md와 cubrid-prior-list.md에 있지만, 여기 있는 모든 층은 그 인프라의 1급 시민이다. 복구(3-패스 ARIES; cubrid-recovery-manager.md)는 그 레코드들을, 그것을 만들어 낸 그 페이지 버퍼 위에서 다시 굴린다.
MVCC 통합. CUBRID는 MVCC 엔진이고, MVCC가 물리적으로 사는 곳은 heap 매니저다. heap 레코드 헤더마다 insert-MVCCID, delete-MVCCID, 그리고 같은 heap의 이전 물리 버전을 가리키는 prev-version 포인터가 들어 있다. B+Tree는 MVCC 헤더 없이 OID만 담고 있다가, 가시성 판정이 OID를 따라 heap으로 들어갈 때 heap의 헤더에 의지한다. 카탈로그와 시스템 테이블도 heap 파일에 살기 때문에 같은 관례를 그대로 받는다. vacuum(cubrid-vacuum.md)은 WAL을 재생 순서로 따라가며 이 헤더들을 읽고, 가장 오래된 활성 MVCCID 워터마크를 기준으로 죽은 버전을 가려 슬롯을 물리적으로 회수한다. 이 회수도 결국 heap 페이지 변경이라, WRITE latch를 잡고 자기 RVHF_* 레코드를 적는다. LOB 정리는 cubrid-lob.md의 red-black 트리 디스패치를 굴리는 그 커밋/롤백 훅에 같이 올라탄다. MVCC 어휘 자체는 cubrid-mvcc.md의 영토이고, 이 섹션이 더하는 몫은 그 어휘의 on-page 구현이다.
개별 문서 요약
섹션 제목: “개별 문서 요약”| 문서 | 한 줄 요약 |
|---|---|
cubrid-disk-manager.md | 4계층 위계(OS 파일 = 볼륨, 64페이지 섹터 = 할당 단위, 파일 = 섹터 묶음, 페이지 = I/O 단위). 영구 vs 임시 디스크 캐시. 두 단계 섹터 예약. 적응형 볼륨 확장. 세 갈래 확장 가능 데이터 표(Partial / Full / User). |
cubrid-page-buffer-manager.md | BCB 배열. 쿼터를 조정할 수 있는 스레드별 private 리스트와 공유 리스트로 갈린 3-zone LRU. lock-free 큐로 victim을 대기자에게 곧장 넘긴다. BCB마다의 사용자 정의 read/write/flush latch. |
cubrid-double-write-buffer.md | 홈 쓰기 전에 fsync되는 순차 staging 볼륨 — 페이지 버퍼와 데이터 파일 사이에서 찢긴 쓰기를 막는다. 재시작 시 DWB 사본과 홈 페이지를 비교해 필요하면 교체한 뒤에야 로그 재생이 시작된다. |
cubrid-heap-manager.md | slotted 페이지. 아홉 가지 레코드 종류. INSERT/UPDATE/DELETE/READ 흐름. 레코드 헤더 안의 MVCC 버전 관리(insert-MVCCID, delete-MVCCID, prev-version 체인). 핫패스 캐시들. |
cubrid-overflow-file.md | heap의 대형 레코드와 B+Tree 오버플로 OID를 위한 페이지 사슬. FILE_MULTIPAGE_OBJECT_HEAP / FILE_BTREE_OVERFLOW_KEY / 트리별 OID 오버플로가 함께 쓰는 단일 오버플로 파일 모듈. 크래시 안전을 위한 WAL 규율. |
cubrid-lob.md | 데이터 볼륨 바깥 파일로 빠지는 BLOB/CLOB. 레코드 안의 로케이터 URI 이름표. TDES 위의 트랜잭션별 red-black 트리. 커밋/롤백에서 파일시스템과 트랜잭션 결과를 맞추는 단일 디스패치 자리. |
cubrid-btree.md | slotted 페이지 노드. 비-leaf와 leaf에 따로 쓰는 레코드 포맷. 비-유니크 인덱스의 key‖OID 결합. 읽기 길의 latch-coupling. OID 접미사 차원의 유니크 제약. 키별 OID 목록 오버플로. |
cubrid-extendible-hash.md | Fagin 식 EHID 루트 디렉터리(포인터 수가 두 배씩 자란다). 이진 탐색 + 버킷 단위 local depth를 갖춘 slotted 버킷 페이지. 시스템-op로 묶은 split / merge. RVEH_* WAL 레코드. |
cubrid-tde.md | 두 단계 키 계층(마스터 키가 데이터베이스별 DEK 셋을 감싼다). 페이지마다의 nonce를 쓰는 AES-256-CTR 또는 ARIA-256-CTR(영구 페이지는 LSA, 임시 페이지는 원자 카운터, 로그 페이지는 논리 pageid). flush 직전 암호화 / read 직후 복호화 훅. 별도 <db>_keys 마스터 키 파일. 파일 단위 TDE 플래그가 페이지 pflag 비트로 전파된다. |
인접 섹션
섹션 제목: “인접 섹션”스토리지 엔진은 cub_server 프로세스의 가장 아래 층이지만, 시스템 전체의 바닥은 아니다. 이웃한 세 섹션이 스토리지 엔진이 닿는 경계를 하나씩 맡고 있다.
- 위 — DDL과 스키마. 카탈로그와 클래스 객체. 카탈로그 매니저(
cubrid-catalog-manager.md)는 클래스마다의 디스크 표현과 통계를 CTID에 매단 heap 파일에 적어 둔다. 같이 사는 시스템 클래스(_db_class,_db_attribute,_db_index등)는 고정된 root-class OID에서 부트스트랩된다. 인메모리SM_CLASS그래프(cubrid-class-object.md)가 그 카탈로그를 클라이언트 워크스페이스로 끌어와 살아 있는 모양으로 만든다. 이 섹션의 heap 매니저가 바이트를 잡고 있고, DDL과 스키마 섹션이 그 바이트를 해석한다. 전체 그림은cubrid-overview-ddl-schema.md로 간다. - 위 — 트랜잭션과 복구. 로그, vacuum, 체크포인트, 복구. 이 섹션의 모든 더티 페이지는 로그 매니저가 만들어 둔 LSA를 통과해야 한다. 모든 재시작이 같은 페이지 버퍼 위에서 다시 굴러간다. vacuum은 WAL을 따라가며 heap 매니저의 레코드 헤더로 죽은 버전을 회수한다. DWB 복구 핸드셰이크는 로그 재생이 시작되기 전에 끝난다. 스토리지 엔진은 WAL이 지키는 바닥이고, 트랜잭션과 복구 섹션은 그 바닥을 지키는 프로토콜이다.
cubrid-overview-txn-recovery.md로 간다. - 위 — 서버 아키텍처. 로케이터(
cubrid-locator.md)가 스토리지 엔진과 위쪽 계층 사이에 걸린 단 하나의 이름 붙은 다리다. 클라이언트 측 워크스페이스가 더티 객체를LC_COPYAREA버퍼에 모아 서버로 부친다. 서버 쪽locator_*_force가족이 표준 입구 한 자리에서 출발해 heap, btree, lock, log, FK, 복제로 갈라진다. 트리거와 무결성 규칙도 이 자리에서 발화된다. 스토리지 엔진의 시점에서 보면, 모든 변경 호출은 결국 로케이터를 거쳐 들어온다.
섹션 사이의 경계는 일부러 또렷하게 그어 두었다. SELECT가 heap으로 들어가는 길, COMMIT이 WAL을 통과하는 길, DDL이 카탈로그로 가는 길을 따라가려는 독자는 이 경계를 명시적으로 넘게 된다. 각 섹션의 개요가 그 넘는 자리를 정확히 호명해 둔다.