북적북적 DB 무중단 마이그래이션 - 100-hours-a-week/KTB4-13th-wiki GitHub Wiki
1. 배경과 해결할 문제
-
북적북적 V1은 App EC2에서 Nginx, Backend, MySQL을 Docker Compose로 함께 운영하는 구조입니다. MySQL 데이터는 Docker Volume을 통해 EBS에 저장합니다. 초기 POC에서는 비용과 구축 시간을 줄이고 빠르게 서비스를 제공하기 위해 이러한 구성을 선택했습니다.
-
이 구조에서는 애플리케이션과 DB가 같은 서버의 CPU / 메모리 / 디스크를 사용하므로, 한쪽의 부하가 다른 쪽에 영향을 줄 수 있습니다. EC2 장애가 발생하면 API와 DB가 함께 영향을 받고, 운영자가 서버와 DB의 복구를 함께 처리해야 합니다. 따라서, V2에서는 애플리케이션과 DB를 독립적으로 운영하고 장애 대응·백업·복구 부담을 줄일 필요가 있었습니다.
이를 위해 RDS for MySQL Multi-AZ DB Instance로 이전하는 설계를 선택했습니다.
-
또한, V2에서는 DB 위치와 함께 데이터 구조도 달라집니다. ERD 기준으로 상품 테이블이
products에서items로 바뀌고, 장바구니·주문 상세의 상품 참조와 리뷰 대상·작성 권한이 변경되며, 결제·취소·포인트·쿠폰 구조가 추가됩니다. -
따라서, 기존 ID와 관계를 잘못 연결하면 주문과 리뷰가 다른 상품을 가리킬 수 있는 문제가 잠재되어 있습니다. 또한, 저장 길이가 줄어드는 도서 설명·주소는 적재 실패나 원문 손실이 발생할 수 있습니다.
-
서비스 운영 중에 이전을 진행하므로 데이터를 복사하는 동안에도 주문 생성 / 재고 차감 / 정보 수정과 삭제가 계속 발생합니다. 이때 초기 복사 이후의 변경을 반영하지 않으면 주문·재고가 불일치하거나 삭제한 데이터가 남을 수 있습니다.
-
또한, 기존 데이터를 V2 구조에 채우는 Backfill 과정에서도 과거 값이 최신 수정을 덮어쓰거나 삭제한 행을 다시 생성하지 않도록 보호해야 합니다.
-
DB 연결을 전환할 때는 진행 중인 요청을 안전하게 마무리하고, 새 요청의 쓰기 대상을 하나로 통일해야 합니다.
-
저장은 완료됐지만 응답이 전달되지 않아 같은 요청이 재시도되는 경우에도 주문이나 재고 변경이 중복 처리되지 않아야 합니다.
-
그리고 전환 후에는 RDS에 새 거래가 쌓이므로, 문제가 발생하더라도 이전 DB 주소로만 되돌리지 않고 최신 거래를 보존할 수 있는 복구 절차를 준비해야 합니다.
따라서, 이번 이전은 조회와 쓰기를 계속 처리하면서 기존 데이터와 업무 이력을 보존하고, 실패해도 새 거래를 잃지 않고 복구할 수 있도록 설계하는 것이 목적입니다.
2. 목표와 설계 조건
이번 마이그레이션의 목표는 데이터 유실 없이 조회·쓰기 요청을 계속 처리하면서 EC2 MySQL을 RDS로 이전하고, 이후 V2 구조로 전환하는 것입니다. DB 위치 이전과 업무 구조 변경은 두 단계로 나누며, 두 단계 모두 기존 기능과 업무 이력을 보존합니다.
-
조회는 이전 중에도 계속 제공하고, 주문·재고 변경 등의 쓰기는 기존 API 계약에 따라 처리합니다. 또한, 성공 응답은 실제 업무 데이터가 커밋된 이후에 반환합니다.
-
전환 중 내부 대기가 발생하더라도 기존 응답 제한시간 안에 완료해야 하며, 계획된 이전으로 인한 요청 누락 / 중복 처리 / 실패 / 시간 초과는 검증 범위에서 0건을 목표로 합니다.
-
데이터 보존 범위는 기존 V1 데이터 전체와 이전 중 발생한 생성·수정·삭제입니다. ID와 참조 관계, 업무 상태와 삭제 상태를 유지하며, 주문 당시 상품·가격·수량·배송지와 결제·취소·환불 이력을 보존합니다. 또한, 데이터를 V2 구조에 맞추기 위해 원문을 잘라 저장하지 않습니다.
-
응답 제한시간은 클라이언트 / 프록시 / Backend의 기존 제한시간 중 가장 짧은 값을 기준으로 정합니다. 대기 요청의 남은 시간 안에 검증·전환·쓰기 처리·응답 전달을 마쳐야 하며, 전환 취소 후 원본에서 처리를 재개하는 시간도 확보해야 합니다.
-
V2로 이전 당시의 조건은 MySQL 8.0 / 논리 데이터 20GB / PK가 있는 InnoDB 업무 테이블 24개 / 피크 업무 쓰기 초당 5트랜잭션입니다. 이전 중 DDL을 동결하고 binlog와 보존 공간이 준비된 것으로 가정합니다.
3. 대안 비교와 선정 이유
이번 비교는 V1의 EC2 MySQL을 V1 구조 그대로 RDS for MySQL Multi-AZ DB Instance로 이전하는 1단계를 대상으로 합니다.
- Source와 Target은 MySQL 8.0, 논리 데이터는 20GB, InnoDB 업무 테이블은 24개, 피크 업무 쓰기는 초당 5트랜잭션으로 가정합니다.
- 모든 업무 테이블에 PK가 있으며, 이전 중 DDL을 변경하지 않습니다.
AWS DMS 복제 Task 방식 / 선정
-
AWS DMS 복제 Task 방식은 Full Load / CDC / Data Validation을 같은 Task에 구성해 초기 복사·변경 반영·행 검증 상태를 함께 관리할 수 있습니다. 따라서, 복사 도구와 복제·검증 도구 사이의 설정과 상태를 연결하는 작업을 줄일 수 있다는 점이 장점입니다.
-
DMS를 사용하기 전에 DB 접속 권한과 네트워크, 변경 기록의 보존 기간을 확인하고 RDS에 필요한 DB 구조를 준비해야 합니다. DB별 쓰기 허용 상태를 관리하는
write_authority는 복제에서 제외합니다. 또한 데이터가 잘리거나 누락되지 않았는지 검증하고, 복사·검증 작업 때문에 기존 서비스가 느려지지 않는지 확인해야 합니다. -
북적북적은 운영 중인 주문·재고 변경을 반영하면서 V2 데이터 변환과 복구도 준비해야 합니다. 제한된 인력과 일정에서는 복제·행 검증의 연결 절차를 줄이고 전환 통제와 업무 정합성에 시간을 배분하기 위해 DMS 복제 Task 방식을 선정합니다. 이를 위해 임시 복제 자원 비용과 원본의 추가 읽기 부하를 감수합니다.
MySQL Shell / 미선정
-
MySQL Shell은 데이터를 청크로 나누어 병렬 Dump/Load를 수행하고 압축 / 적재 진행 기록 / 재개 기능을 제공합니다. 지원 버전에서는 checksum으로 초기 적재 데이터를 확인할 수 있어 초기 복사와 반복 리허설에 유리합니다.
-
현재 상황에서는 덤프 메타데이터의 binlog 위치·GTID와 실제 복제 시작점의 일치를 확인하고, MySQL 기본 복제와 DMS Validation-only 등의 지속 검증을 연결해야 합니다. 적재 중단, 복제 장애, 검증 불일치가 발생했을 때 어느 단계부터 재개할지도 정해야 합니다. 초기 checksum을 통과하더라도 이후 주문·재고 변경의 반영과 검증은 계속 필요합니다.
-
이번 이전에서는 적재·기본 복제·지속 검증을 별도로 연결하고 재개 절차까지 검증하는 작업이 추가되므로 기본안으로 선정하지 않았습니다. 다만 초기 적재 성능과 반복 리허설에 유리한 기능을 갖추고 있어, 준비 범위를 확대하거나 DMS 비용·부하가 문제가 될 때 먼저 비교할만한 대안입니다.
MyDumper/MyLoader / 미선정
-
MyDumper/MyLoader는 테이블·청크별로 데이터를 추출하고 병렬 적재하는 오픈소스 도구입니다. 병렬도 / 청크 / 압축 / 적재 트랜잭션과 인덱스 생성 시점을 조정할 수 있어 데이터 특성에 맞게 초기 복원 성능을 튜닝할 수 있습니다. AWS의 대용량 실험에서는 스레드를 늘렸을 때 복원이 오히려 느려지는 경우도 있어, 자원과 작업 분배를 함께 조정해야 합니다.
-
현재 상황에서는 주문·주문 상세·재고를 같은 기준 시점으로 추출하는 스냅샷과 잠금 조건을 검증해야 합니다. 백업의 복제 위치를 기준으로 기본 binlog 복제를 구성하고, 별도 행 검증과 실패 재개 절차도 연결해야 합니다. 병렬도와 인덱스 생성 순서를 바꾸면 원본 부하·적재시간·인덱스 생성시간을 함께 측정해야 합니다.
-
현재 20GB 조건에서는 이러한 세밀한 튜닝이 전체 준비시간을 줄인다는 실측 근거가 없습니다. 제한된 일정에서 스냅샷·튜닝·복제·검증을 별도로 준비하는 부담이 크므로 기본안으로 선정하지 않았습니다. MySQL Shell의 지원 조건이나 성능이 부적합해 복사 방식을 더 세밀하게 조정해야 할 때 검토합니다.
XtraBackup / 미선정
-
XtraBackup은 데이터 파일을 물리적으로 백업하므로 SQL 문장을 다시 실행해 데이터를 적재하는 부담을 줄일 수 있습니다. 논리 적재 시간이 병목일 때 검토할 가치가 있는 방식이며, 백업 기준점에서 기본 복제를 연결하는 구성도 가능합니다.
-
현재 상황에서는 원본 MySQL과 XtraBackup의 버전·파일 형식을 맞추고 전체 백업 / 전송 / RDS 복원 / 기본 복제 / 검증을 준비해야 합니다. RDS는 지원되는 백업을 S3에서 새 DB 인스턴스로 복원하며, 부분 백업 가져오기는 지원하지 않습니다. 따라서 파일 복원 속도뿐 아니라 백업·S3 전송·새 RDS 생성까지의 시간을 확인해야 합니다.
-
북적북적에는 기존 물리 백업 운영 체계와 검증된 복원 절차가 없다는 가정을 두었습니다. 물리 백업 체계를 처음 준비하는 작업까지 포함하면 이번 인력과 일정에서 부담이 크므로 기본안으로 선정하지 않았습니다. 다만, 논리 적재가 전체 준비시간의 병목으로 확인되면 다시 비교할 수 있습니다.