과거 누적 DDL과 데이터 보정을 시점별 SQL로 분리하고 관리자·CLI 실행기를 제공한다. 실행 순서, 잠금, 체크섬, 성공·실패 이력 및 개별 실행의 선행 조건을 검증한다. 기존 스키마의 부분 적용 복구와 설치 SQL 정합성 검사를 추가하고 실행·복구 절차를 문서화한다.
53 lines
5.1 KiB
Markdown
53 lines
5.1 KiB
Markdown
# 데이터베이스 마이그레이션
|
|
|
|
데이터베이스 스키마 변경은 설정·목록·상세 화면이나 공통 라이브러리의 일반 실행 경로에서 수행하지 않는다. 신규 설치의 최종 스키마는 `install/gnuboard5.sql`에 반영하고, 기존 설치 변경은 `migrations` 디렉터리의 버전형 SQL 파일로 관리한다.
|
|
|
|
## 파일 규칙
|
|
|
|
- 파일명은 `YYYYMMDD_NNN_설명.sql` 형식을 사용한다.
|
|
- 파일명은 한 번 배포한 뒤 변경하거나 재사용하지 않는다.
|
|
- `-- @description`에 관리자에게 표시할 설명을 작성한다.
|
|
- 각 SQL 문 바로 앞에 `-- @if-table-missing`, `-- @if-table-exists`, `-- @if-column-missing`, `-- @if-index-missing` 조건을 둘 수 있다. 조건이 여러 개면 모두 만족할 때만 실행한다.
|
|
- 게시판별 글 테이블은 `-- @foreach-write-table-if-column-missing column_name`과 `{{write_table}}`을 사용한다.
|
|
- SQL에는 실제 접두어 대신 실행기가 지원하는 테이블 자리표시자를 사용한다.
|
|
- 한 파일은 가능한 한 하나의 목적만 포함한다.
|
|
|
|
자리표시자는 `$g5`에 등록된 `*_table` 키를 `{{config_table}}` 형식으로 사용한다. 실행기가 실제 테이블명으로 치환하며, 치환되지 않은 자리표시자는 오류로 처리한다.
|
|
|
|
## 실행 방법
|
|
|
|
CLI를 권장한다.
|
|
|
|
```bash
|
|
php bin/db-migrate.php status
|
|
php bin/db-migrate.php migrate
|
|
php bin/db-migrate.php migrate 20260416_001_member_auto_login
|
|
php bin/check-migration-schema.php
|
|
php bin/check-migration-runner.php
|
|
php bin/check-runtime-ddl.php
|
|
```
|
|
|
|
웹에서는 최고관리자가 **환경설정 → DB업그레이드**에서 전체 또는 특정 마이그레이션을 명시적으로 실행할 수 있다. 성공한 마이그레이션의 개별 실행 버튼은 비활성화되며, 전체 실행에서도 성공 이력과 체크섬이 일치하는 항목은 건너뛴다. 화면 조회만으로는 DDL이 실행되지 않는다.
|
|
|
|
전체 실행은 파일명 오름차순, 즉 오래된 마이그레이션부터 처리하며 하나가 실패하면 이후 실행을 중단한다. 개별 실행도 대상보다 앞선 모든 마이그레이션의 성공 이력과 체크섬이 유효해야 한다. 선행 항목이 누락·실패·변경된 경우 대상만 건너뛰기 성공으로 기록하지 않고 오류로 차단한다.
|
|
|
|
실행기는 `g5_migrations` 테이블에 마이그레이션 ID, 체크섬, 상태, 오류, 실행시간과 적용시각을 기록한다. 프로세스 간 잠금을 사용해 동시 실행을 막고, 실패하면 이후 마이그레이션을 중단한다. 적용이 끝난 파일의 체크섬이 바뀌면 오류로 처리한다.
|
|
|
|
현재 마이그레이션은 공통 실행 취소를 제공하지 않는다. 컬럼·테이블 삭제에 따른 데이터 손실과 후속 마이그레이션 의존성을 자동으로 안전하게 해결할 수 없기 때문이다. `g5_migrations`의 성공 이력만 삭제하는 것도 실제 스키마를 되돌리지 않으므로 취소로 취급하지 않는다. 롤백이 필요하면 데이터베이스 백업을 복원하거나, 해당 변경에 맞춘 별도 복구 절차를 검토한다.
|
|
|
|
`check-migration-schema.php`는 마이그레이션의 테이블·컬럼·인덱스가 신규 설치 SQL에 포함되는지와 최종 컬럼 정의가 일치하는지 검사한다. `check-migration-runner.php`는 격리된 임시 테이블로 부분 적용 스키마, 쇼핑몰 미설치 건너뛰기, 기존 데이터 보정을 검사한다. 마이그레이션을 추가하거나 설치 SQL을 변경한 뒤 두 검사를 반드시 실행한다.
|
|
|
|
`check-runtime-ddl.php`는 관리자·게시판·라이브러리·쇼핑몰 등 일반 실행 경로에 DDL 문이 다시 추가되지 않았는지 검사한다. 테이블이나 컬럼 변경은 이 검사를 우회하지 말고 버전형 마이그레이션으로 작성한다.
|
|
|
|
게시판 삭제 시 게시판별 테이블을 함께 삭제하는 것처럼 사용자가 명시적으로 요청한 데이터 생명주기 작업은 마이그레이션과 구분해 제한된 허용 목록으로 관리한다. 일반 레코드 생성 과정에서 `AUTO_INCREMENT`를 초기화하는 DDL은 허용하지 않는다.
|
|
|
|
## 권한과 배포
|
|
|
|
운영 환경에서는 웹 런타임 DB 계정에서 DDL 권한을 제거하고, 배포 단계에서 별도의 권한을 가진 계정으로 CLI 마이그레이션을 실행하는 구성을 권장한다. 웹 실행 기능을 사용하는 환경은 실행 시에만 필요한 DDL 권한이 있어야 한다.
|
|
|
|
배포 전에는 백업과 테이블 크기, 예상 잠금 시간을 확인한다. MySQL 계열 DB의 DDL은 트랜잭션으로 완전히 되돌릴 수 없으므로 실패한 마이그레이션의 오류를 확인하고 수동 복구 후 재실행한다.
|
|
|
|
## 기존 업그레이드 코드
|
|
|
|
과거 설치본을 화면 접근 시점에 보정하던 누적 DDL은 일반 실행 파일에서 제거했다. `orderupgrade.php`와 `adm/dbupgrade.php`에 누적됐던 배포 후 변경은 실제 도입 시점별 마이그레이션으로 이전했다. 조사 근거와 대응 목록은 `database-migration-history.md`에 기록한다.
|