v2 DB 무중단 마이그레이션 - 100-hours-a-week/KTB4-17th-wiki GitHub Wiki

DB 마이그레이션 테스트

1. 마이그레이션 테스트

1.1. 목적

  • 서비스 요청이 들어오는 상태에서 기존 v1 DB를 v2 RDS로 전환
  • 전환 과정의 API 에러율과 읽기/쓰기 불가 시간 측정
  • 데이터 누락 및 중복 여부 확인
  • v2 RDS 전환 실패 시 기존 v1 DB로 롤백 가능한지 확인

1.2. 마이그레이션 방식

1.2.1. 쓰기 중단 + CDC 방식

  • Full Load: v1 DB의 기존 데이터를 v2 RDS로 복제
  • CDC: 마이그레이션 중 발생하는 변경 데이터를 지속적으로 복제
v1 DB
→ 기존 데이터 복제
→ 변경 데이터 실시간 반영
→ 쓰기 중단
→ 복제 지연 = 0
→ v2 RDS 전환
→ 성공 시 Commit / 실패 시 Rollback

1.2.2. 메시지 큐 도입

v1 DB
→ 기존 데이터 복제
→ 변경 데이터 실시간 반영
→ 쓰기 요청은 큐에 보관하고 조회는 계속 처리
→ 쓰기 중단
→ 복제 지연 = 0
→ v2 RDS 전환
→ 큐에 대기 중인 쓰기 반영
→ 성공 시 Commit / 실패 시 Rollback

1.3. 테스트 대상 API

구분 API
쓰기 POST /api/v1/chat-rooms/{chatRoomId}/messages
읽기 GET /api/v1/chat-rooms/{chatRoomId}/messages?size=20

1.4. Rollback 기준

: 3분 이내 정상화되지 않거나 복구 불가능한 오류가 확인되면 부하를 중지하고 즉시 수동 Rollback한다.

  • [롤백 조건]
  • Backend Task 실패가 3회 발생
  • ALB Health Check가 2회 연속 실패
  • Health Check 응답시간이 5초를 초과

2. 마이그레이션 환경 구성

2.1. 기본 구성

  • Source DB
    • 현재 서비스에서 사용 중인 기존 DB
  • Target RDS
    • 마이그레이션 후 사용할 신규 DB
  • AWS DMS
    • Source DB의 기존 데이터와 변경 데이터를 Target RDS로 복제
  • Backend (v2 ECS)
    • 전환 전: Source DB 사용
    • 전환 후: Target RDS 사용

2.2. 테스트 데이터

  • 테스트 계정: 총 130명
    • 부하 테스트용: 120명
    • 프로브용: 10명
  • 테스트용 채팅방: 65개
  • 기본 쓰기 데이터: 채팅방당 메시지 500건
  • 각 쓰기 요청에 고유 ID를 부여하여 중복 쓰기 방지

2.3. 모니터링

  • DMS
    • CloudWatch를 통해 CDC 지연 확인
  • 애플리케이션
    • k6를 통해 API 성공/실패 요청 수 측정
  • AWS 인프라
    • Backend 서비스 수(ECS 컨테이너 개수)
    • ALB Health Check 확인
  • WhaTap
    • SQL 실행 시간, 호출 건수

2.4. 데이터 정합성 검증 : full outer join 방식, checksum방식

(1) 양적 검증: 데이터의 갯수나 존재유무

  • 기존: row수 세기 → 양방향 GROUP BY 결과를 FULL OUTER JOIN으로 비교

    Source 테이블과 Target 테이블을 동일한 기준으로 GROUP BY한 뒤 두 결과를 FULL OUTER JOIN하여 집계치 차이를 검증.

[ 동작 방식 ]

채팅방 id로 group by를 각각 진행

chat_room_id row_count
100 50
200 30
300 20

source와 target에 FULL OUTER JOIN 진행 → 채팅 건수 비교

chat_room_id Source 건수 Target 건수
100 50 50
200 30 28
300 20 0
400 0 10

(2) 질적 검증: 데이터 값, 관계, api확인

  • checksum: source와 target의 데이터 일치 여부 확인
    • DB마이그레이션 전후 테이블의 행,컬럼값 비교.

[ 동작 방식 ]

select권한 확인
→ 테이블 마다 checksum 쿼리 생성함
→ `CRC32`로 행의 값을 숫자로 만듦
→ 그 결과를 XOR로 합침 (최종 checksum= h1 xor h2 xor h3)
→ source와 target의 체크썸 비교

출처: https://dev.mysql.com/doc/refman/8.4/en/checksum-table.html


3. 단계별 마이그레이션 테스트

3.1. 쓰기 중단 + CDC 마이그레이션

  • 상태: 10 RPS 성공
  • DB 전환 중 쓰기를 중단하고 요청 실패율 및 쓰기 불가 시간 측정

3.1.1. 테스트 결과

  • 부하: 쓰기 10 RPS, 읽기 10 RPS
  • Backend 중단부터 RDS 첫 정상 응답까지: 6분 46초
부하 쓰기 불가 시간 API 실패율 DB 오류 결과
10 RPS 6분 46초 67.8% 0건 성공

3.1.2. API 요청 결과

  • 전체 요청: 12,397건
  • 실패 요청: 8,401건
  • 실패율: 67.8%
실패 원인
원인 건수
Backend 중단으로 인한 503 5,002건
Target Backend 기동 대기 중 503 2,422건
신규 Backend 등록 중 502 948건
DB Connection/Query 오류 0건

3.1.3. API 지연 시간

  • 전환 전 정상 구간 p95
    • 쓰기: 162ms
    • 읽기: 155ms
  • k6 성공 요청 전체 p95: 3.284초
    • v2 Backend 기동 직후의 지연 포함

3.1.4. 데이터 정합성

  • 결과: 만족
  • 프로브 쓰기 성공: 2,049건
  • v2 RDS 저장: 2,049건
  • 데이터 누락: 0건
  • 데이터 중복: 0건

3.2. 쓰기 중단 + Queue