(KO) CUBRID 시스템 파라미터 — 튜닝 레지스트리, conf/env/URL 파싱, 세션별 범위 지정
목차
학술적 배경
섹션 제목: “학술적 배경”관계형 DBMS는 수백 개의 조정 가능한 값을 갖는다. 버퍼 풀 크기, 로그 버퍼 크기, 락 타임아웃, 기본 격리 수준, 오류 로그 심각도, 체크포인트 주기, 문자 집합, 시간대까지 — 각 서브시스템이 고유한 값 묶음을 가져온다. 설정 서브시스템은 그 값들에 이름을 붙이고, 타입을 정하고, 기본값을 지정하고, 외부 소스로부터 덮어쓰고, 요청이 들어오면 엔진의 나머지 부분에 되돌려 주는 곳이다. 거의 모든 다른 모듈이 이 모듈을 호출한다는 점에서, 이 서브시스템은 비용이 낮고, 예측 가능하며, 엔진 내부에서는 이례적인 수준의 타입 안전성을 갖춰야 한다.
구현 방식을 결정하는 세 가지 속성이 있다.
- 중앙 레지스트리. 모든 파라미터는 이름, 타입, 기본값, 선택적 범위, 그리고 행동 플래그 집합(클라이언트 쪽인가, 서버 쪽인가, 양쪽 다인가? 사용자가 온라인으로 바꿀 수 있는가? 재시작이 필요한가? deprecated인가?)을 갖는다. 레지스트리는 모든 파라미터에 대한 답을 아는 유일한 장소이며, 파라미터를 추가할 때 손을 대야 하는 유일한 장소다.
- 여러 소스, 우선순위 순서. 일반적인 엔진은 레지스트리 기본값에서
시작해, 설정 파일, 프로세스 환경, 연결 시점 인자, 런타임 SQL(
SET문) 순으로 읽는다. 나중의 소스가 앞선 것을 덮어쓴다. 사용자가SET문에 직접 입력한 가장 구체적인 소스가 이겨야 한다는 기대 때문에 이 순서는 중요하다. - 서버 전역 범위 vs. 세션 범위. 일부 파라미터는 전역적이다. 서버의
물리적 상태(버퍼 풀, 로그 버퍼, 포트 번호, 최대 클라이언트 수)를
기술하며, 서버 재시작이나 DBA 권한의 명령으로만 바꿀 수 있다. 다른
파라미터는 세션 범위다. 현재 클라이언트가 자신의 쿼리를 어떻게
동작시키길 원하는지(격리 수준, 시간대, 옵티마이저 예약, 이 세션의
오류 로그 심각도)를 기술하며, 단일 클라이언트의
SET SYSTEM PARAMETERS는 그 클라이언트의 세션에만 영향을 줘야 한다. 설정 서브시스템은 어느 파라미터가 어느 쪽인지 알고, 읽기/쓰기를 적절히 라우팅할 책임을 진다.
교과서적 설명은 빈약하다. Database Internals(Petrov)는 이 주제를 건너
뛰고, Tom Lane의 PostgreSQL 논문 “PostgreSQL’s Configuration Engine”이
가장 가까운 정식 참조이다. 그 논문의 핵심 통찰은 파라미터 목록 자체가
나머지 엔진이 컴파일 기준으로 삼는 타입이 검사된 심볼 테이블이라는 것이다.
운영체제 문헌에서도 커널 튜너블(sysctl, MIB) 이라는 이름으로 같은
패턴이 등장한다. 핫 경로에서 수백 개의 호출자가 읽고, 결국 열거형을 키로
하는 타입 지정 슬롯 테이블과 인라인 접근자라는 동일한 관용구로 수렴한다.
구현 자유도는 다음에 있다. 타입 체계(CUBRID는 int/float/bool/string에
더해 2 GiB를 넘는 바이트 카운트를 위한 BIGINT, 이름 있는 열거형 값을
위한 KEYWORD, INTEGER_LIST를 추가한다), 기본값-현재값 쌍(CUBRID는
슬롯마다 둘 다 저장해 덤프 루틴이 한 번의 비교로 drift를 표시할 수
있게 한다), conf 파일 섹션 방식(CUBRID는 INI 스타일 섹션을 선택해 하나의
파일로 프로세스 수준 오버라이드와 데이터베이스별 오버라이드를 모두
처리한다), 그리고 세션별 저장소(CUBRID는 미리 계산된 세션 적격 부분
집합인 prm_Def_session_idx[]를 인덱스로 하는 희소 배열을 유지한다).
DBMS 공통 설계 패턴
섹션 제목: “DBMS 공통 설계 패턴”모든 관계형 엔진은 파라미터 아키텍처에서 거의 동일한 구조로 수렴했다. 차이는 사용자를 향한 표면의 인체공학에 있는 경우가 대부분이다.
Postgres GUC (Grand Unified Configuration). struct config_generic 위에
타입별 서브클래스(config_int, config_real, config_string, config_bool,
config_enum)를 두고, 시작 시 배열을 순회한다(ConfigureNamesInt[] 등).
각 GUC는 누가 언제 바꿀 수 있는지를 결정하는 context 열거형
(PGC_INTERNAL, PGC_POSTMASTER, PGC_SIGHUP, PGC_SUSET,
PGC_USERSET, PGC_BACKEND)을 갖는다. 읽기는 핫 경로에서 GetConfigOption()
또는 직접 포인터 접근으로 이뤄진다. pg_settings 카탈로그 뷰는 GUC 테이블의
얇은 래퍼다.
MySQL 시스템 변수. Sys_var_init()으로 등록된 sys_var 객체 레지스트리.
읽기는 세션의 경우 THD::sys_var_value(), 전역의 경우 글로벌 락을 사용한다.
SESSION / GLOBAL 분리는 SET GLOBAL, SET SESSION, SHOW VARIABLES에서
명시적으로 드러난다. 설정 파일은 [server] / [client] / [mysqld] 섹션이
있는 my.cnf다.
Oracle SPFILE/PFILE. 파라미터는 바이너리 SPFILE(영속) 또는 텍스트
PFILE(init.ora) 중 하나에 산다. ALTER SYSTEM SET ... SCOPE = MEMORY|SPFILE|BOTH 구문이 메모리 반영과 영속 저장을 결정한다. 카탈로그
뷰: v$parameter, v$spparameter.
SQLite. pragma만 있다. PRAGMA name = value. 일부는 연결별
(journal_mode, synchronous), 일부는 데이터베이스별(page_size, 생성 시
에만 설정 가능). 설정 파일 없음.
CUBRID는 사용자 표면(SQL SET SYSTEM PARAMETERS '...', INI 스타일
cubrid.conf, GLOBAL / SESSION 구분이 플래그에 암묵적으로 포함)으로는
MySQL에 가장 가깝지만, 구현(단일 prm_Def[] 타입 슬롯 배열과 인라인
getter, 컨텍스트/범위/지속성 규칙을 인코딩하는 파라미터별 플래그 워드)으로는
Postgres에 더 가깝다.
이론 ↔ CUBRID 명칭 매핑
섹션 제목: “이론 ↔ CUBRID 명칭 매핑”| 이론적 개념 | CUBRID 명칭 |
|---|---|
| 파라미터 ID 열거형 | enum param_id / PARAM_ID (system_parameter.h) |
| 파라미터별 슬롯 | struct sysprm_param / SYSPRM_PARAM (system_parameter.h) |
| 레지스트리 배열 | prm_Def[] (system_parameter.c) |
| 타입 태그 | SYSPRM_DATATYPE (int/float/bool/keyword/bigint/string/intlist) |
| 정적(컴파일 타임) 플래그 워드 | SYSPRM_PARAM::static_flag (PRM_FOR_CLIENT, PRM_FOR_SERVER, …) |
| 동적(런타임) 플래그 워드 | SYSPRM_PARAM::dynamic_flag (PRM_SET, PRM_ALLOCATED, …) |
| 태그 있는 값 | SYSPRM_PARAM_VALUE { is_null, v } over SYSPRM_VALUE union |
| 기본값-현재값 쌍 | default_value and value fields side-by-side |
| 범위 | lower_limit, upper_limit |
| 강제 오버라이드 | force_value (string) + prm_set_force |
| 단위 변환기 | set_dup / get_dup callbacks |
| conf 파일 로더 | sysprm_load_and_init → prm_read_and_parse_ini_file |
| 섹션 디스패처 | prm_load_by_section |
| 환경 변수 오버라이드 | prm_check_environment (대문자로 변환 후 envvar_get) |
| 파라미터 간 조율 | prm_tune_parameters (로드 후 실행) |
| 복합 파라미터 | PRM_COMPOUND flag + prm_set_compound (예: compat_mode) |
| 별칭 파라미터 쌍 | PARAM_VALUE_SHARE[] table + sysprm_find_shared_system_parameter |
| 세션 범위 부분 집합 | PRM_FOR_SESSION flag + prm_Def_session_idx[] |
| 세션별 값 배열 | SESSION_PARAM array on SESSION_STATE::session_parameters |
| 세션별 getter 우회 | prm_get_value / PRM_SERVER_SESSION macro |
| 런타임 변경 목록 | SYSPRM_ASSIGN_VALUE linked list |
| 사용자 SQL → 레지스트리 | db_set_system_parameters → sysprm_validate_change_parameters |
| 서버 측 파라미터 변경 | xsysprm_change_server_parameters (x = server stub) |
| 연결 시 서버 강제 갱신 | PRM_FORCE_SERVER + xsysprm_get_force_server_parameters |
| 재로드 | sysprm_reload_and_init (PRM_RELOADABLE 파라미터만) |
| 최종 정리 | sysprm_final |
CUBRID의 구현
섹션 제목: “CUBRID의 구현”설정 서브시스템은 다섯 가지 움직이는 부분으로 구성된다. 모든 튜너블에 이름을 붙이는 파라미터 테이블, 기본값·conf 파일·환경·런타임 SQL에서 값을 끌어오는 결정 파이프라인, 세션이 다른 세션에 영향 없이 파라미터 부분 집합을 오버라이드할 수 있게 해 주는 세션별 우회 경로, 범위가 겹칠 때 클라이언트와 서버 사이에 값을 동기화하는 전파 채널, 마지막 으로 진단을 위해 테이블을 직렬화하는 덤프/출력 기계다. 이 순서대로 살펴본다.
전체 구조
섹션 제목: “전체 구조”flowchart LR
subgraph SRC["외부 소스"]
DEF["컴파일 타임<br/>기본값<br/>(prm_Def[].default_value)"]
CONF["cubrid.conf<br/>(INI 섹션)"]
HACONF["cubrid_ha.conf<br/>(HA 전용)"]
ENV["환경 변수<br/>대문자 이름"]
URL["URL / 연결<br/>파라미터 (cci/jdbc)"]
SQL["SET SYSTEM<br/>PARAMETERS '...'"]
end
subgraph LOAD["결정 경로 (system_parameter.c)"]
SLI["sysprm_load_and_init<br/>→ _internal"]
PRP["prm_read_and_parse_ini_file"]
PLBS["prm_load_by_section"]
PCE["prm_check_environment"]
PTP["prm_tune_parameters"]
end
subgraph TBL["레지스트리"]
PRM["prm_Def[] 배열<br/>PARAM_ID 인덱스"]
IDX["prm_Def_session_idx[]<br/>희소 세션 맵"]
SHARE["PARAM_VALUE_SHARE[]<br/>별칭 쌍"]
end
subgraph SCOPE["프로세스별 상태"]
GLOBAL["서버 전역 값<br/>(prm_Def[].value)"]
SESS["세션별 값<br/>(SESSION_PARAM 배열<br/>on SESSION_STATE)"]
end
subgraph READ["읽기 API"]
GETI["prm_get_integer_value (인라인)"]
GETB["prm_get_bool_value (인라인)"]
GETS["prm_get_string_value (인라인)"]
GETV["prm_get_value (세션별 우회)"]
end
DEF --> SLI
CONF --> PRP
HACONF --> PRP
PRP --> PLBS
PLBS --> SLI
ENV --> PCE
PCE --> SLI
SLI --> PTP
PTP --> PRM
PRM --> IDX
PRM --> SHARE
PRM --> GLOBAL
URL --> SQL
SQL --> SESS
SQL --> GLOBAL
GLOBAL --> GETI
GLOBAL --> GETB
GLOBAL --> GETS
SESS --> GETV
GETI --> GETV
GETB --> GETV
GETS --> GETV
파라미터 테이블
섹션 제목: “파라미터 테이블”CUBRID의 모든 튜너블은 prm_Def[] 배열(system_parameter.c:1010)의
항목 하나에 대응한다. 구조체 형태는 헤더의 SYSPRM_PARAM으로 고정되어
있다.
// sysprm_param — system_parameter.hstruct sysprm_param{ PARAM_ID id; // enum tag const char *name; // string the parser expects unsigned int static_flag; // compile-time scope/role flags SYSPRM_DATATYPE datatype; // int/float/bool/keyword/bigint/string/intlist unsigned int dynamic_flag; // runtime: SET / ALLOCATED / ... const SYSPRM_PARAM_VALUE default_value; // compile-time default SYSPRM_PARAM_VALUE value; // current value (mutated) const SYSPRM_PARAM_VALUE upper_limit; // optional bound const SYSPRM_PARAM_VALUE lower_limit; // optional bound char *force_value; // string forced from runtime API DUP_PRM_FUNC set_dup; // input -> storage unit DUP_PRM_FUNC get_dup; // storage -> display unit};세 가지 점이 특히 중요하다.
ID 열거형이 정식 기준점이다. PARAM_ID(header:97)는 prm_Def[]
초기화 순서와 동일하게 선언되며, 디버그 빌드의 온전성 검사
sysprm_check_id_order(system_parameter.c:5965의 즉시 호출 람다)는
모든 슬롯에서 GET_PRM(i)->id == i가 성립하는지 단언한다. 이 불변식
덕분에 모든 호출자는 prm_find로 이름 조회를 하지 않고도 prm_Def[id]
를 O(1)로 역참조할 수 있다. 매크로 GET_PRM(id)(header:679)는 단순히
(&prm_Def[(id)])다.
정적 플래그 워드가 정책 필드다. 소수의 비트가 엔진이 파라미터를
내리는 모든 정책 결정을 인코딩한다. PRM_USER_CHANGE(런타임 SET
허용), PRM_FOR_CLIENT / PRM_FOR_SERVER(어느 쪽이 복사본을 갖는지),
PRM_HIDDEN(덤프 시 숨김), PRM_RELOADABLE(sysprm_reload_and_init
시 초기화 가능), PRM_COMPOUND(설정 시 다른 것들에 연쇄 적용),
PRM_TEST_CHANGE(test_mode=on 상태에서만 변경 가능), PRM_FOR_HA
(cubrid_ha.conf에서 읽음), PRM_FOR_SESSION(세션 범위), PRM_FORCE_SERVER
(클라이언트는 연결 시 서버에서 가져와야 함), PRM_FOR_QRY_STRING(플랜
캐시 키에 포함), PRM_CLIENT_SESSION(클라이언트/서버 세션, 서버에 영향
없음), PRM_SIZE_UNIT / PRM_TIME_UNIT / PRM_DIFFER_UNIT(단위 처리),
PRM_FOR_HA_CONTEXT(HA 로그 적용자로 복제), PRM_GET_SERVER
(이중 범위, 서버에서 읽음), PRM_FOR_PL_CONTEXT(PL/SP 컨텍스트로 전달),
PRM_DEPRECATED, PRM_OBSOLETED가 있다.
전형적인 테이블 항목은 몇 가지 OR 연산된 플래그로 전체 정책을 인코딩한다.
data_buffer_size의 경우 static_flag = PRM_FOR_SERVER | PRM_SIZE_UNIT | PRM_DIFFER_UNIT | PRM_RELOADABLE, 타입 PRM_INTEGER, 기본값과 현재값
모두 {.i = 32768}(페이지), 상한 없음, 하한 1024 페이지,
set_dup / get_dup 콜백 prm_size_to_io_pages / prm_io_pages_to_size
로 설정된다. 이 플래그들이 의미하는 바는 “서버 전용, 입력 시 K/M/G 접미사
허용, 사람이 읽기 좋은 단위로 표시, 재로드 가능, 저장 단위는 페이지지만
사용자 표면 단위는 바이트”다. set_dup / get_dup 쌍이 그 단위 변환을
연결하는 방식이다.
기본값-현재값 쌍은 이유가 있어 중복된다. 슬롯마다 default_value와
value를 모두 저장하면 낭비처럼 보이지만, 이 덕분에
sysprm_dump_parameters(5847)가 한 번의 비교로 비기본값 항목에 표시를
달 수 있고, prm_set_default_internal(9489)이 스칼라 타입의 경우 구조체
대입 하나로(prm->value = prm->default_value;) 컴파일 타임 기준값을
복원할 수 있다.
결정 파이프라인
섹션 제목: “결정 파이프라인”전체 로더는 하나의 private 함수
sysprm_load_and_init_internal(system_parameter.c:6015)을 병목으로 한다.
이 함수는 세 개의 공개 진입점으로 호출된다. 서버 쪽의 sysprm_load_and_init,
CS/SA 클라이언트의 sysprm_load_and_init_client, 그리고 런타임 재읽기를
위한 sysprm_reload_and_init(reload=true 플래그 사용)다.
sequenceDiagram
participant Caller as boot_restart_server / boot_cl
participant SLI as sysprm_load_and_init_internal
participant Reset as PRM_RELOADABLE 초기화 루프
participant File as prm_read_and_parse_ini_file
participant Sec as prm_load_by_section
participant DefLoop as 기본값 채우기 루프
participant Env as prm_check_environment
participant Tune as prm_tune_parameters
participant Force as force_value 루프
Caller->>SLI: db_name, conf_file, load_flags
Note right of SLI: reload이면 PRM_RELOADABLE 전부 초기화
SLI->>Reset: for each prm if PRM_RELOADABLE: prm_set_default
SLI->>File: ${CUBRID}/conf/cubrid.conf 또는 $CONF_FILE
File->>Sec: section "common" (ignore_section=true)
File->>Sec: section "@<dbname>"
File->>Sec: section "service" (첫 번째 패스에서만)
Note right of File: HA 모드 켜져 있으면: cubrid_ha.conf도 로드
File->>Sec: section "%<host>|*", "%<host>|<user>"
SLI->>DefLoop: PRM_SET 없는 각 prm에 prm_set_default
SLI->>Env: 각 prm에 대해 envvar_get(대문자 이름)
SLI->>Tune: 파라미터 간 일관성 조정
SLI->>Force: force_value 있는 각 prm에 prm_set
SLI-->>Caller: NO_ERROR
로더는 세 가지 겹친 관심사를 다룬다. 어떤 파일을 읽을지, 그 파일의 어떤 섹션이 적용되는지, 값이 아직 없는 키를 어떻게 처리할지다.
어떤 파일을 읽을지. 기본은 설치 레이아웃 기준으로 envvar_confdir_file
이 결정하는 ${CUBRID}/conf/cubrid.conf다. 환경 변수 CONF_FILE이 경로를
오버라이드한다. 선택적으로 HA_CONF_FILE은 ha_mode != off일 때 HA
전용 파라미터를 위한 별도 파일을 지정한다. sysprm_load_and_init의 인자
conf_file은 호출자가 특정 경로를 주입할 수 있게 하지만, 실제로는 항상
NULL로 전달되며 내부에서 이를 단언한다.
어떤 섹션이 적용되는지. conf 파일은 INI 형식이며 ini_parser 라이브러리로
파싱되고, prm_load_by_section(system_parameter.c:6350)이 섹션마다 한 번씩
순회한다. 적용되는 섹션을 순서대로 나열하면 다음과 같다.
[common]— 모든 데이터베이스, 모든 호스트. 먼저 읽히므로 데이터베이스별 오버라이드가 이긴다.[@<dbname>]— 특정 데이터베이스에만 적용되는 설정(db_name != NULL, 서버의 일반 케이스).[standalone]—SA_MODE(csql -S, 유틸리티)에서만 참조된다.[service]— 서비스 런처 설정(cubrid셸 래퍼가 사용하는service,server키). 여기서ignore_section=false플래그가 로더에게 파라미터 이름에service::접두사를 유지하라고 알린다. 레지스트리에서 두 파라미터 정의가 명시적으로"service::service와service::server"접두사를 갖는 이유가 이것이다.[%<host>|*]와[%<host>|<user>]— 호스트별 또는 호스트-사용자별 오버라이드. HA가 활성화되고 호스트 이름이 해석될 때만 참조된다.
prm_load_by_section은 모든 키를 맹목적으로 prm_set을 호출하지
않는다. 먼저 모드와 플래그로 필터링한다. CS_MODE에서는 서버 전용 파라미터
(PRM_FOR_CLIENT 없음)를 조용히 건너뛴다. SERVER_MODE에서는 반대다.
재로드 시에는 PRM_RELOADABLE 없는 파라미터를 건너뛴다. 로드 플래그에
SYSPRM_IGNORE_HA가 없으면 PRM_FOR_HA 파라미터만 고려된다(이것이
단일 로더 경로에서 cubrid_ha.conf가 cubrid.conf 위에 층을 이루는
방식이다). PRM_OBSOLETED는 조용히 건너뛰고, PRM_DEPRECATED는 경고를
내지만 계속 진행한다. 패턴은 정적 플래그가 값을 고려할지 말지를 결정한다
는 것이다. 두 바이너리가 동일한 conf 파일을 읽지만 각자에게 해당하는
부분 집합만 적용된다.
기본값 채우기와 환경 변수. 모든 섹션이 적용된 후, 아직 건드리지 않은
모든 파라미터를 컴파일 타임 기본값으로 채우는 루프가
system_parameter.c:6144에서 실행된다. 환경 변수 패스 prm_check_environment
(7091)는 테이블을 순회하며 각 파라미터 이름을 대문자로 바꾸고
envvar_get에 해당 환경 변수가 export되어 있는지 물어본다. 있으면 값을
prm_set에 넣는다. 순서는 기본값 → conf 파일 → 환경 변수 → 런타임 강제다.
나중 단계는 set_flag=true로 prm_set을 호출하므로 동적 플래그 워드에
PRM_SET이 설정되고, 다음 단계가 아직 설정되지 않은 경우만 설정 결정을
올바르게 내릴 수 있다.
파라미터 간 조율. prm_tune_parameters(system_parameter.c:9865)는
로드 후 실행되는 정리 패스다. 여러 파라미터를 함께 고려해야 하는 불변식을
구체화한다. max_clients를 min(CSS_MAX_CLIENT_COUNT, css_get_max_socket_fds())로 제한하고, 사용자가 기본값을 그대로 두었고 호스트
의 코어 수를 알 수 있으면 task_worker를 오버라이드하며, HA 관련 파라미터를
자기 일관적인 형태로 조정한다(ha_mode != off일 때 ha_server_state 기본값은
STANDBY, 그렇지 않으면 ACTIVE). 사용자가 ha_node_list를 지정하지 않으면
<host>@<host>로 설정한다. 이 함수가 설정 서브시스템이 엔진 정책이라는
달갑지 않은 역할을 하는 곳이다. 대부분의 내용이 “사용자가 달리 지정하지
않았다면, 시스템이 합리적이라고 판단하는 값은 이것이다”다.
강제 오버라이드. 로더가 하는 마지막 작업은 테이블을 순회해 force_value
문자열이 NULL이 아닌 슬롯을 set_flag=false로 prm_set을 재실행하는
것이다. force_value 필드는 prm_set_force(9471)로만 채워지며,
공개 API sysprm_set_force로 노출된다. 이후 재로드를 거쳐도 값이 살아남아야
하는 호출자가 사용한다. 특히 부트 모듈이 클라이언트 연결 초기에 URL 스타일
param=val 오버라이드를 주입할 때 쓴다. set_flag=false이므로 동적 플래그
PRM_SET이 올라가지 않으며, 덤프 루틴은 여전히 그 슬롯을 진단 목적으로
기본값으로 간주한다.
세션별 우회 경로
섹션 제목: “세션별 우회 경로”설정 서브시스템에서 가장 어려운 설계 선택은 동일한 파라미터를 전역과
세션 모두에서 설정할 수 있을 때 어떻게 되는가다. CUBRID의 답은 파라미터의
플래그(PRM_FOR_SESSION)로 표시하고, 읽기 경로는 그 파라미터에 한해서만
우회 경로를 탄다는 것이다.
동작 방식은 세 가지 상태 조각에 기반한다.
세션 인덱스. DIM(prm_Def) 크기로 한 번 할당되는 flat int[]로,
각 PARAM_ID를 세션별 값 배열의 위치에 매핑하거나, 세션 범위가 아닌
파라미터에는 -1을 반환한다.
// prm_Def_session_idx 채우기 — system_parameter.cSYSPRM_INDIRECT_POS prm_Def_session_idx[DIM (prm_Def)];static int num_session_parameters = 0;
if (num_session_parameters == 0) { for (i = 0; i < MAX_SYSTEM_PARAMS; i++) prm_Def_session_idx[i] = (PRM_IS_FOR_SESSION (GET_PRM (i))) ? num_session_parameters++ : -1;}읽기 경로가 너무 핫하기 때문에 해시 방식은 검토 후 기각되었다.
prm_get_*_value는 모든 페이지 접근, 모든 락 획득, 모든 플랜 생성마다
호출된다. 세션별 우회는 포인터 산술 + 간접 배열 로드로 컴파일되어야 하고,
해시 조회는 허용되지 않는다.
세션별 값 배열. SESSION_PARAM은 작은 타입 지정 값 구조체(prm_id,
flag, datatype, value)이며, 세션 적격 파라미터당 하나의 항목을 갖는다.
세션 모듈(자세한 내용은 cubrid-server-session.md 참조)은 첫 연결 시
SESSION_STATE::session_parameters에 NUM_SESSION_PRM 크기의 배열을 건다.
sysprm_session_init_session_parameters(11447)가 연결 시점 조율자다. 세션
상태에 이미 파라미터 배열이 있으면(재연결), 서버 측 값을 유지하고 클라이언트
패킷에서 풀어낸 값을 버린다. 없으면(새 클라이언트), 클라이언트 값을 사용하고
update_session_state_from_sys_params를 호출해 세션 시간대 영역 같은 파생
캐시를 갱신한다. 이것이 TCP 수준 재연결 때 클라이언트가 연결이 끊기기 전에
설정했던 세션별 설정을 복구하는 메커니즘이다.
읽기 경로의 우회. 인라인 getter prm_get_integer_value(header:834-846)와
그 형제 함수들은 PRM_SERVER_SESSION 매크로(header:681-683)를 검사해, 오직
SERVER_MODE이고 파라미터가 실제로 세션 범위인 경우에만 현재 스레드의 세션으로
prm_get_value(10486)로 역참조한다. 매크로 자체는 아래와 같다.
#define SERVER_SESSION_MASK ((PRM_FOR_SESSION | PRM_FOR_SERVER) | PRM_CLIENT_SESSION)#define SERVER_SESSION_CHCK ((PRM_FOR_SESSION | PRM_FOR_SERVER) & ~PRM_CLIENT_SESSION)#define PRM_SERVER_SESSION(id) \ (((GET_PRM (id))->static_flag & SERVER_SESSION_MASK) == SERVER_SESSION_CHCK)이 파라미터가 세션 범위이고 서버 측이지만 클라이언트 전용 세션이 아닌지
라는 질문이 인코딩된 유일한 장소다. 분기는 압도적으로 우회 없음으로
예측된다. 느린 경로 자체는 BO_IS_SERVER_RESTARTED 가드 하나와 세션별
배열에서 session_get_session_parameter 조회 하나로, 세션 배열이 아직
연결되지 않은 경우 전역 값으로 폴백한다.
flowchart TD
CALL["prm_get_integer_value(prm_id)"]
CHECK{"PRM_SERVER_SESSION(prm_id)<br/>and SERVER_MODE<br/>and 서버 재시작됨"}
GLOBAL["return prm_Def[prm_id].value.v.i"]
SESS["session_get_session_parameter(thread, prm_id)"]
SHASH{"session_parameters[]에서<br/>찾았는가"}
GLOBAL2["return prm_Def[prm_id].value.v.i"]
SESSV["return SESSION_PARAM.value.i"]
CALL --> CHECK
CHECK -- no --> GLOBAL
CHECK -- yes --> SESS
SESS --> SHASH
SHASH -- no --> GLOBAL2
SHASH -- yes --> SESSV
파라미터 간 별칭
섹션 제목: “파라미터 간 별칭”일부 파라미터는 동일한 저장소에 대한 두 가지 이름이다. 전형적인 예는
sort_buffer_size(바이트 단위)와 sort_buffer_pages(IO 페이지 단위)다.
저장소는 하나(정수 페이지 카운트)지만 사용자가 설정하는 방법이 두 가지다.
CUBRID의 해법은 PARAM_VALUE_SHARE[] 테이블(system_parameter.c:5341)이다.
static const int *PARAM_VALUE_SHARE[] = { /* {count, PRM_ID_a, PRM_ID_b, ...} */ (int[]) {2, PRM_ID_SR_NBUFFERS, PRM_ID_SORT_BUFFER_SIZE}, (int[]) {2, PRM_ID_PB_NBUFFERS, PRM_ID_PAGE_BUFFER_SIZE}, (int[]) {2, PRM_ID_BT_OID_NBUFFERS,PRM_ID_BT_OID_BUFFER_SIZE}, (int[]) {2, PRM_ID_LK_TIMEOUT_SECS,PRM_ID_LK_TIMEOUT}, (int[]) {2, PRM_ID_LOG_NBUFFERS, PRM_ID_LOG_BUFFER_SIZE}, /* ... */ (int[]) {2, PRM_ID_JAVA_STORED_PROCEDURE, PRM_ID_STORED_PROCEDURE}, /* ... */ NULL,};각 행의 첫 번째 요소는 별칭 id 수이고 나머지는 id로, 오름차순이며
연속적이어야 한다고 주석에 명시되어 있다. sysprm_set_value(9335)가
그 파라미터 중 하나에 값을 설정하면 sysprm_find_shared_system_parameter를
참조해 같은 설정을 행의 다른 모든 id에도 sysprm_set_value_internal으로
재실행한다. 파라미터별 단위 변환(레지스트리 항목에 선언된 set_dup /
get_dup 콜백)이 실제 페이지-바이트 변환을 처리한다. share 테이블은 멤버십
관계만 담당한다.
PRM_COMPOUND 플래그는 다른 메커니즘이다. 복합 파라미터는 설정 시 다른
여러 파라미터를 부작용으로 설정하지만, 관계는 하나의 저장소에 N개의 이름이
아니라 하나의 입력 키워드가 N개의 출력 값을 선택이다. 현재 유일한 예는
compat_mode다. 설정 시 prm_compound_has_changed(9448)가
prm_set_compound(10310)를 호출하는데, 이 함수는 compat 대상(CUBRID/MySQL/
Oracle)과 업데이트할 파라미터를 인덱스로 하는 2차원 배열 compat_mode_values를
사용한다. oracle_style_outerjoin, ansi_quotes, pipes_as_concat 등이
사용자가 선택한 대상에 따라 서로 다른 기본값을 갖게 된다.
서버와의 전파
섹션 제목: “서버와의 전파”CUBRID 설치는 일관된 파라미터 값을 봐야 하는 프로세스가 최소 두 개다.
클라이언트(cubridcs 라이브러리, JDBC/CCI 드라이버에 링크되거나 SA 모드의
cubridsa)와 서버(cub_server). 각자 자체 prm_Def[] 테이블을 유지하지만,
PRM_FOR_CLIENT | PRM_FOR_SERVER로 태그된 파라미터에서는 값이 일치해야 한다.
전파 규칙은 세 가지 플래그로 인코딩된다.
PRM_FOR_CLIENT만 있는 경우 — 파라미터가 클라이언트에만 존재하고 서버에는 보이지 않는다. 순수 클라이언트 측 파라미터(예: CSQL 동작).PRM_FOR_SERVER만 있는 경우 — 반대. 대부분의 물리 자원 파라미터(버퍼 크기, 로그 크기, 포트).- 둘 다 설정된 경우 — 양쪽에 파라미터가 존재한다. 어느 쪽이 이기는지와
언제인지는
PRM_FORCE_SERVER와PRM_GET_SERVER에 따라 다르다.
클라이언트 주도 변경. 사용자 표면 경로는
SET SYSTEM PARAMETERS '<name>=<value>;...'이며 db_set_system_parameters
(db_admin.c:2879)에 도달한다. 패턴은 검증 → RPC 가능성 → 로컬 적용이다.
sysprm_validate_change_parameters(7196)는 name=value;name=value 페이로드를
sysprm_generate_new_value로 파싱해 SYSPRM_ASSIGN_VALUE 연결 리스트와
상태 코드(PRM_ERR_NO_ERROR: 모든 파라미터가 클라이언트 전용,
PRM_ERR_NOT_FOR_CLIENT: 서버가 필요한 파라미터 있음,
PRM_ERR_NOT_FOR_CLIENT_NO_AUTH: DBA 권한 필요)를 반환한다. 서버가 필요하면
db_set_system_parameters는 sysprm_change_server_parameters(클라이언트 측
RPC 스텁)를 호출하고 이것이 xsysprm_change_server_parameters(8124)에
도달한다. 이 함수는 check=true로 sysprm_change_parameter_values를 얇게
감싸 서버가 클라이언트 전용으로 표시된 파라미터를 거부할 수 있게 한다.
RPC 실행 여부와 관계없이 클라이언트도 로컬에서 sysprm_change_parameter_values
를 호출한다.
역방향은 db_get_system_parameters → sysprm_obtain_parameters(7983) →
서버에 값이 있는 파라미터를 위한 sysprm_obtain_server_parameters다.
서버 강제 갱신. PRM_FORCE_SERVER 플래그는 “이 파라미터의 권위 있는
값은 서버에 있으며, 새로 접속하는 클라이언트는 연결 시 반드시 가져와야
한다”를 선언한다. sysprm_tune_client_parameters(10266)는 boot_register_client
직후 호출되는 클라이언트 측 훅이다. sysprm_get_force_server_parameters로
서버에 요청하고, 응답을 SYSPRM_ASSIGN_VALUE 목록으로 묶어
sysprm_change_parameter_values(..., check=false, ...)로 로컬에 적용한다.
서버 측은 xsysprm_get_force_server_parameters(8165)로, PRM_FORCE_SERVER
로 플래그된 모든 파라미터를 테이블에서 찾아 응답에 담는다. 전형적인 예는
intl_collation, server_timezone, block_ddl_statement다. 클라이언트가
이들을 서버에서 상속받지 않으면 SQL 의미론이 달라지기 때문이다.
sequenceDiagram participant Client participant Server participant ClientPRM as Client prm_Def[] participant ServerPRM as Server prm_Def[] Note over Client,Server: 등록 시점 Client->>Server: xboot_register_client (session_params 포함) Server->>ServerPRM: sysprm_session_init_session_parameters Server-->>Client: BOOT_SERVER_CREDENTIAL + session_id Client->>Server: sysprm_get_force_server_parameters Server->>ServerPRM: PRM_FORCE_SERVER 파라미터 순회 Server-->>Client: SYSPRM_ASSIGN_VALUE 목록 Client->>ClientPRM: sysprm_change_parameter_values Note over Client,Server: 런타임 SET SYSTEM PARAMETERS Client->>ClientPRM: sysprm_validate_change_parameters Client->>Server: sysprm_change_server_parameters (PRM_FOR_SERVER인 경우) Server->>ServerPRM: sysprm_change_parameter_values Client->>ClientPRM: sysprm_change_parameter_values (PRM_FOR_CLIENT인 경우)
URL 파라미터, 재로드, 정리
섹션 제목: “URL 파라미터, 재로드, 정리”CCI/JDBC 드라이버는 cubrid:host:port:db:user:password:?param=val&... 형태의
연결 URL을 받는다. URL 단편은 name=val;name=val 형태로 재포맷되어 DB-Connect
콜백 초기에 db_set_system_parameters에 전달된다. 이후 경로는 런타임 SQL SET
과 동일하다. 이후 재로드에서도 살아남아야 하는 URL 파라미터(예: URL로 지정된
lock_timeout이 cubrid.conf에 의해 덮어쓰이면 안 됨)의 경우, 드라이버는
prm_set_force를 사용한다. 각 값이 슬롯의 force_value 필드에 저장되고
sysprm_load_and_init_internal 호출이 끝날 때마다 재적용된다.
sysprm_reload_and_init는 실행 중 재읽기 경로다. reload=true로 _internal을
호출하는데, 이는 (a) conf 파일을 읽기 전에 PRM_RELOADABLE 파라미터를 전부
기본값으로 초기화하고, (b) prm_load_by_section 내부에서 PRM_RELOADABLE이
없는 파라미터를 건너뛴다. 무거운 물리 파라미터(PRM_ID_PAGE_BUFFER_SIZE,
PRM_ID_LOG_NBUFFERS, PRM_ID_CSS_MAX_CLIENTS)는 재로드 불가능하다. 이들은
한 번만 할당된다. sysprm_final(9783)은 대칭적인 정리 함수로, 테이블을
순회하며 PRM_ALLOCATED로 플래그된 값을 해제하고, dynamic_flag = 0으로
초기화하며, prm_file_has_been_loaded 집합을 비운다.
진단을 위한 덤프
섹션 제목: “진단을 위한 덤프”sysprm_dump_parameters(5847)가 검사 루틴이다. 호출자는 마커 문자(' ',
'C', 'S'), 포함/제외 플래그 마스크, 마스크의 AND-vs-OR 의미론을 넘긴다.
새 스타일 출력은 [<마커><drift>] name=value (default) 형태로 기본값과 다른
항목이 한눈에 보인다. 이전 스타일은 그냥 name=value를 출력한다.
기본값-현재값 비교는 슬롯에서 prm->value와 prm->default_value를 직접
읽는다. 재포맷이나 I/O 없이 이것이 가능한 이유가 테이블이 둘 다 보유하기
때문이다. xsysprm_dump_server_parameters는 마커를 'S'로 미리 채우는 서버
측 래퍼다.
소스 코드 가이드
섹션 제목: “소스 코드 가이드”설정 서브시스템은 C 파일 하나와 공개 헤더로 구성된다. 아래에서 심볼을
역할별로 묶었고, 끝에 있는 위치 힌트 테이블이 각 심볼과 updated: 시점
기준 줄 번호를 연결한다.
헤더 — 타입과 정책. system_parameter.h는 id 열거형 PARAM_ID, 타입 태그
SYSPRM_DATATYPE, 변형 공용체 SYSPRM_VALUE와 태그 래퍼
SYSPRM_PARAM_VALUE, 슬롯 구조체 SYSPRM_PARAM, 세션 범위 값 타입
SESSION_PARAM, 변경 목록 타입 SYSPRM_ASSIGN_VALUE, 정적·동적 플래그 정의,
접근자 매크로(GET_PRM, PRM_GET_INT/BOOL/...), 정책 매크로
PRM_SERVER_SESSION, STATIC_INLINE getter prm_get_integer_value /
..._bool_value / ..._float_value / ..._string_value /
..._integer_list_value / ..._bigint_value를 노출한다. Windows 빌드에서는
getter가 인라인이 아닌 함수로 제공된다.
레지스트리 데이터 (system_parameter.c). 파라미터마다 #define PRM_NAME_<ID> 하나씩(120-797), 그 다음 SYSPRM_PARAM prm_Def[]
(1010-5331), 미리 계산된 세션 인덱스 prm_Def_session_idx[], 크기 캐시
MAX_SYSTEM_PARAMS, 별칭 테이블 PARAM_VALUE_SHARE[], CS_MODE별 캐시
cached_session_parameters, 키워드 테이블(boolean_words,
er_log_level_words, isolation_level_words, ha_mode_words,
compat_words 등).
로더. 세 개의 공개 진입점(sysprm_load_and_init / ..._client /
_reload_and_init)이 모두 sysprm_load_and_init_internal을 통과한다.
섹션별 작업은 prm_read_and_parse_ini_file → prm_load_by_section →
prm_section_cmp + prm_find다. 로드 후 패스는 prm_check_environment
(환경 변수 오버라이드), prm_tune_parameters(파라미터 간 일관성), 강제값
재실행 루프다. init_server_timezone_parameter는 시간대 관련 늦은 초기화
단계다.
쓰기 경로. prm_set은 문자열을 타입 지정 값으로 파싱(sysprm_generate_new_value)하고
sysprm_set_value로 적용한다. sysprm_set_value는 실제 변형을 위해
sysprm_set_value_internal을 호출하고, 별칭 id로 전파하기 위해
sysprm_find_shared_system_parameter를 참조하며, PRM_COMPOUND인 경우
prm_compound_has_changed → prm_set_compound로 추가 설정을 연쇄 실행한다.
prm_set_default는 기본값으로 초기화한다. prm_set_force는 재실행을 위해
force_value에 문자열을 저장한다. 타입 지정 공개 setter prm_set_integer_value
/ ..._bool / ..._float / ..._string / ..._integer_list / ..._bigint가
직접 쓰기 API다.
읽기 경로. prm_get_value는 필요시 세션별 우회를 거쳐 활성
SYSPRM_VALUE의 포인터를 반환한다. 헤더의 인라인 getter가 핫 경로다.
prm_get_name, prm_get_master_port_id, prm_get_commit_on_shutdown은 타입
지정 편의 래퍼다.
SQL/URL과 전파. sysprm_validate_change_parameters는 name=val;...을
정책 검사와 함께 SYSPRM_ASSIGN_VALUE 목록으로 파싱한다.
sysprm_make_default_values는 이름을 name=default; 문자열로 재포맷한다.
sysprm_change_parameter_values는 목록을 적용한다. sysprm_obtain_parameters
는 읽기 대응 함수다. db_set_system_parameters / db_get_system_parameters
(compat/db_admin.c)가 SQL-API 드라이버다. xsysprm_change_server_parameters,
xsysprm_obtain_server_parameters, xsysprm_get_force_server_parameters,
xsysprm_dump_server_parameters, xsysprm_get_pl_context_parameters가
서버 측 RPC 스텁이다. sysprm_tune_client_parameters는 PRM_FORCE_SERVER
값을 가져오는 클라이언트 등록 후 훅이다.
sysprm_session_init_session_parameters는 서버 측 연결 시점 조율 로직이다.
와이어 포맷. sysprm_pack_sysprm_value / ..._unpack_..._value가 하나의
SYSPRM_VALUE를 다룬다. sysprm_pack_session_parameters / ..._unpack_...
쌍이 xboot_register_client 시점에 전송되는 세션별 배열을 처리한다.
sysprm_pack_assign_values / ..._unpack_... 쌍이 변경 목록을 처리한다.
sysprm_free_assign_values가 해제 함수다.
진단과 정리. sysprm_dump_parameters와 xsysprm_dump_server_parameters,
sysprm_print_parameters_for_qry_string(플랜 캐시 키),
sysprm_print_parameters_for_ha_repl(HA 복제), prm_print(슬롯별 포맷터),
prm_rewrite_int_list, 디버그 빌드 온전성 검사 sysprm_check_id_order와
prm_check_parameters. sysprm_final이 프로세스 종료 시 순회 함수다.
위치 힌트 (updated: 시점 기준)
섹션 제목: “위치 힌트 (updated: 시점 기준)”| 심볼 | 파일 / 줄 |
|---|---|
enum param_id / PARAM_ID | system_parameter.h:97-534 |
| 정적 / 동적 플래그 매크로 | system_parameter.h:606-646 |
SYSPRM_DATATYPE / SYSPRM_VALUE / SESSION_PARAM / SYSPRM_ASSIGN_VALUE | system_parameter.h:539-578 |
SYSPRM_PARAM (슬롯 구조체) | system_parameter.h:706-721 |
PRM_SERVER_SESSION 매크로 | system_parameter.h:681-683 |
인라인 prm_get_*_value getter | system_parameter.h:819-947 |
PRM_NAME_* 매크로 | system_parameter.c:120-797 |
NULL_SYSPRM_PARAM_VALUE | system_parameter.c:1007 |
SYSPRM_PARAM prm_Def[] | system_parameter.c:1010-5331 |
prm_Def_session_idx[] | system_parameter.c:5333 |
MAX_SYSTEM_PARAMS / num_session_parameters | system_parameter.c:5335-5339 |
PARAM_VALUE_SHARE[] | system_parameter.c:5341-5374 |
cached_session_parameters | system_parameter.c:5383 |
키워드 테이블 (boolean_words, …) | system_parameter.c:5399-5530 |
sysprm_dump_parameters | system_parameter.c:5847 |
sysprm_set_er_log_file | system_parameter.c:5919 |
sysprm_check_id_order | system_parameter.c:5963 |
sysprm_load_and_init_internal | system_parameter.c:6015 |
sysprm_load_and_init / ..._client / _reload_and_init | system_parameter.c:6285-6315 |
prm_load_by_section | system_parameter.c:6350 |
prm_read_and_parse_ini_file | system_parameter.c:6574 |
prm_check_environment | system_parameter.c:7091 |
sysprm_validate_change_parameters | system_parameter.c:7196 |
sysprm_make_default_values | system_parameter.c:7322 |
sysprm_change_parameter_values | system_parameter.c:7402 |
sysprm_obtain_parameters | system_parameter.c:7983 |
xsysprm_change_server_parameters | system_parameter.c:8124 |
xsysprm_obtain_server_parameters | system_parameter.c:8140 |
xsysprm_get_force_server_parameters | system_parameter.c:8165 |
xsysprm_get_pl_context_parameters | system_parameter.c:8223 |
sysprm_get_range | system_parameter.c:8380 |
prm_set | system_parameter.c:9167 |
sysprm_set_value / ..._internal | system_parameter.c:9183-9362 |
sysprm_find_shared_system_parameter | system_parameter.c:9366 |
prm_set_force | system_parameter.c:9471 |
prm_set_default / ..._internal | system_parameter.c:9489-9589 |
prm_find | system_parameter.c:9597 |
sysprm_final | system_parameter.c:9783 |
prm_tune_parameters | system_parameter.c:9865 |
sysprm_tune_client_parameters | system_parameter.c:10266 |
prm_set_compound | system_parameter.c:10310 |
prm_get_next_param_value | system_parameter.c:10347 |
prm_get_value | system_parameter.c:10486 |
prm_set_integer_value / ..._bool / ..._float / ..._string / ..._integer_list / ..._bigint | system_parameter.c:10533-10650 |
sysprm_pack_session_parameters / ..._unpack_... | system_parameter.c:11118-11233 |
sysprm_pack_assign_values / ..._unpack_... | system_parameter.c:11243-11357 |
sysprm_free_assign_values | system_parameter.c:11366 |
sysprm_session_init_session_parameters | system_parameter.c:11447 |
sysprm_get_session_parameters_count | system_parameter.c:12127 |
cubrid.conf 설정 파일 | conf/cubrid.conf:25-75 |
db_set_system_parameters | compat/db_admin.c:2879 |
db_get_system_parameters | compat/db_admin.c:3014 |
소스 검증 노트
섹션 제목: “소스 검증 노트”prm_Def[]를 서브시스템 호출 위치와 교차 검증하면 몇 가지 세부 사항이
드러난다.
PRM_ID_OPTIMIZER_RESERVE_02 … _20은PRM_OBSOLETED를 가진 자리 표시자 슬롯이다. 새 옵티마이저 파라미터는PRM_LAST_ID를 올리는 대신 예약 슬롯을 재사용한다. 이렇게 하면 열거형-id ↔ 네트워크 프로토콜 매핑이 버전 간에 안정적으로 유지된다.PRM_ID_HA_MODE_FOR_SA_UTILS_ONLY는 비공개 채널이다. SA 모드에서prm_tune_parameters는ha_mode를 강제로 OFF로 초기화하지만, 설정된 값을 여기에 저장해 유틸리티의 HA 인식 로깅 경로가 여전히 찾을 수 있게 한다. 사용자가 직접 설정하는 방법은 없다.- HA conf는 두 번 로드된다. 첫 번째
prm_read_and_parse_ini_file호출은SYSPRM_IGNORE_HA를 전달해PRM_FOR_HA를 건너뛴다. 두 번째는 반대 플래그로cubrid_ha.conf를 읽는다. 로더가 단일 부팅에서 두 번 실행되는 유일한 곳이다. PRM_FOR_HA_CONTEXT는 복제 인식적이다. 마스터가SET SYSTEM PARAMETERS로 이런 파라미터를 바꾸면, HA 로그 적용자가 테이블을 순회해 복제본에도 재적용한다.PRM_FOR_PL_CONTEXT는 PL/SP 연결 시xsysprm_get_pl_context_parameters로 한 번 전달된다. 이후 그 파라미터에 대한 변경은 JVM에 전달되지 않는다. 실시간 업데이트가 필요한 호출자는 재바인딩해야 한다.- 복합 vs. 공유 — 경계가 흐릿하다.
PRM_COMPOUND는 부작용으로 여러 개를 설정하고,PARAM_VALUE_SHARE는 두 id를 같은 저장소에 연결한다.sysprm_set_value는 쓰기 → 별칭 전파 → 복합 연쇄 순서로 처리한다. 복합이면서 동시에 share 쌍의 절반인 파라미터는prm_set_compound의 재귀 가드 없이는 루프에 빠진다. 현재 그런 파라미터는 없어 이 케이스는 테스트되지 않았다. - 환경 변수가 conf보다 우선한다.
prm_check_environment는 conf 파일 이후에 실행된다. 따라서 export된CUBRID_DATA_BUFFER_SIZE=1G는cubrid.conf의data_buffer_size=512M을 이긴다. 이는 Postgres의PGOPTIONS우선순위와 일치하며 MySQL 관례를 반전시킨다. prm_tune_parameters는PRM_SET없이 변형한다. 조율 함수는set_flag=false로prm_set을 호출한다. 따라서 조율된 값은 변하지만PRM_DEFAULT_USED플래그는 유지되고 덤프 루틴은 여전히 해당 파라미터를 기본값으로 기술한다. 조율 함수가 엔진 정책이지 사용자 의도가 아니기 때문에 의도적이다. 그러나 덤프의default_marker가 항상 컴파일 타임 기본값과 같은 것은 아니라는 뜻이기도 하다.
미해결 질문
섹션 제목: “미해결 질문”PRM_FOR_QRY_STRING플랜 캐시 키 비용. 플랜 캐시 키 문자열을 만들기 위해 전체 테이블을 순회하는 것은 핫 경로다. 미리 계산된 비트맵이 도움이 되겠지만 그런 작업의 흔적이 트리에 없다.PRM_FOR_HA_CONTEXT파라미터를 자동으로 파생할 수 있을까? 현재는 모든 HA 컨텍스트 파라미터가 수동으로 플래그된다. 실제 불변식은 “결정론적 SQL 의미론에 영향을 미치는 모든 파라미터는 복제되어야 한다”이다. 자동으로 인코딩하면 취약해지지만 가치 있을 것이다._RESERVE슬롯이 ABI를 위해 필요한가? 비용은 테이블 공간, 덤프 출력 노이즈, 개발자 주의 분산이다. 대안(append-and-bump-version)이 대부분의 다른 엔진이 하는 일이다. CUBRID의 근거는 타당하지만 일회성 포맷 변경으로 슬롯을 제거할 수 있다.- 재로드 + 세션 파라미터.
sysprm_reload_and_init는 전역 테이블만 초기화한다. 로컬 복사본을 가진 세션은 알림을 받지 못한다.PRM_ID_LK_TIMEOUT_SECS를 재로드해도 기존 세션이SET SYSTEM PARAMETERS를 실행하거나 재연결하기 전까지 보이지 않는다. 의도된 것인지는 주석이 없다. force_value×PRM_FOR_SESSION은 불안정하다. force 값은prm_set으로 전역 슬롯에 재적용되지만, 세션 파라미터의 경우 그 경로가 세션별 우회를 타 전역 기본값이 아닌 현재 스레드의 세션에 도달한다. 현재 이 케이스를 실행하는 호출자가 없다.
src/base/system_parameter.c— 구현 (12,272 줄).src/base/system_parameter.h— 공개 타입, 인라인 getter, 플래그 정의 (957 줄).conf/cubrid.conf— 사용자 대상 기본 설정 파일 (75 줄, 샘플. 설치본에는 더 긴 파일이 포함됨).src/compat/db_admin.c—db_set_system_parameters,db_get_system_parameters, SQL 대면 래퍼.- 서브시스템 호출 위치는
prm_get_*_value(PRM_ID_*)로 grep 가능. 예:pgbuf_Pool.num_buffers = prm_get_integer_value(PRM_ID_PB_NBUFFERS);(src/storage/page_buffer.c),wait_msecs = prm_get_integer_value (PRM_ID_LK_TIMEOUT_SECS);(src/transaction/lock_manager.c),log_No_logging = prm_get_bool_value(PRM_ID_LOG_NO_LOGGING);(src/transaction/log_manager.c). - 인접 문서:
cubrid-boot.md— 로더가 프로세스 시작에 연결되는 방식.cubrid-server-session.md—SESSION_STATE::session_parameters배열과xsession_check_session재연결 경로.