feat(migrations): 스키마 baseline 스냅샷 — fresh-DB/DR 부팅 fix (R1)
R0 가 입증했듯 migrations/ 전체 replay 는 011(view active_documents 가 documents.embedding 의존, DROP COLUMN CASCADE 부재)·326(enum-same-txn) 등 누적 비-replayable 로 깨져 신규/DR 환경 init_db 부팅이 불가능했다. 표준 squash baseline 로 해소: - migrations/_baseline/0358_schema_baseline.sql: prod 스키마 스냅샷(pg_dump --schema-only --no-owner --no-privileges, psql 메타·search_path='' 정리 = asyncpg exec_driver_sql 호환). - init_db._load_baseline_if_fresh: documents 테이블 부재(fresh) 시 baseline 적재 + schema_migrations 1..358 스탬프 → 이후 post-baseline(359/360)만 적용. ★기존 DB(documents 존재)는 skip = prod 무영향(additive). baseline 부재 시 기존 replay 경로(하위호환). - migration_smoke: baseline 경로 검증. ★실측 — 이전 FAIL(011 abort) → 이제 FRESH/INCREMENTAL 모두 PASS (pg16.14). cutoff(_BASELINE_CUTOFF=358) 갱신 시 baseline 재생성. 검증: py_compile + migration_smoke PASS. ★boot-path 변경이라 deploy 전 staging 부팅 검증 필수. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -77,28 +77,41 @@ run_scenario() {
|
||||
fi
|
||||
}
|
||||
|
||||
scenario_fresh() {
|
||||
reset_db
|
||||
emit_single_txn "${MIGS[@]}" | psql_exec -d "$DB"
|
||||
}
|
||||
BASELINE_CUTOFF=358
|
||||
BASELINE_FILE="$MIG_DIR/_baseline/0358_schema_baseline.sql"
|
||||
|
||||
scenario_dr() {
|
||||
reset_db
|
||||
local phase1=() phase2=() f base ver p1out p1rc
|
||||
# post-baseline(버전 > cutoff) 마이그 파일만 출력
|
||||
_post_baseline() {
|
||||
local f base ver
|
||||
for f in "${MIGS[@]}"; do
|
||||
base="$(basename "$f")"; ver="${base%%_*}"; ver="$((10#$ver))"
|
||||
if [ "$ver" -le 319 ]; then phase1+=("$f"); else phase2+=("$f"); fi
|
||||
[ "$ver" -gt "$BASELINE_CUTOFF" ] && printf '%s\n' "$f"
|
||||
done
|
||||
# phase1: 001~319 자동커밋 (과거 운영 DB = 타입/값 모두 커밋된 상태)
|
||||
p1out="$( emit_autocommit "${phase1[@]}" 2>/dev/null | psql_exec -d "$DB" 2>&1 )"; p1rc=$?
|
||||
if [ "$p1rc" -ne 0 ]; then
|
||||
local p1last; p1last="$(printf '%s\n' "$p1out" | grep '>>>APPLY' | tail -1 | sed 's/>>>APPLY //')"
|
||||
printf '%s\n' ">>>APPLY ${p1last}" # run_scenario 가 마지막 마커를 읽도록 전달
|
||||
printf '%s\n' "$p1out" | grep -iE 'ERROR|unsafe|DETAIL' | head -2
|
||||
return 1
|
||||
}
|
||||
|
||||
# FRESH — init_db fresh 경로 미러: baseline 적재 + post-baseline 을 단일 트랜잭션
|
||||
scenario_fresh() {
|
||||
reset_db
|
||||
local post=(); while IFS= read -r f; do post+=("$f"); done < <(_post_baseline)
|
||||
{
|
||||
echo '\set ON_ERROR_STOP on'; echo 'BEGIN;'
|
||||
echo "\\echo >>>APPLY _baseline"
|
||||
cat "$BASELINE_FILE"; echo
|
||||
for f in "${post[@]}"; do
|
||||
echo "\\echo >>>APPLY $(basename "$f")"; cat "$f"; echo
|
||||
done
|
||||
echo 'COMMIT;'
|
||||
} | psql_exec -d "$DB"
|
||||
}
|
||||
|
||||
# INCREMENTAL — 기존 운영 DB(at cutoff) 모사: baseline 커밋 후 post-baseline 을 별 트랜잭션
|
||||
scenario_dr() {
|
||||
reset_db
|
||||
if ! { echo '\set ON_ERROR_STOP on'; cat "$BASELINE_FILE"; } | psql_exec -d "$DB" >/dev/null 2>&1; then
|
||||
printf '%s\n' ">>>APPLY _baseline"; echo "baseline 적재 실패"; return 1
|
||||
fi
|
||||
# phase2: 320~end 단일 트랜잭션 (catch-up 업그레이드)
|
||||
emit_single_txn "${phase2[@]}" 2>/dev/null | psql_exec -d "$DB"
|
||||
local post=(); while IFS= read -r f; do post+=("$f"); done < <(_post_baseline)
|
||||
emit_single_txn "${post[@]}" 2>/dev/null | psql_exec -d "$DB"
|
||||
}
|
||||
|
||||
# ── 컨테이너 기동 ──
|
||||
@@ -109,17 +122,17 @@ echo "pg: $(docker exec "$CNAME" psql -U postgres -tAc 'show server_version' 2>/
|
||||
echo
|
||||
|
||||
fail=0
|
||||
echo "── FRESH (빈 DB 단일 트랜잭션) ──"
|
||||
echo "── FRESH (baseline 적재 + post-baseline 단일 트랜잭션 = init_db fresh 경로) ──"
|
||||
run_scenario FRESH scenario_fresh || fail=1
|
||||
echo
|
||||
echo "── DR (001~319 커밋 후 320~end 단일 트랜잭션) ──"
|
||||
echo "── INCREMENTAL (baseline 커밋 후 post-baseline 별 트랜잭션 = 기존 DB 증분) ──"
|
||||
run_scenario DR scenario_dr || fail=1
|
||||
echo
|
||||
|
||||
if [ "$fail" -eq 0 ]; then
|
||||
echo "RESULT: PASS — 빈 DB/DR 모두 단일 트랜잭션 적용 가능 (enum-barrier 적용됨)"
|
||||
echo "RESULT: PASS — fresh/incremental 모두 baseline+post-baseline 적용 가능"
|
||||
exit 0
|
||||
else
|
||||
echo "RESULT: FAIL — 위 지점에서 단일 트랜잭션 적용 불가 (enum-same-txn 등 미수정)"
|
||||
echo "RESULT: FAIL — baseline/post-baseline 적용 불가 (위 지점)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user