(KO) CUBRID 시스템 카탈로그 — 섹션 개요
CUBRID 시스템 카탈로그 — 섹션 개요
섹션 제목: “CUBRID 시스템 카탈로그 — 섹션 개요”이 섹션에서 다루는 것
섹션 제목: “이 섹션에서 다루는 것”관계형 엔진은 자기 자신을 자기 자신에게, SQL으로 기술해야 한다. 사용자(또는 엔진)가 던지는 자기-기술 질문은 두 종류다.
- 정적 — 스키마. 어떤 클래스가 있고, 어떤 컬럼을 가지며, 어떤 인덱스가 걸려 있고, 누가 소유주이며, 어떤 권한이 있는가? 이 답은 시스템 카탈로그 클래스가 한다 —
_db_class,_db_attribute,_db_index,_db_auth, … — 스키마 객체 하나당 한 행을 담는 실제 heap 테이블, 그리고 그 위에 얹혀 같은 데이터를 SQL 클라이언트용으로 재조형하는 시스템 뷰(db_class,db_attribute, …) 레이어. 행은 DDL이 쓰고, 모든 plan compile이 읽는다. - 동적 — 런타임 상태. 어느 스레드가 블록됐는가? 페이지 버퍼는 얼마나 차 있는가? 로그 tail은 어디인가? 어떤 락이 잡혀 있는가? 이 답은 SHOW 명령이 한다 —
SHOW THREADS,SHOW PAGE BUFFER STATUS,SHOW LOG HEADER— 디스크에는 행이 존재하지 않고, 질의가 그 관계를 건드릴 때마다 서버 메모리에서 즉시 합성되는 행들.
이 섹션이 둘을 함께 묶는 이유는 둘이 하나의 일관된 표면이기 때문이다. 사용자가(또는 엔진 자신이) 이 데이터베이스 안에서 무슨 일이 벌어지는지 묻는 모든 질문은 어떤 테이블처럼 생긴 것 안의 어떤 행으로 답해진다. 그리고 실행기는 두 종류 모두에 동일한 스캔 연산자로 닿는다. 정적 표면과 동적 표면은 같은 아이디어 — SQL을 통한 자기-기술 — 를 두 가지 시간 지평에 적용한 결과다.
flowchart TB
subgraph staticcat["정적 표면 — SQL에서 보이는 시스템 클래스"]
DEF["system_catalog_definition<br/>(클래스별 메타-스키마:<br/>attribute, constraint,<br/>grant, row_init)"]
INST["catcls_install<br/>(createdb 시점 3-패스 부트스트랩)"]
SYSCL["_db_class, _db_attribute,<br/>_db_index, _db_auth, ...<br/>+ db_class, db_attribute,<br/>... 22개 시스템 뷰"]
DEF --> INST --> SYSCL
end
subgraph dynamiccat["동적 표면 — 질의 시점에 합성"]
REWRITE["SHOW name<br/>=> SELECT * FROM<br/>(PT_SHOWSTMT)"]
SCAN["S_SHOWSTMT_SCAN<br/>(가상 스캔 연산자)"]
SYNTH["SHOWSTMT_TYPE별<br/>start / next / end<br/>(스레드 상태,<br/>페이지 버퍼 카운터,<br/>로그 헤더, 락, ... 읽기)"]
REWRITE --> SCAN --> SYNTH
end
EXEC["Executor scan_next_scan 루프<br/>(균일: 힙, B+Tree, 리스트,<br/>JSON-table, SHOW, 모든 leaf)"]
SYSCL --> EXEC
SYNTH --> EXEC
이 섹션은 시스템 클래스를 받쳐 주는 온-디스크 카탈로그 포맷을 다루지 않는다 — OR_CLASSREP, CTID, 전용 카탈로그 heap은 DDL과 스키마의 cubrid-catalog-manager.md다. catalog-manager는 시스템 클래스가 올라타는 저장소고, 이 섹션은 SQL 표면이 보는 façade다. 둘의 경계는 — _db_class는 attributes와 constraints를 가진 실제 CUBRID 클래스(이 섹션의 영역)이고, 그 행의 디스크 위 바이트는 전용 카탈로그 heap의 OR_CLASSREP 레코드로 인코딩되어 있다(DDL과 스키마의 영역).
두 절반
섹션 제목: “두 절반”정적 표면 — cubrid-system-catalog-classes.md. CUBRID이 SQL에서 보이는 시스템 클래스 가족(_db_class, _db_attribute, _db_index, _db_auth, …)을 데이터 주도 프레임워크로 어떻게 정의·부트스트랩하는지에 대한 분석. 클래스마다 cubschema::system_catalog_definition 값으로 인코딩되고(attributes + constraints + grants + 선택적 row initializer), 단일 system_catalog_builder가 그 값을 소비해 db_create_class -> smt_add_attribute -> sm_update_class -> constraint/grant를 발급한다 — 사용자 CREATE TABLE이 타는 것과 같은 DDL 프리미티브다. 시스템 뷰(db_class, db_attribute, …)는 query spec을 SQL 문자열 리터럴로 들고 다니다가 두 번째 패스에서 db_add_query_spec으로 설치된다. install 전체는 root-class 앵커를 createdb 시점에 한 번 돌고, 그 후 잠든다.
동적 표면 — cubrid-show-commands.md. CUBRID가 서버 내부 런타임 상태(볼륨 헤더, 로그 헤더, 힙·B+Tree 용량, 크리티컬 섹션, 스레드, 페이지 버퍼, 트랜잭션 테이블, 타임존)를 어떻게 SQL로 질의 가능한 가상 테이블로 노출하는지. 파이프라인은 균일하다. 파서가 SHOW <name>을 SELECT * FROM (PT_SHOWSTMT)로 다시 쓰고, 옵티마이저가 TARGET_SHOWSTMT로 access spec을 만들고, 실행기가 S_SHOWSTMT_SCAN을 열고, show_scan.c의 SHOWSTMT_TYPE별 start/next/end 함수 포인터가 크리티컬 섹션 상태·스레드 풀 상태·로그 헤더 필드·페이지 버퍼 카운터를 읽어 즉석에서 튜플을 합성한다. SQL 나머지(SHOW 결과에 대한 술어, 투영, 정렬, 조인)가 그대로 작동하게 만드는 트릭은 — leaf가 다른 모든 스캔 연산자와 균일하다는 것이다. 그래서 실행기는 threads가 진짜 테이블이 아니라는 사실을 끝까지 모른다.
읽는 순서
섹션 제목: “읽는 순서”두 절반은 코드 수준에서 독립적이다(정적 표면은 SHOW를 부르지 않고, SHOW는 런타임 메모리만 읽지 정적 카탈로그 테이블은 읽지 않는다). 작업 대상이 무엇이냐로 골라라.
- DDL / 스키마 / 질의 최적화를 읽고 있다면
cubrid-system-catalog-classes.md부터. 24개 시스템 클래스와 22개 시스템 뷰는 다른 거의 모든 문서(DDL 실행, 옵티마이저, 인증, 파티션, 트리거, PL 패밀리)에서 참조된다._db_class,_db_attribute,_db_auth가 SQL 테이블로 어떻게 생겼는지 아는 것이 기초다. - 라이브 시스템을 디버깅하고 있다면
cubrid-show-commands.md부터. SHOW는 런타임에 손이 가는 진단 표면이다. 정적 카탈로그가 어떻게 동작하는지(같은 아이디어가 스키마에 적용된 것)를 알고 나면 SHOW 파이프라인은 같은 자기-기술 트릭, 다만 일시 상태에 적용으로 보인다.
시스템 클래스의 구현(예: _db_class의 행이 디스크에 어떻게 들어가는가?)을 읽고 있다면, 그건 DDL과 스키마의 cubrid-catalog-manager.md다 — 정적-표면 문서를 먼저 읽은 뒤에 보라, catalog-manager 문서는 _db_class가 무엇인지 안다고 가정한다.
횡단 관심사
섹션 제목: “횡단 관심사”- 둘 다 실행기의 스캔 레지스트리로 표면화된다.
cubrid-system-catalog-classes는 진짜 클래스를 빌드하고, 그 행은 카탈로그 힙에 살므로, 읽기는 표준S_HEAP_SCAN을 탄다.cubrid-show-commands는 동일한SCAN_TYPE레지스트리에S_SHOWSTMT_SCAN을 추가하는데, 이 레지스트리는 힙·리스트·B+Tree·집합·메서드·JSON-table 스캔이 함께 사는 곳이다. 실행기 입장에서 둘 다 평범한 leaf라서 술어, 투영, 정렬, 조인, 집계가 균일하게 작동한다.cubrid-scan-manager.md와cubrid-query-executor.md참조. - 정적 카탈로그는
createdb에 한 번 쓰이고, 이후로는 사용자 DDL이 내용을 쓴다. 24개 클래스 메타-스키마는createdb이 심는 root-class 앵커를catcls_install이 정확히 한 번 설치한다. 그 이후로는 모든 사용자CREATE TABLE이_db_class/_db_attribute/_db_index에 행을 추가하고, 모든ALTER가 그것을 갱신하고,DROP이 삭제한다. DDL 파이프라인(cubrid-ddl-execution.md)과 인메모리 스키마 그래프(cubrid-class-object.md)가 소비자이자 작성자다 — 이 섹션의 정적-표면 문서는 그들이 읽고 쓰는 테이블의 정의다. - SHOW 명령이 다른 모든 서브시스템의 내부 상태를 노출한다. SHOW THREADS는 워커 풀(
cubrid-thread-worker-pool.md,cubrid-thread-manager-ng.md)을 읽는다. SHOW LOG HEADER는 로그 매니저(cubrid-log-manager.md)를. SHOW PAGE BUFFER STATUS는 페이지 버퍼 매니저(cubrid-page-buffer-manager.md)를. SHOW LOCKS는 락 매니저(cubrid-lock-manager.md)를. SHOW TRAN TABLES는 트랜잭션 서브시스템(cubrid-transaction.md)을. SHOW TIMEZONES는 로딩된 타임존 라이브러리(cubrid-timezone.md)를. 횡단으로 읽는 독자에게 SHOW는 실질적으로 엔진의 나머지 부분을 발견하는 표면이다. - 정적 카탈로그와 SHOW가
_db_collation/_db_charset데이터를 공유한다. i18n 기본 요소는 두 번 표면화된다 — createdb에 설치되는_db_charset/_db_collation행으로(이 섹션, 정적 표면), 그리고 질의 시점에 합성되는SHOW LOCALES/SHOW COLLATION으로(이 섹션, 동적 표면). 두 읽기는 일치한다 — 둘 다 결국 서버 부팅 시 로딩된 같은libcubrid_collations.soblob을 참조하기 때문이다.cubrid-charset-collation.md참조. - 온-디스크 카탈로그가 두 절반을 모두 받쳐 준다.
_db_class행은cubrid-catalog-manager.md에서 다루는 전용 카탈로그 heap에 산다. SHOW는 저장에 쓰지는 않지만, 저장에 사는 서브시스템(페이지 버퍼, 로그 매니저)의 내부 상태를 읽는다. 경계는 의도적이다 — 이 섹션은 SQL 표면 façade, 저장은cubrid-catalog-manager(DDL과 스키마)와 서브시스템별 세부 문서.
세부 문서 요약
섹션 제목: “세부 문서 요약”| 문서 | 표면 | 한줄 요약 |
|---|---|---|
cubrid-system-catalog-classes.md | 정적 | _db_class, _db_attribute, _db_index, …을 정의·부트스트랩하는 데이터 주도 프레임워크. 24개 클래스 + 22개 뷰가 각각 system_catalog_definition 값으로 인코딩되고 단일 system_catalog_builder가 createdb에서 install. 시스템 뷰는 바이너리에 컴파일된 SQL 문자열 리터럴 query spec을 들고 다닌다. |
cubrid-show-commands.md | 동적 | SHOW <name>을 SELECT * FROM (PT_SHOWSTMT)로 재작성; S_SHOWSTMT_SCAN 가상 스캔; show_scan.c의 SHOWSTMT_TYPE별 start/next/end 함수 포인터가 서버 내부 상태(스레드, 래치, 페이지 버퍼, 로그 헤더, 트랜잭션 테이블, 타임존)에서 즉석에서 튜플을 합성. |
인접 섹션
섹션 제목: “인접 섹션”- DDL과 스키마. 시스템 클래스를 받쳐 주는 온-디스크 카탈로그 포맷(
OR_CLASSREP,CLS_INFO,CTID, 전용 카탈로그 힙, 통계)은cubrid-catalog-manager.md에 산다. 사용자 클래스 행을_db_class에 쓰는 DDL 파이프라인은cubrid-ddl-execution.md다. plan compile마다_db_class행을 소비하는 인메모리SM_CLASS그래프는cubrid-class-object.md다. 스키마 변경의 전체 그림을 보려면 그 셋을 이 섹션의 정적-표면 문서와 함께 읽어라 — DDL이 행을 쓰고, catalog-manager가 그것을 저장하고, 이 섹션이 그 행이 사는 테이블을 정의한다. - 질의 처리. 컴파일된 모든 질의는 정적 카탈로그를 읽는다(
_db_class행을SM_CLASS그래프로 풀고, 카디널리티 추정을 위해 통계를 조회). 사용자가 SHOW를 던지거나 가상 테이블에 질의하면 동적 카탈로그도 읽는다. 카탈로그 클래스 읽기에S_HEAP_SCAN을, SHOW에S_SHOWSTMT_SCAN을 호스트하는 스캔 매니저 디스패치 테이블은cubrid-scan-manager.md와cubrid-query-executor.md에서 다룬다. - 서버 아키텍처.
boot_sr이createdb시점에 정적 표면을 설치하기 위해catcls_init+catcls_install을 한 번 호출한다 —cubrid-boot.md참조. SHOW 명령은 거의 모든 서버 아키텍처 서브시스템의 내부 상태를 직접 노출한다(위 횡단 관심사 목록 참조). 카탈로그 읽기를 페이지화하는 로케이터의 MOP 테이블은cubrid-locator.md다. - 저장 엔진. 카탈로그·시스템 클래스 행은 힙 행이고, SHOW는
cubrid-page-buffer-manager.md,cubrid-log-manager.md,cubrid-lock-manager.md의 내부 상태를 직접 읽는다 — 이 서브시스템들이 평소에 숨고 있는 SQL 표면을 우회한다. - 국제화. 두 i18n 기본 요소 모두 이 섹션으로 표면화된다 — 정적으로는
_db_charset/_db_collation행으로, 동적으로는SHOW LOCALES/SHOW COLLATION/SHOW TIMEZONES/SHOW FULL TIMEZONES로.cubrid-overview-i18n-specialty.md참조.