V1 → V2 Staging 마이그레이션 3차 리허설 결과 - 100-hours-a-week/KTB4-4th-wiki GitHub Wiki
NeedU V1 → V2 Staging 마이그레이션 3차 리허설 결과
목차
- 개요
- 마이그레이션 구성 및 절차
- 리허설 타임라인
- MySQL 마이그레이션 결과
- PostgreSQL 마이그레이션 결과
- Write Gate 및 Write Freeze 분석
- ALB V2 전환 및 HTTP 검증
- Gate OFF 이후 조회 API 복구 검증
- k6 조회 부하 테스트 결과
- 발견된 문제 및 원인 분석
- 3차 리허설의 한계
- 4차 리허설 개선 계획
- 최종 결론
1. 개요
1.1 목적
3차 리허설에서는 V1에서 V2 Staging 환경으로의 데이터베이스 및 트래픽 전환 절차를 검증한다.
MySQL은 AWS DMS Full Load + CDC, PostgreSQL은 Dump/Restore 방식으로 이전하고, ALB Write Gate를 이용해 쓰기 요청을 차단한 상태에서 최종 Cutover를 진행한다.
특히 이번 리허설에서는 다음 항목을 중점적으로 검증한다.
- MySQL DMS Full Load 및 CDC 기반 데이터 이전
- PostgreSQL 사전 복원
- V2 ECS 서비스 사전 기동 및 정상 상태 확인
- ALB Write Gate 적용
- V1 MySQL/PostgreSQL 활성 트랜잭션 종료 확인
- DMS 중지 및 MySQL 정책 변환
- ALB Target Group 기반 V1 → V2 전환
- Write Gate 해제 이후 서비스 복구 확인
- k6 10 RPS 조회 부하 테스트
- Cutover 단계별 소요 시간 및 자동화 필요성 분석
1.2 리허설 환경
| 항목 | 구성 |
|---|---|
| 수행 일자 | 2026-10-18 |
| 마이그레이션 대상 | V1 → V2 Staging |
| V1 | EC2, Nginx, MySQL, PostgreSQL |
| V2 | ALB, ECS, RDS MySQL, RDS PostgreSQL |
| MySQL 이전 | AWS DMS Full Load + CDC |
| PostgreSQL 이전 | pg_dump / pg_restore |
| Write Gate | ALB 기반 요청 차단 |
| 트래픽 전환 | ALB Target Group 가중치 변경 |
| Cutover 실행 | 수동 |
| 부하 테스트 | k6, 10 RPS / 60분 계획 |
| 담당 A | Cindy — DB 이전, DMS, ECS, ALB 및 정책 변환 |
| 담당 B | Mond — 트랜잭션 검증, k6, HTTP 검증 및 결과 기록 |
1.3 최종 결과 요약
| 검증 항목 | 결과 | 판정 |
|---|---|---|
| MySQL Full Load | 7개 테이블 이전 확인 | PASS |
| MySQL CDC | Cutover 이전 실행 확인 | PASS |
| PostgreSQL 사전 복원 | 수행 확인 | PASS |
| V2 ECS 사전 상태 | 2/2 Healthy 확인 | PASS |
| Pre-Cutover Smoke Test | 7/7 HTTP 200 | PASS |
| PostgreSQL 활성 트랜잭션 | 2회 연속 0건 | PASS |
| MySQL 활성 트랜잭션 | 2회 연속 0건 | PASS |
| DMS 중지 | 13:20:05 KST | 실행 확인 |
| MySQL 정책 변환 | 13:21:22 KST 완료 | 실행 확인 |
| ALB V2 전환 | 13:22:30 KST 완료 | 실행 확인 |
| Write Gate OFF | 13:24:49 KST | PASS |
| Write Freeze | 4분 50초~5분 49초 | 120초 목표 FAIL |
| Gate OFF 이후 조회 API | HTTP 200, 3회 연속 | PASS |
| Gate OFF 이후 k6 | 1,665건, 비정상 요청 0건 | 관측 구간 PASS |
| k6 60분 본 테스트 | 13:31경 중도 종료 결정 | 미완료 |
| MySQL/PostgreSQL 최종 정합성 | 상세 증빙 미확보 | 확인 필요 |
| RPO 0 | 쓰기 요청 대조 미완료 | 미검증 |
| 실제 서비스 중단 시간 | 별도 계측 미완료 | 미검증 |
종합 판정: Cutover 실행 및 Gate OFF 이후 조회 검증 성공 / Write Freeze 120초 목표 미달 / k6 본 테스트 미완료 / 최종 데이터 정합성 추가 검증 필요
2. 마이그레이션 구성 및 절차
2.1 데이터베이스 이전 방식
| 항목 | V1 | V2 Staging | 이전 방식 |
|---|---|---|---|
| MySQL | EC2 직접 설치 | RDS MySQL | DMS Full Load + CDC |
| PostgreSQL | EC2 직접 설치 | RDS PostgreSQL | pg_dump / pg_restore |
MySQL은 DMS를 통해 초기 데이터를 적재한 후 CDC로 변경 사항을 복제한다.
PostgreSQL은 사전에 Dump/Restore를 수행하여 Cutover 중 복원에 소요되는 시간을 줄인다.
단, PostgreSQL은 DMS CDC 방식이 아니므로 사전 Dump 이후 변경된 데이터의 처리 여부를 별도로 검증해야 한다.
2.2 트래픽 전환 방식
기존 DNS 기반 전환 대신 ALB Target Group 가중치 변경 방식을 사용한다.
Cutover 중에는 ALB Write Gate를 활성화하여 쓰기 요청을 차단하고, DB 동기화 및 전환 작업이 완료된 후 Gate를 해제한다.
2.3 3차 Cutover 절차
- V2 MySQL/PostgreSQL 데이터 사전 준비
- DMS Full Load 및 CDC 실행 확인
- ECS 서비스 Healthy 상태 확인
- Pre-Cutover Smoke Test
- k6 조회 부하 테스트 시작
- Write Gate ON
- PostgreSQL 활성 트랜잭션 확인
- MySQL 활성 트랜잭션 확인
- DMS 중지
- MySQL 정책 변환
- ALB Target Group V2 전환
- FE/BE 연결 확인
- Write Gate OFF
- 조회 API 정상 복구 확인
- k6 조회 부하 결과 확인
이번 리허설은 각 단계를 수동으로 실행했다.
3. 리허설 타임라인
모든 시각은 2026-10-18 KST 기준이다.
3.1 전체 타임라인
| 시각 | 작업 | 결과 |
|---|---|---|
| Cutover 이전 | MySQL DMS Full Load | 7개 테이블 이전 확인 |
| Cutover 이전 | MySQL CDC | 실행 확인 |
| Cutover 이전 | PostgreSQL 사전 복원 | 완료 확인 |
| Cutover 이전 | V2 ECS 상태 확인 | 2/2 Healthy |
| Cutover 이전 | Pre-Cutover Smoke Test | 7/7 HTTP 200 |
| 13:14경 | k6 조회 부하 테스트 시작 | 10 RPS / 60분 계획 |
| 13:19분대 | Write Gate ON | 정확한 초 단위 시각 미확인 |
| 13:19:22 | PostgreSQL 활성 트랜잭션 1차 | 0건 |
| 13:19:27 | PostgreSQL 활성 트랜잭션 2차 | 0건 |
| 13:20:05 | DMS 중지 | Cindy 완료 보고 |
| 13:20:27 | MySQL 활성 트랜잭션 1차 | 0건 |
| 13:20:32 | MySQL 활성 트랜잭션 2차 | 0건 |
| 13:21:22 | MySQL 정책 변환 | 완료 |
| 13:22:30 | ALB V2 전환 | 완료 |
| 13:22:46 | 첫 조회 API 검증 | HTTP 503 |
| 13:22:49 | FE/BE 연결 확인 | FE 307, BE 401 |
| 13:23:11 | HTTP 503 원인 확인 시작 | MIGRATION_IN_PROGRESS 확인 |
| 13:24:49 | Write Gate OFF | Disabled 확인 |
| 13:24:49 | Gate OFF 직후 HTTP 확인 | 403, CSRF 토큰 만료 |
| 13:26:17~13:26:23 | 조회 API 재검증 | HTTP 200, 3회 연속 |
| Gate OFF 이후 | k6 중간 집계 | 1,665건, 비정상 0건 |
| 13:31경 | 리허설 종료 논의 | 자동화 도입 결정, k6 중단 합의 |
3.2 타임라인 분석
Cutover 자체는 실행됐지만, Write Gate ON 이후 여러 작업을 수동으로 수행하면서 쓰기 차단 시간이 길어졌다.
특히 다음 순서가 확인된다.
- 13:20:05 — DMS 중지
- 13:20:27~13:20:32 — MySQL 활성 트랜잭션 확인
- 13:21:22 — MySQL 정책 변환 완료
- 13:22:30 — ALB V2 전환
- 13:24:49 — Write Gate OFF
MySQL 활성 트랜잭션 검증은 DMS 중지 이후에 완료됐다.
이는 사전에 계획한 검증 순서와 실제 실행 순서가 달랐음을 의미한다.
4차에서는 DMS 중지 전 필수 검증 완료 여부를 자동으로 확인하도록 개선할 필요가 있다.
4. MySQL 마이그레이션 결과
4.1 DMS Full Load 및 CDC
| 항목 | 결과 |
|---|---|
| Source | V1 MySQL |
| Target | V2 Staging RDS MySQL |
| 방식 | Full Load + CDC |
| 대상 테이블 | 7개 |
| Full Load | 완료 확인 |
| CDC | Cutover 이전 실행 확인 |
| DMS 중지 | 13:20:05 KST |
| 최종 Validation 결과 | 확인 필요 |
MySQL 데이터는 DMS를 통해 이전했으며, Cutover 중 DMS 중지 작업을 수행했다.
4.2 활성 트랜잭션 검증
MySQL에서는 InnoDB 활성 트랜잭션을 조회했다.
| 확인 시각 | 활성 트랜잭션 |
|---|---|
| 13:20:27 | 0 |
| 13:20:32 | 0 |
5초 간격으로 두 차례 확인한 결과 모두 0건이었다.
판정: 활성 트랜잭션 검증 PASS
다만 이 결과는 해당 조회 시점에 활성 트랜잭션이 없었다는 의미다. 신규 쓰기 차단의 완전성이나 데이터 정합성 전체를 증명하는 결과는 아니다.
4.3 DMS 중지 순서 문제
실제 실행 순서는 다음과 같다.
- 13:20:05 — DMS 중지
- 13:20:27 — MySQL 활성 트랜잭션 1차 확인
- 13:20:32 — MySQL 활성 트랜잭션 2차 확인
따라서 DMS 중지 전에 MySQL 활성 트랜잭션 0건을 확인했다는 판정은 할 수 없다.
DMS 중지 시점과 MySQL 트랜잭션 검증 사이에는 22~27초의 차이가 있었다.
이 구간에 데이터 변경이 없었는지는 현재 기록만으로 확정할 수 없다.
4.4 MySQL 정책 변환
| 항목 | 결과 |
|---|---|
| 시작 | DMS 중지 이후 |
| 완료 | 13:21:22 KST |
| 작업 | MySQL 정책 변환 |
| 실행 결과 | 완료 보고 |
| 정책 변환 세부 SQL 검증 | 확인 필요 |
판정: 정책 변환 실행 완료
5. PostgreSQL 마이그레이션 결과
5.1 사전 복원
PostgreSQL은 pg_dump / pg_restore 방식으로 사전 복원했다.
| 항목 | 결과 |
|---|---|
| Source | V1 PostgreSQL |
| Target | V2 Staging RDS PostgreSQL |
| 이전 방식 | Dump/Restore |
| 복원 시점 | Cutover 이전 |
| 복원 여부 | 완료 확인 |
| 최종 정합성 | 확인 필요 |
5.2 활성 트랜잭션 검증
PostgreSQL에서는 xact_start IS NOT NULL 조건을 사용했다.
이 조건을 통해 idle in transaction 상태도 확인 범위에 포함했다.
| 확인 시각 | 활성 트랜잭션 |
|---|---|
| 13:19:22 | 0 |
| 13:19:27 | 0 |
두 차례 모두 0건이었다.
판정: PostgreSQL 활성 트랜잭션 검증 PASS
5.3 PostgreSQL 정합성 관련 한계
PostgreSQL은 MySQL과 달리 이번 리허설에서 DMS CDC로 이전하지 않았다.
따라서 다음 항목은 별도 확인이 필요하다.
- Dump 이후 V1에서 발생한 변경 데이터
- V1/V2 테이블별 행 수 비교
- 주요 PK 및 데이터 값 비교
- pgvector 확장 및 인덱스 상태
- Cutover 이후 V2 신규 쓰기 결과
판정: 사전 복원 및 트랜잭션 검증 PASS / 최종 정합성 확인 필요
6. Write Gate 및 Write Freeze 분석
6.1 Write Gate 적용 목적
Write Gate는 Cutover 동안 신규 쓰기 요청을 차단하여 V1과 V2 사이의 데이터 불일치 가능성을 줄이기 위한 장치다.
6.2 Write Gate 실행 결과
| 항목 | 결과 |
|---|---|
| Gate ON | 13:19분대 KST |
| Gate ON 정확한 초 | 미확인 |
| ALB V2 전환 | 13:22:30 KST |
| Gate OFF | 13:24:49 KST |
| Gate OFF 확인 | Disabled |
| Gate OFF 직후 응답 | HTTP 403, CSRF 토큰 만료 |
Gate OFF 이후 확인된 HTTP 403은 MIGRATION_IN_PROGRESS 응답이 아니라 CSRF 토큰 만료 응답이었다.
따라서 Gate가 계속 활성화돼 있었다는 증거로 볼 수 없다.
6.3 Write Freeze 지속 시간
Write Freeze는 Write Gate ON부터 OFF까지의 시간으로 정의한다.
Gate ON은 13:19분대로만 기록되어 있다.
Gate ON이 13:19:00~13:19:59 사이였다면 Write Freeze는 다음 범위에 해당한다.
| Gate ON 가정 | Gate OFF | Write Freeze |
|---|---|---|
| 13:19:00 | 13:24:49 | 5분 49초 |
| 13:19:59 | 13:24:49 | 4분 50초 |
따라서 Write Freeze는 4분 50초~5분 49초 범위로 추정된다.
| 항목 | 결과 |
|---|---|
| Write Freeze | 4분 50초~5분 49초 |
| 정확한 소요 시간 | Gate ON 초 단위 로그 필요 |
| 120초 이내 목표 | FAIL |
| 5분 이내 여부 | 정확한 Gate ON 시각 없이는 확정 불가 |
판정: Write Freeze 120초 목표 FAIL
6.4 목표 미달 원인
이번 Cutover는 수동으로 진행했다.
Gate ON 이후 다음 작업을 순차적으로 실행했다.
- PostgreSQL 트랜잭션 검증
- DMS 중지
- MySQL 트랜잭션 검증
- MySQL 정책 변환
- ALB V2 전환
- FE/BE 연결 확인
- HTTP 503 원인 확인
- Write Gate OFF
작업 간 명령 실행 및 확인 시간이 누적되면서 Write Freeze가 길어졌다.
6.5 Write Freeze와 서비스 중단 시간의 차이
Write Freeze는 쓰기 요청을 차단한 시간이다.
전체 서비스의 읽기 요청이 중단된 시간과 동일하지 않다.
특히 이번에는 Write Gate ON 상태에서 조회 API가 HTTP 503을 반환했다.
따라서 실제 읽기 영향 여부와 시간을 별도로 분석해야 한다.
7. ALB V2 전환 및 HTTP 검증
7.1 ALB 전환
| 항목 | 결과 |
|---|---|
| 전환 방식 | ALB Target Group 가중치 변경 |
| 전환 대상 | V1 → V2 |
| 전환 완료 | 13:22:30 KST |
7.2 ALB 전환 직후 첫 조회 검증
| 항목 | 결과 |
|---|---|
| 확인 시각 | 13:22:46 KST |
| 요청 | GET /api/v1/auth/csrf |
| HTTP 상태 | 503 |
| 응답 시간 | 27.816ms |
| Gate 상태 | ON |
첫 조회 검증은 HTTP 503을 반환했다.
이후 응답 본문을 확인했다.
| 항목 | 결과 |
|---|---|
| 응답 본문 확인 시작 | 13:23:11 KST |
| HTTP 상태 | 503 |
| 응답 코드 | MIGRATION_IN_PROGRESS |
| 응답 서버 | awselb/2.0 |
해당 503은 Write Gate로 인한 의도된 차단 응답으로 확인됐다.
따라서 애플리케이션 장애로 분류하지 않는다.
다만 Write Gate가 활성화된 상태에서 해당 조회 API가 정상 응답하지 못했다는 사실은 별도로 기록해야 한다.
7.3 FE/BE 연결 확인
Cindy가 ALB 전환 이후 FE/BE 연결을 확인했다.
| 항목 | 시각 | HTTP 상태 | 응답 시간 |
|---|---|---|---|
| Frontend | 13:22:49 | 307 | 0.136645s |
| Backend | 13:22:49 | 401 | 0.069376s |
HTTP 307은 리다이렉트 응답이며, HTTP 401은 인증이 필요한 요청에 대한 응답일 수 있다.
따라서 이 결과만으로 전체 서비스 기능 정상 동작을 입증할 수는 없지만, 요청 경로가 응답하고 있음을 확인하는 근거로 사용할 수 있다.
7.4 Gate OFF 이후 응답
13:24:49 KST에 Write Gate Disabled 상태가 확인됐다.
동일 시점의 응답은 다음과 같았다.
{
"message": "보안 토큰이 만료되었습니다. 다시 시도해 주세요.",
"data": {
"csrfTokenRefreshRequired": true
}
}
HTTP 상태는 403이었다.
이는 이전의 MIGRATION_IN_PROGRESS 503과 다른 응답이다.
판정: ALB 전환 실행 확인 / Write Gate 해제 확인
8. Gate OFF 이후 조회 API 복구 검증
8.1 검증 목적
Write Gate 해제 이후 V2 조회 API가 정상 응답하는지 확인한다.
8.2 테스트 결과
| 항목 | 결과 |
|---|---|
| Gate OFF | 13:24:49 KST |
| 조회 검증 시작 | 13:26:17 KST |
| 조회 검증 종료 | 13:26:23 KST |
| 요청 | GET /api/v1/auth/csrf |
| 총 요청 | 3회 |
| HTTP 200 | 3회 |
| HTTP 503 | 0회 |
8.3 응답 시간
| 요청 | HTTP 상태 | 응답 시간 |
|---|---|---|
| 1차 | 200 | 29.270ms |
| 2차 | 200 | 37.954ms |
| 3차 | 200 | 36.112ms |
3회 연속 HTTP 200을 확인했다.
판정: Gate OFF 이후 조회 API 복구 PASS
8.4 검증 한계
Gate OFF 시각은 13:24:49이며, HTTP 200을 확인한 최초 시각은 13:26:17이다.
두 시각의 차이는 1분 28초다.
그러나 이 시간 전체가 서비스 복구에 소요됐다는 의미는 아니다.
그 사이에 지속적으로 요청을 보내 정상 응답 최초 발생 시점을 측정한 기록이 없기 때문이다.
따라서 실제 복구 소요 시간을 88초로 판정하지 않는다.
9. k6 조회 부하 테스트 결과
9.1 테스트 목적
Cutover 전후 지속적으로 조회 요청을 보내 V2 전환 이후 서비스 응답 상태를 확인한다.
9.2 테스트 설정
| 항목 | 설정 |
|---|---|
| 도구 | Grafana k6 |
| 테스트 대상 | staging.needu.gift |
| 요청 유형 | 조회 API |
| 목표 RPS | 10 |
| 목표 테스트 시간 | 60분 |
| 시작 시각 | 13:14경 KST |
| 종료 | 13:31경 중단 합의 |
9.3 Gate OFF 이후 중간 결과
| 항목 | 결과 |
|---|---|
| Gate OFF | 13:24:49 KST |
| 집계 요청 | 1,665건 |
| 비정상 요청 | 0건 |
| 관측 성공률 | 100% |
| 60분 본 테스트 | 미완료 |
Gate OFF 이후 집계된 1,665건에서 비정상 요청은 확인되지 않았다.
판정: Gate OFF 이후 관측 구간 PASS
9.4 전체 테스트 판정
13:31경 Cindy가 수동 Cutover의 시간 지연 문제를 제기하며 GitHub Actions 기반 통합 워크플로 도입을 제안했다.
이후 자동화 적용 후 다시 리허설을 진행하기로 합의했고, k6 테스트를 중단하기로 결정했다.
따라서 60분 본 테스트는 완료되지 않았다.
9.5 검증 한계
- 60분 전체 부하 테스트 미완료
- Cutover 중 요청별 상태 코드 시계열 미확보
- 최초 실패 및 복구 시각 미확보
- 전체 테스트 p95/p99 결과 미확보
- 실제 읽기 서비스 영향 시간 미확정
특히 Gate OFF 이후 비정상 요청이 0건이었다는 결과만으로 Cutover 전체 구간이 무중단이었다고 판단할 수 없다.
최종 판정: Gate OFF 이후 조회 부하 정상 / 60분 테스트 미완료
10. 발견된 문제 및 원인 분석
10.1 수동 Cutover로 인한 Write Freeze 증가
현상
Write Freeze가 최소 4분 50초 이상 지속됐다.
원인
Write Gate ON 이후 여러 단계를 수동으로 수행했다.
- DB 활성 트랜잭션 확인
- DMS 중지
- MySQL 정책 변환
- ALB 전환
- FE/BE 연결 확인
- 503 원인 분석
- Write Gate 해제
영향
- 120초 Write Freeze 목표 미달
- Cutover 진행 시간 증가
- 운영 환경에서 반복 실행 시 작업 실수 가능성 증가
개선 방향
GitHub Actions 기반 통합 Cutover 워크플로를 구현한다.
10.2 DMS 중지와 MySQL 트랜잭션 검증 순서 불일치
현상
DMS는 13:20:05에 중지됐지만 MySQL 활성 트랜잭션 검증은 13:20:27~13:20:32에 완료됐다.
문제점
DMS 중지 전 MySQL 활성 트랜잭션 0건을 확인하지 못했다.
개선 방향
자동화에서 다음 순서를 강제한다.
- Write Gate ON
- PostgreSQL 활성 트랜잭션 2회 연속 0건
- MySQL 활성 트랜잭션 2회 연속 0건
- DMS CDC 최종 상태 확인
- DMS 중지
필수 검증 실패 시 다음 단계로 진행하지 않도록 한다.
10.3 Write Gate ON 상태에서 조회 API 503
현상
13:22:46에 GET /api/v1/auth/csrf가 HTTP 503을 반환했다.
원인
ALB Write Gate에 의한 MIGRATION_IN_PROGRESS 응답이었다.
분석
애플리케이션 장애는 아니지만, 해당 조회 API가 Write Gate의 차단 대상에 포함된 사실이 확인됐다.
Write Gate가 쓰기 요청만 차단하도록 설계됐다면 Listener Rule의 HTTP Method 및 Path 조건을 검토해야 한다.
개선 방향
- GET 요청과 POST/PUT/PATCH/DELETE 요청 분리 검증
- Write Gate 적용 대상 Path 확인
- 의도된 503과 실제 서비스 장애 구분
- Gate ON 중 읽기 요청 정상 처리 여부 별도 검증
10.4 Write Gate OFF 이후 검증 지연
현상
Gate OFF는 13:24:49에 확인됐지만 HTTP 200 재검증은 13:26:17에 시작됐다.
문제점
Gate OFF 직후부터 최초 정상 응답까지의 실제 시간을 측정하지 못했다.
개선 방향
Gate OFF 직후 자동 Smoke Test를 실행하고, 최초 정상 응답 시각을 기록한다.
10.5 k6 본 테스트 중도 종료
현상
10 RPS / 60분 테스트를 완료하지 못했다.
원인
수동 Cutover 시간 증가와 자동화 필요성에 대한 팀 논의로 리허설을 중단했다.
개선 방향
Cutover 자동화 적용 이후 동일 조건으로 재시험한다.
11. 3차 리허설의 한계
11.1 최종 데이터 정합성 미확정
MySQL DMS Full Load 및 CDC 실행, PostgreSQL 사전 복원은 확인됐다.
하지만 V1/V2의 최종 행 수, PK, 주요 컬럼을 비교한 상세 결과는 확보되지 않았다.
11.2 RPO 0 미검증
성공 응답을 받은 모든 쓰기 요청이 V2 DB에 반영됐는지 대조하지 않았다.
따라서 RPO 0을 입증할 수 없다.
11.3 Cutover 중 실제 서비스 중단 시간 미측정
Write Gate ON/OFF 시각과 일부 HTTP 검증 결과는 있지만, 전체 Cutover 동안의 연속적인 요청별 성공·실패 시각은 확보되지 않았다.
따라서 실제 서비스 중단 시간을 확정할 수 없다.
11.4 V2 신규 쓰기 검증 결과 미확보
Gate OFF 이후 조회 API 정상 응답은 확인했다.
그러나 V2 MySQL/PostgreSQL에 신규 쓰기가 정상 반영됐는지에 대한 DB 수준 검증 결과는 확보되지 않았다.
11.5 자동 롤백 미구현
Cutover 단계별 실패 시 복구 정책이 자동화되지 않았다.
특히 V2에서 신규 쓰기가 발생한 이후에는 단순히 ALB를 V1으로 되돌리는 방식으로 복구할 수 없다.
12. 4차 리허설 개선 계획
12.1 개선 목표
3차 리허설에서 확인된 가장 큰 문제는 수동 Cutover로 인한 Write Freeze 증가다.
4차에서는 GitHub Actions 기반 Cutover 자동화를 적용한다.
목표: Write Freeze 120초 이내
12.2 개선 항목
| 항목 | 3차 결과 | 4차 개선 방향 |
|---|---|---|
| Cutover 실행 | 수동 | GitHub Actions 자동화 |
| Preflight | 수동 확인 | 자동 검증 |
| 활성 트랜잭션 | 수동 SQL 조회 | 자동 확인 |
| DMS 중지 | 수동 | 조건 충족 후 자동 중지 |
| MySQL 정책 변환 | 수동 | 자동 실행 |
| ALB 전환 | 수동 | Target Group 가중치 자동 변경 |
| Write Gate | 수동 ON/OFF | 자동 ON/OFF |
| 단계별 시간 | 일부 수동 기록 | 시작·종료 시각 자동 기록 |
| Write Freeze | 4분 50초~5분 49초 | 120초 이내 |
| HTTP 검증 | 수동 | 전환 전후 Smoke Test 자동화 |
| 실패 처리 | 수동 판단 | 단계별 Fail-closed 정책 |
12.3 자동 Cutover 절차
- Preflight 실행
- MySQL/PostgreSQL/DMS/ECS 상태 확인
- Write Gate ON
- PostgreSQL 활성 트랜잭션 0건 확인
- MySQL 활성 트랜잭션 0건 확인
- DMS CDC 최종 동기화 확인
- DMS 중지 및 완료 대기
- MySQL 정책 변환
- ALB Backend V2 전환
- ALB Frontend V2 전환
- Target Health 확인
- Write Gate OFF
- Smoke Test 실행
- 단계별 결과 및 Write Freeze 시간 기록
12.4 실패 시 처리 원칙
| 실패 단계 | 대응 원칙 |
|---|---|
| Gate ON 이전 | Cutover 중단, 기존 서비스 유지 |
| Gate ON 이후 / DMS 중지 전 | CDC 유지, 안전 상태 확인 후 Gate 해제 검토 |
| DMS 중지 이후 / V2 쓰기 전 | DB 동기화 및 ALB 상태 확인 후 복구 방향 결정 |
| V2 쓰기 발생 이후 | 자동 V1 원복 금지, 신규 쓰기 차단 및 데이터 정합성 확인 |
단순히 모든 오류에서 Gate OFF 또는 ALB V1 복귀를 수행하면 데이터 불일치가 발생할 수 있다.
따라서 실패 단계와 데이터베이스 쓰기 상태에 따라 복구 정책을 구분한다.
13. 최종 결론
2026년 10월 18일 진행한 V1 → V2 Staging 마이그레이션 3차 리허설에서는 MySQL DMS Full Load + CDC, PostgreSQL 사전 복원, ECS 사전 기동 및 ALB Target Group 기반 Cutover 절차를 실행했다.
PostgreSQL과 MySQL 활성 트랜잭션은 각각 5초 간격으로 두 차례 확인했으며 모두 0건이었다.
DMS는 13:20:05 KST에 중지됐고, MySQL 정책 변환은 13:21:22 KST에 완료됐다.
ALB V2 전환은 13:22:30 KST에 완료됐으며, Write Gate는 13:24:49 KST에 해제됐다.
Write Freeze는 Gate ON의 정확한 초 단위 시각이 없어 확정할 수 없지만, 4분 50초~5분 49초 범위로 추정된다. 따라서 120초 이내 목표는 달성하지 못했다.
ALB 전환 직후 조회 API에서 발생한 HTTP 503은 MIGRATION_IN_PROGRESS 응답으로, Write Gate에 의한 의도된 차단으로 확인됐다.
Gate OFF 이후 /api/v1/auth/csrf는 HTTP 200을 3회 연속 반환했으며, k6 중간 집계에서도 1,665건의 요청 중 비정상 요청은 0건이었다.
다만 k6 60분 테스트는 중도 종료됐고, 최종 데이터 정합성 및 실제 서비스 중단 시간은 검증되지 않았다.
최종 판정
| 구분 | 판정 |
|---|---|
| 데이터 이전 절차 | 실행 확인 |
| 활성 트랜잭션 검증 | PASS |
| ALB V2 Cutover | 실행 확인 |
| Write Gate 해제 | PASS |
| Write Freeze 120초 목표 | FAIL |
| Gate OFF 이후 조회 API | PASS |
| Gate OFF 이후 k6 관측 구간 | PASS |
| k6 60분 본 테스트 | 미완료 |
| RPO 0 | 미검증 |
| 실제 서비스 중단 시간 | 미검증 |
종합 판정: Cutover 실행 성공 및 전환 이후 조회 검증 PASS / Write Freeze 목표 FAIL / 자동화 개선 필요
3차 리허설을 통해 수동 Cutover 절차의 시간적 한계와 검증 순서 문제를 확인했다.
이에 따라 4차 리허설에서는 GitHub Actions 기반 통합 Cutover 워크플로를 적용하여 작업 순서를 표준화하고, Write Freeze를 120초 이내로 단축하는 것을 핵심 개선 목표로 설정한다.