(KO) CUBRID migrate — 볼륨 헤더, active log codeset, collation sync 를 위한 one-shot 9.1→9.2 in-place 형식 업그레이더
이론적 배경
섹션 제목: “이론적 배경”Disk-format 업그레이더는 데이터베이스 엔진이 버전 사이에서 on-disk 레이아웃이 비호환적으로 바뀔 때 함께 배포하는 도구다. 두 가지 디자인 선택이 도구의 모양을 지배한다.
- In-place 와 dump-and-reload 가운데 무엇을 고르는가. In-place 는 기존 볼륨 파일을 다시 쓴다. 더 빠르고 (두 번째 디스크 공간 이 필요 없고 re-import 도 없다) per-format 변환기와 견고한 크래시-복구 story 가 필요하다. Dump-and-reload (이전 바이너리 로 export, 새 바이너리로 import) 는 더 느리지만 개념적으로 단순하고 표준 export / import 경로를 재사용한다.
- Single-version-pair 와 multi-version-chain 가운데 무엇을 고르는가. Single-pair 도구가 엄격히 버전 N 에서 N+1 로 마이 그레이트한다. Chain 도구는 모든 historical 형식을 이해하고 어떤 것에서든 current 로 변환한다. Chain 은 운영자에게 더 쉽 지만 (업그레이드당 한 도구) 테스트 매트릭스를 폭발시킨다. Pair 는 단순하고 명시적이지만 운영자가 중간 버전을 traverse 해야 한다.
CUBRID 의 migrate 는 in-place 와 single-pair (9.1→9.2) 조합
을 고른다. startup 의 hard guard
rel_disk_compatible() != V9_2_LEVEL 가 다른 CUBRID 버전이
링크되어 있으면 마이그레이터를 거절한다. 9.1→9.2 변환기를 9.0
또는 9.3 install 에 실수로 돌리는 일을 막는 장치다. 이후 모든
버전 업그레이드는 자기 pair 도구 (또는 dump-and-reload 의
release-note 지시) 를 가진다.
In-place 선택이 마이그레이터에 undo journal 유지를 강제한다.
모든 수정된 볼륨 헤더가 먼저 read 되고 옆 버퍼에 write 되고
새 형식으로 다시 write 된다. mid-migration 크래시가 나면
journal 의 각 entry 를 undo_fix_volume_header 로 rollback
할 수 있다.
CUBRID 의 접근
섹션 제목: “CUBRID 의 접근”네 단계 시퀀스
섹션 제목: “네 단계 시퀀스”migrate <db_name> 가 엄격한 네 단계 시퀀스를 돌린다는 점이다:
- 볼륨 헤더 재작성. 데이터베이스의 볼륨-info 파일에 list 된
모든 데이터 볼륨을 walk 한다. 각 볼륨을 v9.1
r91_disk_var_header(migrate.c:115의 struct) 로 read 한 뒤 v9.2 레이아웃으로 reshape 해 다시 write 한다. 각 pre-rewrite 헤더가 in-memory undo list (vol_undo_info, maxUNDO_LIST_SIZE = 32) 에 capture 된다. - Active log 의 codeset patch. active log 헤더가 codeset 필드
를 운반한다. 그 값이 카탈로그 (
db_root.codeset) 와 어긋나 있으면fix_codeset_in_active_log가 in-place 로 patch 해서 migration 후 log 의 텍스트 record 해석이 카탈로그와 매치되게 한다. db_restart와synccoll_force를 통한 카탈로그 reconcile. 새 바이너리로 데이터베이스를 부팅하고db_collation의 모든 collation 행을 walk 한 뒤 (catcls_get_db_collation통해) 각각을 같은 collation 의 locale 라이브러리 view 와 비교한다. id, 이름, codeset, checksum 이 모두 일치해야 하며, contraction 이 있는 경우는 예외다 (9.2 에서 on-diskCOLL_CONTRACTION표현이 reorganise 되었으므로 checksum drift 가 허용된다). 그 다음synccoll_force가 locale 라이브러리에서 collation 행을 다시 쓴다.- 볼륨 통계 refresh.
file_update_used_pages_of_vol_header가 헤더의 used-pages counter 를 refresh 하기 위해 모든 볼륨을 스캔한다. 이 값은 9.1 에서 다르게 계산되었고 9.2 의미로 다시 빌드되어야 한다.
어느 단계가 실패하면 마이그레이터가 unwind 된다 —
error_undo_vol_header 가 undo list 의 모든 entry 를 역순으로
다시 적용해 원래 v9.1 헤더를 복원한다. 그 다음 error_undo_compat
가 compat-level 마커 (check_and_fix_compat_level)를 되돌려
데이터베이스가 9.1 바이너리로 다시 열릴 수 있게 한다.
Undo 규율
섹션 제목: “Undo 규율”// migrate.c (의역)fix_all_volume_header (db_path) { walk volume info; for each volume { undo_page = make_volume_header_undo_page (vol_path, size); // read + journal if (undo_page) { vol_undo_info[vol_undo_count++] = (vol_path, undo_page, size); } fix_volume_header (vol_path); // in-place 재작성 }}
error_undo_vol_header: for (i = vol_undo_count - 1; i >= 0; i--) { undo_fix_volume_header (vol_undo_info[i].filename, vol_undo_info[i].page, vol_undo_info[i].page_size); } free_volume_header_undo_list ();Journal 은 in-memory 전용이다. mid-rewrite 프로세스 크래시가
journal 을 잃고 볼륨을 mixed 상태로 남긴다는 의미다. 운영자는
migrate 를 돌리기 전에 cold backup 을 갖추고 있어야 한다.
도구 외부에 process-crash 복구 경로가 존재하도록 보장하는 장치다.
시그널 핸들러 (intr_handler, SIGINT 와 Windows console-control
에 설치)가 loop 가 볼륨 사이에 검사하는 플래그를 설정한다 —
mid-volume 으로 abort 하는 대신 같은 undo 시퀀스를 trigger 하는
graceful Ctrl-C 를 허용한다.
r91_disk_var_header — 레거시 on-disk 모양
섹션 제목: “r91_disk_var_header — 레거시 on-disk 모양”// migrate.c — 마이그레이트되는 형식struct r91_disk_var_header { char magic[CUBRID_MAGIC_MAX_LENGTH]; INT16 iopagesize; INT16 volid; DISK_VOLPURPOSE purpose; INT32 sect_npgs; INT32 total_sects; INT32 free_sects; INT32 hint_allocsect; INT32 total_pages; INT32 free_pages; INT32 sect_alloctb_npages; INT32 page_alloctb_npages; INT32 sect_alloctb_page1; INT32 page_alloctb_page1; INT32 sys_lastpage; INT64 db_creation; INT32 max_npages; INT32 dummy; LOG_LSA chkpt_lsa; HFID boot_hfid; INT16 offset_to_vol_fullname; INT16 offset_to_next_vol_fullname; INT16 offset_to_vol_remarks; char var_fields[1];};9.2 헤더 (disk_manager.{c,h} 에 정의)가 이를 다른 필드 레이아웃
으로 reorganise 한다 — sector-allocation 추적이 별도 per-볼륨
metadata page 로 옮겨가고, dummy 필드가 repurpose 되고, 여러
offset 이 재계산된다. fix_volume_header 가 필드별 번역을 담고
있다. 마이그레이터가 코드베이스에서 v9.1 레이아웃을 아는 유일한
곳이다.
Compat-level 가드
섹션 제목: “Compat-level 가드”check_and_fix_compat_level 이 “migration in progress” 를 나타내는
sentinel 을 데이터베이스에 쓴다. 마이그레이터 프로세스가 깨끗하게
kill 되거나 (또는 성공적으로 끝나면) sentinel 이 클리어된다.
sentinel 이 set 인 동안 데이터베이스가 9.1 또는 9.2 바이너리로
열리면 둘 다 mount 를 거절한다 — migration window 동안 double-
migration 또는 사고 액세스를 방지한다는 뜻이다.
엄격한 버전 assertion
섹션 제목: “엄격한 버전 assertion”// migrate.c::main (의역)if (rel_disk_compatible () != V9_2_LEVEL) { printf ("CUBRID library version is invalid.\n" "Please upgrade to CUBRID 9.2 and retry migrate.\n"); return EXIT_FAILURE;}rel_disk_compatible() 이 링크된 CUBRID 라이브러리의 disk-compat
level 을 돌려준다. 마이그레이터는 링크된 level 이 정확히 9.2 가
아니면 시작을 거절한다 — 바이너리가 다른 target 버전으로
마이그레이트하는 데 잘못 사용되는 것을 방지한다. 이것이
migrate 가 엄격히 버전 잠긴 도구인 이유다 — “현재가 무엇이든
업그레이드” 가 아니라 “9.1 → 9.2, 그것 외에는 없다” 라는 뜻이다.
소스 워크스루
섹션 제목: “소스 워크스루”| 심볼 | 역할 |
|---|---|
main | 진입; arg 검사; 버전 가드; 네 단계 orchestration; 에러 rollback |
intr_handler | SIGINT 핸들러; graceful abort 위한 interrupt 플래그 설정 |
fix_all_volume_header | 단계 1 driver: 볼륨 info walk, 볼륨당 fix_volume_header 호출 |
fix_volume_header | 볼륨별 헤더 재작성 (v9.1 → v9.2) |
make_volume_header_undo_page | undo journal 위해 기존 헤더를 옆 버퍼로 read |
undo_fix_volume_header | undo journal 의 한 entry 복원 |
free_volume_header_undo_list | 성공 후 in-memory undo journal drop |
get_active_log_vol_path | 볼륨-info 파일에서 active log 경로 찾기 |
get_db_path | 데이터베이스 이름 → full path 해석 (databases.txt 통해) |
check_and_fix_compat_level | migration-in-progress sentinel write |
fix_codeset_in_active_log | 단계 2: active log 헤더의 codeset 필드 patch |
get_codeset_from_db_root | patch 를 위해 카탈로그의 정규 codeset read |
r91_disk_var_header (struct) | 레거시 v9.1 볼륨-헤더 레이아웃 |
VOLUME_UNDO_INFO (struct) | per-undo-entry record (파일명 + page bytes + 크기) |
vol_undo_info (전역 배열) | undo journal, max 32 entry |
위치 힌트 (2026-05-05 기준)
섹션 제목: “위치 힌트 (2026-05-05 기준)”| 심볼 | 경로 |
|---|---|
main | src/executables/migrate.c:404 |
r91_disk_var_header (struct) | src/executables/migrate.c:115 |
fix_all_volume_header (선언) | src/executables/migrate.c:155 |
get_active_log_vol_path | src/executables/migrate.c:167 |
fix_codeset_in_active_log | src/executables/migrate.c:200 |
V9_1_LEVEL / V9_2_LEVEL (define) | src/executables/migrate.c:49–50 |
심볼 이름이 정규 anchor 이고, 라인 번호는 updated: 날짜에
스코프된 힌트이다.
Cross-check 노트
섹션 제목: “Cross-check 노트”- One-pair 범위가 디자인의 핵심이다. 모던 CUBRID (10.x 이후)
는 다른 업그레이드 경로를 사용한다. release note 가 보통
in-place 마이그레이터가 아니라
unloaddb/loaddb를 통한 dump-and-reload 를 처방한다. 이 바이너리는 누군가가 pre-9.2 데이터베이스를 업그레이드하는 archaeological / DR 시나리오를 위해 보존된다. - In-memory undo journal 의 한도 문제.
UNDO_LIST_SIZE = 32는 32 볼륨 이상의 데이터베이스가 가장 최근 32 개의 in-flight 재작성 너머로 rollback 할 수 없다는 의미다. 어쨌든 mid-migration abort 가 (시그널 이유가 아닌) 크래시 이유로는 journal 을 잃기 때문에 실제로는 받아들일 만하다. - Collation contraction 의 허용 list. checksum 비교 주변의
count_contr == 0검사가 존재하는 이유는 9.2 의COLL_CONTRACTIONstruct 가 reorganise 되었기 때문이다. contraction 이 있는 collation 은 사용자에게 보이는 동작이 변하지 않았더라도 9.2 에서 의도적으로 다른 on-disk checksum 을 가진다. 그 collation 들의 checksum 비교를 우회하는 것은 의도된 신뢰 호출이다. AU_DISABLE_PASSWORDS다음에db_login("DBA", NULL). 마이 그레이터는 auth 가 우회된 채로 돈다. DBA login 은 인증된 것이 아니라 위치적이다. 마이그레이터가 데이터베이스 파일에서 로컬로 돌고 두 번째 연결이 불가능하기 때문에 (compat-level sentinel 이 정상 mount 를 방지) 안전하다.cubrid migrateverb 가 없다. 대부분 utility 와 달리migrate는ua_Utility_Map에 등록되지 않은 standalone 바이너리다 (cubrid-cub-admin.md참조). 운영자는migrate <db_name>으로 직접 invoke 한다. 의도적인 omission 이 그 좁은 범위와 매치된다. 일반 admin-CLI 모양에 맞지 않기 때문이다.
열린 질문
섹션 제목: “열린 질문”- 모던 형식 업그레이드 경로가 무엇인가. 예컨대 10.x → 11.x 에 대한 이 도구의 문서화된 동등물이 없다. dump-and-reload 경로가 release note 에 암묵적이다. 미래 버전이 비슷한 in-place 마이 그레이터로 이득을 볼지는 미정이다.
- Cold-backup 요구사항을 도구가 강제하지 않는다. 운영자는
migrate를 돌리기 전에 cold backup 을 갖추고 있어야 하지만 도구 자체가 강제하지는 않는다. 최근 backup 이 감지되지 않으면 돌기를 거절하는 pre-flight 검사가 프로세스를 강화할 것이다. - 32-entry undo cap 의 적정성. 일반적인 데이터베이스에는 충분히 크지만 큰 다중 볼륨 install 에는 작다. (또는 journal 을 on-disk 파일로 옮기는 것을) widen 할지는 도구가 활발히 개발 되지 않기 때문에 떠오르지 않은 scoping 질문이다.
Sources
섹션 제목: “Sources”src/executables/migrate.c— 전체 utility (단일 파일, ~830 줄)src/executables/AGENTS.md— agent 가이드- 인접 문서:
cubrid-disk-manager.md(migrate 가 생산하는 모던 볼륨-헤더 형식),cubrid-charset-collation.md(단계 3 이 reconcile 하는 collation 인프라),cubrid-log-manager.md(단계 2 가 patch 하는 active-log 헤더),cubrid-boot.md(단계 3 이db_restart통해 행사하는 데이터베이스-부팅 경로),cubrid-cub-admin.md(통합 admin CLI; migrate 는ua_Utility_Map에 없다)