NeedU V1 → V2 2차 마이그레이션 리허설 결과 보고서 - 100-hours-a-week/KTB4-4th-wiki GitHub Wiki
목차
- 개요
- 마이그레이션 구성
- 리허설 타임라인
- MySQL 마이그레이션 검증
- PostgreSQL 마이그레이션 검증
- Write Gate 동작 검증
- k6 지속 부하 테스트
- V2 ECS 및 ALB 전환 검증
- 전환 후 HTTP 오류 및 복구 검증
- V2 쓰기 검증
- Write Gate 지속 시간 및 병목 분석
- 모니터링 및 관측성
- 한계 및 미검증 항목
- 3차 리허설 개선 계획
- 최종 결론
1. 개요
1.1 목적
1차 리허설에서 확인한 V1 → V2 데이터 이전 및 서비스 전환 절차를 개선하고, 전환 중 서비스 요청 실패와 복구 시간을 측정한다.
특히 1차에서 발생한 Write Freeze 이후 긴 전환 시간과 DNS 전환의 불확실성을 줄이고, 지속적인 부하가 발생하는 상황에서 V2 전환 및 쓰기 재개가 정상적으로 이루어지는지 검증한다.
주요 검증 목표는 다음과 같다.
- MySQL DMS Full Load + CDC 기반 데이터 이전 검증
- PostgreSQL Dump/Restore 기반 데이터 이전 검증
- V1/V2 Write Gate 적용 및 해제 검증
- 공통 ALB 기반 V1 → V2 트래픽 전환 검증
- k6 10 RPS 지속 부하 중 HTTP 오류 및 복구 시간 측정
- V2 ECS 정상 동작 및 RDS 신규 쓰기 검증
- 1차 대비 Write Gate 유지 시간 단축 여부 확인
- 데이터 정합성 및 운영 전환 전 잔여 위험 식별
1.2 리허설 환경
| 항목 | 내용 |
|---|---|
| 수행 일자 | 2026-10-17 |
| 대상 | V1 → V2 Staging |
| 전환 방식 | 공통 ALB 기반 가중치 전환 |
| V1 | EC2 + Nginx + MySQL + PostgreSQL |
| V2 | ALB + ECS(FE/BE/AI) + RDS MySQL/PostgreSQL |
| MySQL 이전 | AWS DMS Full Load + CDC |
| PostgreSQL 이전 | pg_dump / pg_restore |
| 쓰기 제어 | Write Gate |
| 부하 테스트 | k6, 10 RPS / 60분 |
| Cloud A | Cindy — DMS, MySQL, ECS, ALB 및 전환 절차 |
| Cloud B | Mond — k6, PostgreSQL, 데이터 비교 및 전환 후 검증 |
1.3 최종 검증 결과
| 검증 항목 | 결과 | 판정 |
|---|---|---|
| MySQL DMS | 7개 테이블 Validated | PASS |
| DMS Pending / Validation Error | 0건 / 0건 | PASS |
| MySQL 건수 비교 | 4개 일치, 3개 V2 추가 레코드 확인 | 기본 검증 PASS |
| DMS 제외 테이블 | 기존 메시지·추천·취향 데이터 미이관 | 추가 검토 |
| PostgreSQL 이전 | 4개 테이블 행 수 일치 | PASS |
| PostgreSQL 구조 | vector 컬럼 및 HNSW 인덱스 확인 | PASS |
| V2 ALB | V1 0%, V2 100% | PASS |
| V2 ECS | FE/BE/AI 각 2 Tasks, Backend TG 2/2 Healthy | PASS |
| V2 신규 쓰기 | 인증 세션, 친구, 채팅방, 메시지 확인 | PASS |
| k6 전체 요청 | 35,944건 중 34,692건 성공 | FAIL |
| k6 전체 Threshold | 실패 1,252건, Drop 57건 | FAIL |
| Gate 해제 후 안정화 | 마지막 실패 이후 약 47분간 오류 0건 | 관측 PASS |
| Write Gate 유지 | 10분 30초 | 1차 대비 단축 |
| RPO 0 | 성공한 원본 쓰기와 대상 데이터 전수 대조 미수행 | 미검증 |
종합 판정: 서비스 전환 및 기본 DB 검증 성공 / k6 전체 Threshold FAIL / 데이터 이관 완전성 및 RPO 0 추가 검증 필요
2. 마이그레이션 구성
2.1 V1 환경
- 단일 EC2 기반 서비스
- Nginx 기반 라우팅
- Frontend, Backend, AI Server 실행
- MySQL 및 PostgreSQL 직접 설치
- V1 Write Gate 적용
- DMS Source 및 PostgreSQL Dump Source
2.2 V2 Staging 환경
- ALB 기반 트래픽 수신
- ECS Frontend / Backend / AI Server
- RDS MySQL 및 PostgreSQL
- MySQL DMS Target
- PostgreSQL Dump/Restore Target
- 전환 후 V2 신규 쓰기 검증
2.3 데이터 이전 방식
| 데이터베이스 | 이전 방식 | 최종 동기화 |
|---|---|---|
| MySQL | DMS Full Load + CDC | Write Gate 이후 CDC 및 Validation 확인 |
| PostgreSQL | pg_dump / pg_restore | 최종 Dump를 V2 RDS에 Restore |
MySQL은 CDC 기반 복제를 사용하고, PostgreSQL은 Dump/Restore를 사용했다.
따라서 MySQL의 CDC 지연·Validation과 PostgreSQL의 Dump 시점·복원 정합성을 별도로 검증해야 한다.
2.4 1차 대비 변경 사항
| 항목 | 1차 | 2차 |
|---|---|---|
| 트래픽 전환 | DNS 전환 | 공통 ALB 가중치 전환 |
| 쓰기 제어 | V1 Nginx Write Freeze | V1/V2 Write Gate |
| 부하 테스트 | V1 직접 조회 90분 | 전환 과정 포함 k6 60분 |
| 전환 후 검증 | Smoke Test 및 인증 세션 | 인증·친구·채팅 데이터 검증 |
| 핵심 측정 | Freeze → DNS 전환 | Gate 유지 및 HTTP 오류 복구 |
3. 리허설 타임라인
모든 시각은 KST 기준이다.
3.1 주요 수행 시각
| 시각 | 단계 | 작업 및 결과 |
|---|---|---|
| 22:18:35 | PostgreSQL | V1 Dump 수행 확인 |
| 22:39경 | k6 | 10 RPS 지속 부하 시작 |
| 22:40:19.115060 | k6 | 최초 Dropped Iteration |
| 22:41:30 | Write Gate | 활성화 |
| 22:43:26.007724 | k6 | 마지막 Dropped Iteration |
| 22:44:30 | DMS | Stopped 상태 확인 |
| 22:52:00 | Write Gate | 해제 |
| 22:52:28.828112 | k6 | 마지막 HTTP 실패 |
| 22:52:29 이후 | k6 | 추가 HTTP 실패 미관측 |
| 23:39:36 | k6 | 60분 테스트 종료 |
PostgreSQL Restore 완료, ALB 가중치 변경 및 ECS 기동의 정확한 시각은 확인된 기록이 없어 기재하지 않았다.
3.2 주요 소요 시간
| 측정 구간 | 소요 시간 |
|---|---|
| Write Gate ON → DMS Stopped 확인 | 3분 |
| DMS Stopped 확인 → Write Gate OFF | 7분 30초 |
| Write Gate ON → OFF | 10분 30초 |
| Write Gate OFF → 마지막 HTTP 실패 | 약 28.83초 |
| 마지막 HTTP 실패 이후 → k6 종료 | 약 47분 7초 |
3.3 1차 대비 시간 비교
| 지표 | 1차 | 2차 |
|---|---|---|
| Freeze/Gate 적용 시각 | 16:58:25 | 22:41:30 |
| DMS Stopped 확인 | 17:06:20 | 22:44:30 |
| Freeze/Gate → DMS Stopped | 7분 55초 | 3분 |
| Freeze/Gate → 트래픽 전환 | 약 23분 35초 | 정확한 시각 미확인 |
| Gate 유지 시간 | 정확한 해제 시각 미확인 | 10분 30초 |
1차의 Freeze → DNS 전환 시간과 2차의 Gate ON → OFF 시간은 종료 기준이 달라 직접적인 동일 지표 비교가 아니다.
다만 Freeze/Gate 적용부터 DMS Stopped 확인까지는 7분 55초에서 3분으로 단축됐다.
4. MySQL 마이그레이션 검증
4.1 DMS Full Load 및 CDC
| 검증 항목 | 결과 |
|---|---|
| DMS Task | needu-v1-to-v2-staging |
| 방식 | Full Load + CDC |
| 최종 상태 | stopped |
| 중지 확인 | 22:44:30 KST |
| 복제 대상 | 7개 테이블 |
| Validation | 7개 테이블 Validated |
| Pending Changes | 0건 |
| Validation Errors | 0건 |
판정: PASS — DMS 복제 대상 기준
4.2 DMS Table Mapping
실제 DMS Selection Rule을 AWS CLI로 조회한 결과 다음 7개 테이블이 복제 대상이었다.
| 테이블 | 복제 여부 |
|---|---|
| users | 포함 |
| auth_sessions | 포함 |
| friends | 포함 |
| ai_chat_rooms | 포함 |
| products | 포함 |
| error_reports | 포함 |
| taste_analyses | 포함 |
products에는 컬럼 제거 Transformation Rule이 포함돼 있다.
4.3 V1/V2 데이터 건수 비교
| 테이블 | V1 | V2 | 차이 | 검증 결과 |
|---|---|---|---|---|
| users | 73 | 73 | 0 | 일치 |
| auth_sessions | 0 | 1 | +1 | V2 세션 확인 |
| friends | 436 | 438 | +2 | V2 ID 649, 650 확인 |
| ai_chat_rooms | 223 | 224 | +1 | V2 채팅방 545 확인 |
| products | 7,969 | 7,969 | 0 | 일치 |
| error_reports | 2 | 2 | 0 | 일치 |
| taste_analyses | 0 | 0 | 0 | 일치 |
DMS 대상 7개 테이블 중 4개는 행 수가 일치했다.
나머지 3개는 V2에 추가 레코드가 존재하는 것을 확인했다.
다만 행 수 비교만으로 기존 모든 레코드의 PK 및 컬럼 값이 동일하다고 확정할 수는 없다.
4.4 DMS 제외 테이블
| 테이블 | V1 | V2 | 확인 사항 |
|---|---|---|---|
| ai_messages | 3,328 | 3 | 기존 메시지 미이관 |
| gift_recommendations | 244 | 0 | 기존 추천 데이터 미이관 |
| personal_recommendations | 257 | 0 | 기존 추천 데이터 미이관 |
| user_taste_profiles | 41 | 1 | 기존 취향 프로필 미이관 |
해당 테이블은 DMS Selection Rule에 포함되지 않았다.
따라서 DMS가 복제에 실패한 것으로 단정할 수는 없지만, 실제 운영 전환 시 기존 데이터를 보존해야 하는지 결정해야 한다.
특히 기존 채팅방만 복제되고 메시지가 복제되지 않는 경우 과거 대화 데이터가 누락될 수 있다.
4.5 검증 판정
- DMS 대상 테이블 복제 상태: PASS
- 기본 건수 비교: PASS
- 기존 전체 데이터 이관: 추가 검토
- 전체 PK 및 컬럼 값 정합성: 미검증
5. PostgreSQL 마이그레이션 검증
5.1 Dump 및 Restore
| 항목 | 결과 |
|---|---|
| Source | V1 EC2 PostgreSQL |
| Target | V2 Staging RDS PostgreSQL |
| Database | needu_vector |
| 방식 | Dump/Restore |
| V1 Dump 수행 | 22:18:35 KST |
| V2 Restore | 데이터 복원 확인, 정확한 완료 시각 미확인 |
5.2 데이터 정합성 검증
| 테이블 | V1 | V2 | 결과 |
|---|---|---|---|
| catalog_embedding_models | 1 | 1 | 일치 |
| catalog_product_documents | 20,289 | 20,289 | 일치 |
| catalog_products | 7,969 | 7,969 | 일치 |
| catalog_sync_runs | 0 | 0 | 일치 |
4개 테이블 모두 V1/V2 행 수가 일치했다.
5.3 DB 구조 검증
V2에서 확인한 항목:
catalog_product_documents.embedding: vector 타입ix_catalog_documents_embedding_hnsw: HNSW 인덱스- 인덱스 연산자 클래스:
vector_cosine_ops
판정: PASS — 행 수 및 확인된 벡터 인덱스 구조 기준
5.4 미검증 항목
- PK 및 주요 컬럼 전체 비교
- 임베딩 벡터 값 비교
- 벡터 차원 일치 여부
- 실제 유사도 검색 결과
- Dump 이후 변경 데이터 반영 여부
6. Write Gate 동작 검증
6.1 적용 목적
전환 중 V1과 V2에 쓰기 요청이 동시에 발생해 데이터 불일치가 생기는 상황을 방지하기 위해 Write Gate를 적용했다.
6.2 적용 및 해제
| 이벤트 | 시각 |
|---|---|
| Write Gate ON | 22:41:30 |
| DMS Stopped | 22:44:30 |
| Write Gate OFF | 22:52:00 |
Write Gate 유지 시간: 10분 30초
6.3 HTTP 요청 영향
| 구간 | HTTP 요청 | 실패 |
|---|---|---|
| Gate 활성화 전 | 1,200 | 78 |
| Gate 활성화 중 | 6,276 | 1,132 |
| Gate 해제 후 | 28,468 | 42 |
Gate 활성화 중에는 CSRF 503, HTTP 0, 429가 관측됐다.
Gate 해제 이후에도 약 29초 동안 CSRF 503이 발생했다.
6.4 검증 판정
| 검증 항목 | 결과 |
|---|---|
| Gate 적용 시각 | 확인 |
| Gate 해제 시각 | 확인 |
| Gate 중 CSRF 503 | 확인 |
| Gate 해제 후 신규 쓰기 | 확인 |
| 대표 쓰기 API별 차단 | 추가 검증 필요 |
| DB 전체 쓰기 차단 완전성 | 미검증 |
Gate 구간의 CSRF 503이 의도된 차단 동작과 일치하는지, HTTP 0 및 429가 별도 문제인지 구분해야 한다.
7. k6 지속 부하 테스트
7.1 테스트 구성
| 항목 | 설정 |
|---|---|
| 도구 | Grafana k6 |
| 목표 부하 | 10 RPS |
| 지속 시간 | 60분 |
| 총 HTTP 요청 | 35,944 |
| 실제 평균 | 9.959 RPS |
| 종료 시각 | 2026-10-17 23:39:36 KST |
| 결과 경로 | v2-migration/k6/results/20261017T133926Z/ |
7.2 전체 결과
| 지표 | 결과 |
|---|---|
| 총 요청 | 35,944 |
| 성공 요청 | 34,692 |
| 실패 요청 | 1,252 |
| 성공률 | 96.52% |
| 실패율 | 3.48% |
| 평균 RPS | 9.959 |
| 평균 응답 시간 | 34.37ms |
| p95 | 33.95ms |
| p99 | 211.53ms |
| 최대 응답 시간 | 9,543.68ms |
| Dropped Iterations | 57 |
| Interrupted Iterations | 0 |
7.3 Threshold 결과
| Threshold | 실제 값 | 판정 |
|---|---|---|
| cutover_success = 1 | 0.965168 | FAIL |
| cutover_unexpected_failures = 0 | 1,252 | FAIL |
| dropped_iterations = 0 | 57 | FAIL |
전체 k6 테스트 판정: FAIL
7.4 구간별 실패 분석
| 구간 | 요청 | 실패 | 실패율 |
|---|---|---|---|
| Gate 활성화 전 | 1,200 | 78 | 6.50% |
| Gate 활성화 중 | 6,276 | 1,132 | 18.04% |
| Gate 해제 후 | 28,468 | 42 | 0.15% |
| 합계 | 35,944 | 1,252 | 3.48% |
7.4.1 Gate 활성화 전
- HTTP 0: 33건
- HTTP 429: 45건
- 총 실패: 78건
7.4.2 Gate 활성화 중
- auth-csrf 503: 851건
- HTTP 0: 104건
- HTTP 429: 177건
- 총 실패: 1,132건
7.4.3 Gate 해제 후
- auth-csrf 503: 42건
- 최초 실패: 22:52:00.126887
- 마지막 실패: 22:52:28.828112
- 이후 테스트 종료까지 추가 HTTP 실패 0건
7.5 Dropped Iterations 분석
| 구간 | 건수 |
|---|---|
| Gate 활성화 전 | 33 |
| Gate 활성화 중 | 24 |
| Gate 해제 후 | 0 |
| 합계 | 57 |
시간별 발생:
| 시각 | 건수 |
|---|---|
| 22:40 | 33 |
| 22:42 | 10 |
| 22:43 | 14 |
- 최초 발생: 22:40:19.115060
- 마지막 발생: 22:43:26.007724
Dropped Iterations는 Gate 해제 후 발생하지 않았다.
다만 발생 원인은 확인되지 않아 VU 부족, 부하 생성기 상태 및 테스트 설정을 추가 분석해야 한다.
7.6 결과 분석
전체 테스트에서는 실패 1,252건과 Dropped Iterations 57건으로 Threshold가 FAIL이었다.
실패 1,132건은 Gate 활성화 구간에 집중됐다.
Gate 해제 이후에는 약 29초 동안 42건의 CSRF 503이 발생했으나, 이후 약 47분 동안 추가 HTTP 실패가 기록되지 않았다.
따라서 전체 테스트 성공과 전환 후 안정화는 구분해 평가해야 한다.
8. V2 ECS 및 ALB 전환 검증
8.1 ECS 최종 상태
| 항목 | 결과 |
|---|---|
| Frontend | 2 Tasks |
| Backend | 2 Tasks |
| AI | 2 Tasks |
| Backend Target Group | 2/2 Healthy |
8.2 ALB 가중치 전환
| 대상 | 최종 가중치 |
|---|---|
| V1 | 0 |
| V2 | 100 |
V2로 트래픽이 전환된 최종 상태를 확인했다.
단, 실제 가중치 변경 완료 시각은 확인되지 않았다.
8.3 ALB 오류 확인
Cloud A 확인 결과, 최종 점검 구간에서 ALB Target 5xx가 관측되지 않았다.
이는 k6에서 발생한 CSRF 503과 측정 지점 및 관측 시간이 다를 수 있으므로 구분해야 한다.
8.4 판정
PASS — V2 최종 라우팅 및 Backend Target Group 정상 상태 확인
9. 전환 후 HTTP 오류 및 복구 검증
9.1 Gate 해제 후 HTTP 503
Gate 해제 직후 다음과 같이 CSRF 503이 발생했다.
| 항목 | 시각 |
|---|---|
| Gate OFF | 22:52:00 |
| 최초 실패 | 22:52:00.126887 |
| 마지막 실패 | 22:52:28.828112 |
| 이후 추가 실패 없음 | 22:52:29 ~ 23:39:36 |
Gate 해제 후 마지막 실패까지 약 28.83초가 소요됐다.
9.2 안정화 구간
- 시작: 22:52:29 KST
- 종료: 23:39:36 KST
- 관측 시간: 약 47분 7초
- 추가 HTTP 실패: 0건
- 추가 Dropped Iterations: 0건
9.3 결과 분석
Write Gate 해제 직후 발생한 CSRF 503은 복구 지연이나 설정 반영 지연 등과 관련됐을 가능성이 있으나, 현재 로그만으로 원인을 확정할 수 없다.
실제 복구 완료 시각을 확정하려면 해당 경로의 최초 정상 응답 시각과 Nginx/ALB 로그를 함께 확인해야 한다.
9.4 판정
전환 후 안정화 확인 / 503 발생 원인 및 정확한 복구 완료 시각 추가 분석 필요
10. V2 쓰기 검증
10.1 검증 방식
전환 이후 V2 MySQL에 신규 데이터가 생성되고 갱신되는지 확인했다.
검증 대상:
- 인증 세션
- 친구 관계
- AI 채팅방
- AI 메시지
10.2 인증 세션
| 항목 | 결과 |
|---|---|
| V1 | 0건 |
| V2 | 1건 |
| 세션 ID | 1 |
| 사용자 ID | 20 |
| 생성 시각(DB 저장값) | 2026-10-17 13:56:14.225802 |
| 마지막 사용 시각(DB 저장값) | 2026-10-17 13:57:24.609212 |
| revoked_at | NULL |
V2에서 인증 세션 INSERT 및 마지막 사용 시각 갱신을 확인했다.
DB 저장값의 타임존은 확인되지 않아 KST로 단정하지 않았다.
10.3 친구 관계
V2에만 존재하는 레코드:
| id | owner_user_id | friend_user_id |
|---|---|---|
| 649 | 20 | 39 |
| 650 | 20 | 57 |
V1 436건, V2 438건으로 차이가 발생했고, 추가된 2개 레코드를 확인했다.
10.4 AI 채팅방 및 메시지
- V2 채팅방 ID: 545
- 사용자 ID: 20
- 상태: ACTIVE
- 메시지: 총 3건
- USER 1건
- AI 2건
V2 신규 채팅방 및 메시지 저장을 확인했다.
10.5 검증 판정
| 항목 | 결과 |
|---|---|
| 인증 세션 생성 | PASS |
| 인증 세션 갱신 | PASS |
| 친구 관계 추가 데이터 | 확인 |
| 채팅방 생성 | PASS |
| 채팅 메시지 저장 | PASS |
| 채팅 완료 및 추천 생성 | 미검증 |
판정: V2 신규 쓰기 검증 PASS — 확인된 기능 기준
11. Write Gate 지속 시간 및 병목 분석
11.1 전환 시간 분석
| 이벤트 | 시각 |
|---|---|
| Write Gate ON | 22:41:30 |
| DMS Stopped | 22:44:30 |
| Write Gate OFF | 22:52:00 |
| 마지막 HTTP 실패 | 22:52:28.828112 |
Write Gate 유지 시간: 10분 30초
11.2 단계별 소요 시간
| 구간 | 소요 시간 |
|---|---|
| Gate ON → DMS Stopped | 3분 |
| DMS Stopped → Gate OFF | 7분 30초 |
| Gate OFF → 마지막 HTTP 실패 | 약 29초 |
DMS 중지 이후 Gate 해제까지의 7분 30초 구간이 전체 Gate 유지 시간의 대부분을 차지했다.
다만 해당 구간의 세부 작업별 소요 시간이 확인되지 않아 실제 병목 원인을 확정할 수 없다.
11.3 1차 대비 비교
| 항목 | 1차 | 2차 |
|---|---|---|
| Freeze/Gate → DMS Stopped | 7분 55초 | 3분 |
| Freeze → DNS 전환 | 약 23분 35초 | 해당 없음 |
| Gate ON → OFF | 측정값 없음 | 10분 30초 |
| 트래픽 전환 | DNS | 공통 ALB |
| 부하 테스트 | V1 조회 90분 | 전환 포함 60분 |
Freeze/Gate → DMS Stopped 구간은 4분 55초 단축됐다.
단, 1차 Freeze → DNS 전환과 2차 Gate ON → OFF는 서로 다른 기준의 지표이므로 직접적인 전환 시간 단축률로 계산하지 않는다.
11.4 개선 방향
- Gate ON 이후 DMS 검증 및 중지 절차 최적화
- DMS 중지 후 Gate OFF까지 세부 작업별 시각 기록
- ECS 및 ALB 전환 준비 단계 사전 완료
- PostgreSQL 최종 동기화 절차 단축
- Gate 해제 후 CSRF 503 원인 분석
- 단계별 자동화 가능 여부 검토
12. 모니터링 및 관측성
12.1 수집 및 분석한 데이터
| 데이터 | 확인 목적 |
|---|---|
| k6 Summary JSON | 전체 요청 수, 성공률, 지연 및 Threshold |
| k6 metrics.jsonl | 구간별 HTTP 실패 및 Dropped Iterations |
| DMS Table Mapping | 실제 복제 대상 확인 |
| DMS Validation | 대상 테이블 복제 검증 |
| MySQL SQL | V1/V2 건수 및 신규 쓰기 확인 |
| PostgreSQL SQL | 테이블 건수 및 벡터 인덱스 확인 |
| ECS/ALB 상태 | 전환 후 서비스 정상 상태 확인 |
12.2 k6 결과 파일
summary-export.jsonmetrics.jsonlconsole.log
결과 경로:
v2-migration/k6/results/20261017T133926Z/
12.3 모니터링 증빙
[증빙 ① — k6 전체 Summary]
- 총 요청 35,944건
- 성공률 96.52%
- p95 33.95ms
- Dropped Iterations 57건
[증빙 ② — k6 구간별 HTTP 실패]
- Gate ON: 22:41:30
- Gate OFF: 22:52:00
- 마지막 실패: 22:52:28.828112
[증빙 ③ — DMS Table Statistics 및 Validation]
- 대상 7개 테이블
- Validated
- Pending 0
- Error 0
[증빙 ④ — V2 ECS 및 ALB]
- FE/BE/AI 각 2 Tasks
- Backend TG 2/2 Healthy
- ALB V2 가중치 100%
[증빙 ⑤ — MySQL 데이터 비교]
- DMS 대상 7개 테이블 건수 비교
- 신규 친구 ID 649, 650
- 신규 채팅방 ID 545
- 인증 세션 ID 1
[증빙 ⑥ — PostgreSQL 데이터 비교]
- 4개 테이블 건수 일치
- vector 컬럼 및 HNSW 인덱스
증빙 이미지는 이번 2차 리허설의 실제 캡처를 첨부해야 한다. 1차 리허설 이미지를 재사용하지 않는다.
12.4 관측성 개선 사항
- Gate ON/OFF 시각을 Grafana에 표시
- DMS Stopped 및 ALB 전환 시각을 함께 표시
- CSRF 503과 기타 오류를 분리
- k6 결과 파일을 로컬 백업
- 성공한 쓰기 요청과 DB 저장 결과를 연결할 수 있는 request_id 검토
13. 한계 및 미검증 항목
13.1 RPO 0 미확정
DMS Validation 및 PostgreSQL 건수 일치는 확인했지만, V1에서 성공 응답을 받은 모든 쓰기 요청이 V2에 반영됐는지는 전수 대조하지 않았다.
따라서 RPO 0은 확정할 수 없다.
13.2 DMS 제외 테이블
다음 테이블은 DMS 복제 대상에서 제외됐다.
- ai_messages
- gift_recommendations
- personal_recommendations
- user_taste_profiles
운영 전환 전 기존 데이터 보존 정책을 확정해야 한다.
13.3 PostgreSQL 변경 데이터
PostgreSQL은 Dump/Restore 방식이므로 Dump 이후 V1에서 변경된 데이터가 존재한다면 V2에 자동 반영되지 않는다.
최종 Dump 시점과 쓰기 차단 시점의 관계를 추가 검증해야 한다.
13.4 쓰기 차단 완전성
CSRF 503은 관측됐지만 모든 대표 쓰기 API의 차단 및 재개를 검증한 것은 아니다.
POST/PUT/PATCH/DELETE와 내부 비동기 작업에 대한 확인이 필요하다.
13.5 k6 Threshold FAIL
전체 실패 1,252건과 Dropped Iterations 57건이 발생했다.
Gate 구간의 예상 거절과 실제 장애를 구분하는 테스트 기준이 필요하다.
13.6 실제 서비스 복구 시간
마지막 실패 시각은 확인됐지만 최초 정상 응답 시각은 별도 검증되지 않았다.
따라서 정확한 서비스 복구 완료 시각은 미확정이다.
13.7 롤백 제한
V2에서 신규 인증·친구·채팅 데이터가 생성됐으므로, 단순히 트래픽을 V1으로 되돌리면 V2 신규 데이터가 V1에 반영되지 않을 수 있다.
롤백 시 신규 데이터 재동기화 및 충돌 처리 계획이 필요하다.
14. 3차 리허설 개선 계획
| 개선 항목 | 적용 방향 | 검증 기준 |
|---|---|---|
| Write Gate | 유지 시간 단축 | Gate ON/OFF 정확한 시각 및 소요 시간 |
| DMS | CDC 최종 검증 절차 최적화 | Pending 0, Validation Error 0 |
| PostgreSQL | 최종 변경분 처리 방식 확정 | 데이터 정합성 |
| ECS/ALB | 사전 준비 및 전환 자동화 | Healthy Target 및 정상 라우팅 |
| k6 | Gate 단계별 실패 구분 | 예상 거절·비정상 실패 분리 |
| HTTP 503 | Gate 해제 후 복구 지연 분석 | 최초 정상 응답 시각 확인 |
| Dropped Iterations | VU 및 부하 생성기 설정 분석 | Drop 원인 파악 |
| MySQL | DMS 제외 테이블 정책 확정 | 기존 데이터 보존 기준 충족 |
| 데이터 정합성 | PK·컬럼·임베딩 값 비교 | 누락·불일치 확인 |
| 쓰기 검증 | 성공 요청 ID와 DB 결과 대조 | 데이터 유실 여부 검증 |
| 롤백 | V2 신규 쓰기 이후 복구 전략 | 데이터 불일치 방지 |
| 모니터링 | Grafana/Loki/CloudWatch 통합 분석 | 전환 단계별 증빙 확보 |
14.1 우선순위
P0
- DMS 제외 테이블 이관 정책 확정
- Write Gate 유지 시간 단축
- MySQL/PostgreSQL 최종 정합성 강화
- 성공 응답 데이터 유실 여부 검증
P1
- Gate 해제 후 503 발생 원인 분석
- Gate 이전 HTTP 0·429 원인 분석
- Dropped Iterations 원인 분석
- k6 Threshold 개선
- ALB 전환 시각 및 복구 시간 계측
15. 최종 결론
2026년 10월 17일 V1 → V2 Staging 2차 마이그레이션 리허설에서 MySQL DMS 복제, PostgreSQL Dump/Restore, Write Gate, 공통 ALB 전환, V2 ECS 정상 동작 및 신규 쓰기 검증을 수행했다.
MySQL DMS는 7개 테이블의 Validation을 완료했으며, PostgreSQL은 4개 테이블의 행 수와 pgvector 인덱스 구조를 확인했다.
V2에서는 인증 세션, 친구 관계, 채팅방 및 메시지 데이터가 정상 저장되는 것을 확인했다.
Write Gate 유지 시간은 10분 30초였고, Gate 적용부터 DMS Stopped 확인까지는 1차의 7분 55초에서 2차 3분으로 단축됐다.
k6 테스트는 2026-10-17 23:39:36 KST에 종료됐으며, 총 35,944건 중 34,692건이 성공했다.
전체 성공률은 **96.52%**였고, 실패 1,252건과 Dropped Iterations 57건으로 Threshold는 FAIL이었다.
다만 Write Gate 해제 후 약 29초까지 발생한 HTTP 503 이후에는 테스트 종료까지 약 47분간 추가 HTTP 실패가 기록되지 않았다.
최종 판정: 서비스 전환 및 기본 DB 검증 성공 / k6 전체 Threshold FAIL / 데이터 이관 완전성 및 RPO 0 추가 검증 필요
3차 리허설에서는 Write Gate 유지 시간 단축, DMS 제외 테이블 정책 확정, 데이터 정합성 강화, HTTP 오류 원인 분석 및 실제 복구 시간 계측을 우선 수행한다.