콘텐츠로 이동

(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.cSHOWSTMT_TYPE별 start/next/end 함수 포인터가 크리티컬 섹션 상태·스레드 풀 상태·로그 헤더 필드·페이지 버퍼 카운터를 읽어 즉석에서 튜플을 합성한다. SQL 나머지(SHOW 결과에 대한 술어, 투영, 정렬, 조인)가 그대로 작동하게 만드는 트릭은 — leaf가 다른 모든 스캔 연산자와 균일하다는 것이다. 그래서 실행기는 threads가 진짜 테이블이 아니라는 사실을 끝까지 모른다.

두 절반은 코드 수준에서 독립적이다(정적 표면은 SHOW를 부르지 않고, SHOW는 런타임 메모리만 읽지 정적 카탈로그 테이블은 읽지 않는다). 작업 대상이 무엇이냐로 골라라.

  1. DDL / 스키마 / 질의 최적화를 읽고 있다면 cubrid-system-catalog-classes.md부터. 24개 시스템 클래스와 22개 시스템 뷰는 다른 거의 모든 문서(DDL 실행, 옵티마이저, 인증, 파티션, 트리거, PL 패밀리)에서 참조된다. _db_class, _db_attribute, _db_auth가 SQL 테이블로 어떻게 생겼는지 아는 것이 기초다.
  2. 라이브 시스템을 디버깅하고 있다면 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.mdcubrid-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.so blob을 참조하기 때문이다. 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.cSHOWSTMT_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.mdcubrid-query-executor.md에서 다룬다.
  • 서버 아키텍처. boot_srcreatedb 시점에 정적 표면을 설치하기 위해 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 참조.