(KO) CUBRID 베이스 / 인프라 — 섹션 개요
목차
이 섹션이 다루는 범위
섹션 제목: “이 섹션이 다루는 범위”베이스 / 인프라 섹션은 src/base/ 디렉터리에 있는 CUBRID 소스
모듈을 묶는다. 스토리지 엔진, 쿼리 처리기, 트랜잭션·복구, PL 모듈
위쪽의 모든 레이어가 이 코드 위에 올라가 있다. 어느 한 레이어에
속한 부품이 아니라, 레이어들이 합성에 쓰는 받침대다.
크게 두 갈래다.
- 커스텀 메모리 할당기. OS
malloc과 엔진 핫패스 사이에 끼어 있는 자체 할당기들. 스레드별 할당을 전역 free-list에서 떼어 내고, 같은 크기 객체를 슬랩 풀에서 재활용한다. - 락프리 자료구조. 페이지 버퍼, 락 매니저, MVCC 테이블, vacuum, CDC를 묶는 동시성 구조물. 한 개의 트랜잭션 회수 척추 위에 올라타 있어, 은퇴된 노드를 잠금 없이도 안전하게 해제할 수 있다.
두 갈래 모두 인프라라고 부르는 이유는, 다른 어떤 서브카테고리의
상세 문서도 이쪽으로 거슬러 오지 않고는 자체적으로 닫혀 있을 수
없기 때문이다. 할당기 군은 모든 서브시스템이 쓰는 C·C++ 힙을
받쳐 주고, 락프리 군은 부하 환경에서 동시 읽기를 지탱하는 모든
테이블을 받쳐 준다. 예전에 AREA가 있던 자리(subcategory: storage-engine)와, 락프리 6개 문서가 묶이지 않은 채 떠다니던
자리에서 둘을 모두 빼와서 한 subcategory: base-infra로 합친
이유는, 그 분류가 소스 트리의 src/base/ 디렉터리와 1:1로 맞고
인프라 부품들이 모일 자리를 목차에 마련해 주기 때문이다.
기반 구조
섹션 제목: “기반 구조”flowchart TB
subgraph CONSUMERS["소비자 (다른 모든 섹션)"]
STORAGE["storage-engine<br/>page-buffer, heap, btree, ehash, ..."]
QP["query-processing<br/>parser, optimizer, executor, list-file, ..."]
TX["txn-recovery<br/>mvcc, lock-manager, log-manager, vacuum, ..."]
PL["pl-language<br/>cub_pl, JavaSP, PL/CSQL"]
end
subgraph LFREE["락프리 자료구조"]
LFOVER["cubrid-lockfree-overview.md<br/>(지도 + 회수 척추)"]
LFTX["cubrid-lockfree-transaction.md"]
LFHM["cubrid-lockfree-hashmap.md"]
LFFL["cubrid-lockfree-freelist.md"]
LFCQ["cubrid-lockfree-circular-queue.md"]
LFBM["cubrid-lockfree-bitmap.md"]
end
subgraph ALLOC["커스텀 할당기"]
AREA["cubrid-common-area.md<br/>(AREA 슬랩 풀)"]
PRIV["cubrid-private-allocator.md<br/>(스레드별 Lea 힙 +<br/>C++ STL 래퍼)"]
end
subgraph OS["OS 계층"]
MALLOC["malloc / free"]
end
CONSUMERS --> LFREE
CONSUMERS --> ALLOC
AREA --> LFBM
AREA --> PRIV
PRIV --> MALLOC
LFREE -.-> PRIV
classDef section fill:#eef,stroke:#88a
class LFREE,ALLOC section
세 가지 성질이 눈여겨볼 만하다.
- AREA는 private 할당기와 락프리 비트맵에 의존한다. AREA의
블록 단위 빈자리 추적기가
lockfree::bitmap이다(둘을 같은 섹션에 두는 이유는 문서 정리상의 편의이기도 하지만, 실제로 엮여 있는 코드를 그대로 반영한 것이기도 하다). AREA의 블록 배열 자체는 SERVER_MODE에서 private 할당기로 잡는다. - 락프리 자료구조는 할당기와 독립이다. 노드 할당은 대부분
freelist의 백버퍼 블록 할당기로 자체 처리하고
(
cubrid-lockfree-freelist.md), 일부는 직접new또는db_private_alloc을 부른다. 이 군을 하나로 묶는 것은 회수 척추(cubrid-lockfree-transaction.md)이지 할당기가 아니다. - OS 계층은 그냥
malloc/free다. CUBRID는tcmalloc,jemalloc,mimalloc같은 외부 할당기를 끼우지 않는다. 스레드별 아레나 이야기는 Doug Lea의dlmalloc이 대신 맡는다. 이 코드는customheaps아래 자체 사본으로 들어와 있고, 워커 스레드마다 한 개씩 인스턴스화된다.
읽는 순서
섹션 제목: “읽는 순서”cubrid-private-allocator.md— 스레드별 Lea 힙,cubmem::private_allocator<T>STL 래퍼, 빌드 모드별 라우팅(SERVER / SA / CS). 이걸 먼저 읽어라. 다른 모든 부품이 직접 또는 간접으로 이 위에 할당하기 때문이다.cubrid-common-area.md— 고정 크기 객체용 슬랩 풀 (DB_VALUE,TP_DOMAIN등). private 힙을 백킹 스토리지로 쓰고, 락프리 비트맵을 블록별 빈자리 추적기로 쓰므로 둘을 먼저 본 뒤에 읽으면 자연스럽다.cubrid-lockfree-overview.md— 락프리 자료구조 지도와 회수 척추 개요. 개별 문서를 읽기 전에 이걸 먼저.cubrid-lockfree-transaction.md— 회수 척추. 비트맵, freelist, hashmap, circular queue가 모두 이 위에 올라간다.- 그다음은 주제에 따라 골라 읽으면 된다
(
cubrid-lockfree-bitmap.md,cubrid-lockfree-freelist.md,cubrid-lockfree-hashmap.md,cubrid-lockfree-circular-queue.md).
상세 문서 요약
섹션 제목: “상세 문서 요약”| 문서 | 요약 |
|---|---|
cubrid-private-allocator.md | 스레드별 Lea-힙 아레나(Doug Lea의 dlmalloc을 customheaps 아래 자체 사본으로 두고 THREAD_ENTRY마다 한 개씩 등록). db_private_alloc / _free / _realloc 매크로가 SERVER_MODE에서는 스레드의 힙으로, CS_MODE에서는 워크스페이스로, SA_MODE에서는 PRIVATE_MALLOC_HEADER 태그를 단 디스패치로 갈래를 나눈다. C++ STL 래퍼 cubmem::private_allocator<T>로 STL 컨테이너도 같은 힙을 쓰게 만들고, private_unique_ptr<T>와 PRIVATE_BLOCK_ALLOCATOR가 편의 계층을 채운다. |
cubrid-common-area.md | 슬랩 스타일 풀 할당기 — 256개짜리 BLOCKSET 배열을 사슬로 잇고, 각 블록은 고정 크기 셀로 채우며, 블록 앞에 락프리 비트맵을 두고, 흔한 경우는 hint 포인터 한 번으로 끝낸다. DB_VALUE, TP_DOMAIN, OBJ_TEMPLATE, set 객체 등을 받친다. |
cubrid-lockfree-overview.md | CUBRID 락프리 자료구조 지도 — legacy C lock_free.{h,c} 계열과 신형 C++ lockfree::* 네임스페이스가 한 개의 트랜잭션 회수 척추 위에 어떻게 올라타는지. |
cubrid-lockfree-transaction.md | system / table / descriptor / address-marker 회수 — 자료구조마다 트랜잭션 id 한 개, 스레드별 descriptor가 읽기 구간을 묶고, 주기적으로 가장 작은 살아 있는 id를 스캔해 freelist에 어느 노드를 풀어 줘도 되는지 알려준다. |
cubrid-lockfree-bitmap.md | 청크 단위 어토믹 비트맵 — std::atomic<unsigned int> 청크들, 두 가지 청크 스타일(고정 한 청크 사용, 청크 리스트 사용), CAS 비트 플립, SERVER_MODE에서 get_entry마다 어토믹으로 진행하는 라운드로빈 시작점 힌트. |
cubrid-lockfree-circular-queue.md | 두 개의 커서 어토믹과 슬롯별 블록 플래그 워드를 가진 고정 용량 MPMC 링. vacuum 로그 블록 분배, 페이지 버퍼 victim 핸드오프, CDC 로그 정보 전달에 쓰인다. |
cubrid-lockfree-freelist.md | 타입드 freelist<T> — 사용 가능 스택 한 개와, 동시 요청자가 할당 경쟁을 하지 않게 lazy로 갈아 끼우는 백버퍼 블록 한 개, 페이로드 타입이 구현하는 on_reclaim 훅, 그리고 백버퍼 시간으로 ABA 윈도우가 명시적으로 제한된 pop 경로. |
cubrid-lockfree-hashmap.md | Harris–Michael 체인 해시 — 옵션으로 엔트리별 뮤텍스를 두며, legacy C lf_hash_*와 신형 C++ lockfree::hashmap<K,T> 두 구현이 cubthread::lockfree_hashmap<K,T> 다리로 묶여 있다. m_type ∈ {OLD, NEW}은 init 시점에 PRM_ID_ENABLE_NEW_LFHASH가 결정한다. |
인접 섹션
섹션 제목: “인접 섹션”cubrid-overview-storage-engine.md— 페이지 버퍼, 힙, B+Tree, extendible 해시, double write buffer, LOB, TDE. 스토리지의 모든 레이어가 private 할당기로 메모리를 잡고, 페이지 버퍼와 락 매니저가 락프리 부품을 쓴다. AREA는 원래 이 섹션에 있었지만 메모리 할당기 부품으로 빼서 이쪽에 옮겼다. 어느 한 레이어에 종속되지 않고 모든 레이어가 같이 쓰기 때문이다.cubrid-overview-server-architecture.md— 스레드 풀, 커넥션 풀, 에러 관리, 시스템 파라미터, 모니터링. 스레드 풀의 엔트리 (cubthread::entry)가private_heap_id를 들고 있다. 에러, 파라미터, 모니터링도src/base/받침대지만, 네트워크 스택 및 broker와도 엮여 있어 일단server-architecture에 두었다. 나중에 분류 경계가 다시 그어지면 이쪽으로 넘어올 수 있다.cubrid-architecture-overview.md§Cross-cutting infrastructure 코드 분석 트리 전체의 정문 라우터. 베이스/인프라를 다른 cross-cutting 부품들과 함께 한 단락으로 묶어 둔 곳.cubrid-design-philosophy.md—tcmalloc/jemalloc대신 자체dlmalloc사본을 쓰는 역사적 사연.