티스토리 뷰
AWS DMS(Database Migration Service)로 DB를 옮기면서 겪은 문제들을 기록해둔다. 마이그레이션이 "완료"로 뜨는데 데이터가 원본과 일치하지 않는 상황이 반복됐다.
문제 1. 데이터가 완전히 일치하지 않는다
DB 이전 시 deleted_at 같은 몇몇 컬럼들에 이전 시간 값이 박혀 있었다. 스키마에도 원래 없던 default 값이 들어가 있었다.
원인: DMS는 스키마를 자동 생성할 때 원본 DDL을 그대로 복제하지 않는다. 타입을 자체 중간 타입으로 변환한 뒤 대상 DB 타입으로 다시 매핑하기 때문에, 이 과정에서 default 값이나 nullable 속성이 달라질 수 있다.
해결: 스키마는 dump로 먼저 이전하고, DMS는 데이터만 옮기게 한다.
# 1. 스키마만 덤프 (데이터 제외)
mysqldump --no-data -h source-host -u user -p mydb > schema.sql
# 2. 대상 DB에 스키마 먼저 생성
mysql -h target-host -u user -p mydb < schema.sql
# 3. DMS 작업 설정에서 대상 테이블 준비 모드 변경
# "대상 테이블 삭제" 대신 "아무 작업도 안 함(DO_NOTHING)" 선택
마지막 단계가 핵심이다. DMS 작업의 대상 테이블 준비 모드를 DROP_AND_CREATE로 두면 애써 만든 스키마를 지우고 자기 방식대로 다시 만든다.
문제 2. 값이 일부 안 들어오거나 에러가 발생한다
원인: 외래키 제약이다. DMS는 테이블을 병렬로 옮기는데 순서가 보장되지 않는다. 자식 테이블이 부모보다 먼저 들어가면 외래키 위반으로 실패한다.
해결: 외래키 무시 옵션을 켠다. 대상 엔드포인트의 추가 연결 속성에 넣는다.
# 대상 엔드포인트 Extra connection attributes
initstmt=SET FOREIGN_KEY_CHECKS=0
마이그레이션이 끝나면 반드시 무결성을 직접 검증해야 한다. 제약을 꺼둔 채로 넣었기 때문에 잘못된 참조가 들어가 있어도 DB가 알려주지 않는다.
-- 고아 레코드 확인 예시
SELECT c.* FROM child c
LEFT JOIN parent p ON c.parent_id = p.id
WHERE p.id IS NULL;
문제 3. 시간이 계속 틀리다
가장 오래 붙잡았던 문제다. 옮긴 데이터의 datetime 값이 몇 시간씩 어긋나 있었다.
원인: 타임존이다. 원본 DB, DMS 복제 인스턴스, 대상 DB가 각각 다른 타임존으로 동작하면 변환 과정에서 값이 틀어진다.
해결: 엔드포인트에 타임존 설정 등이 있다. 추가 연결 속성에서 지정한다.
# MySQL 소스 엔드포인트
serverTimezone=Asia/Seoul
# 여러 속성을 함께 쓸 때는 세미콜론으로 구분
initstmt=SET FOREIGN_KEY_CHECKS=0;serverTimezone=Asia/Seoul
공식 문서에 소스별로 사용 가능한 속성이 정리돼 있다.
근본적인 예방책
애초에 datetime 대신 timestamp를 쓰거나, 애플리케이션에서 UTC로 저장하고 표시할 때만 변환하는 구조가 안전하다. datetime은 타임존 정보가 없는 값이라, 이동할 때마다 해석 주체에 따라 의미가 달라진다.
마이그레이션 후 반드시 검증할 것
DMS가 "완료"라고 표시해도 그대로 믿으면 안 된다는 게 이번 경험의 결론이다.
- 행 수 비교 — 테이블별
COUNT(*)를 원본과 대조 - 체크섬 비교 —
CHECKSUM TABLE또는 주요 컬럼의 집계값 - 경계값 확인 — 최소·최대 날짜, NULL 개수
- 스키마 diff — 양쪽
SHOW CREATE TABLE결과 비교 - 인덱스와 제약 — DMS는 인덱스를 안 옮기는 경우가 많다. 별도 확인 필요
-- 행 수 일괄 비교용
SELECT table_name, table_rows
FROM information_schema.tables
WHERE table_schema = 'mydb'
ORDER BY table_name;
table_rows는 InnoDB에서 추정치이므로 정확한 비교가 필요하면 실제 COUNT(*)를 돌려야 한다.
정리
- 스키마는 dump로 먼저 옮기고 DMS는 데이터만. 대상 테이블 준비 모드를
DO_NOTHING으로 - 외래키는
initstmt=SET FOREIGN_KEY_CHECKS=0로 끄고, 끝나고 무결성 직접 검증 - 시간이 어긋나면 엔드포인트의
serverTimezone확인 datetime보다 UTC 저장이 이전에 안전하다- DMS가 완료라고 해도 행 수·체크섬·인덱스를 직접 대조한다
'AWS > 기타' 카테고리의 다른 글
| AWS 비용 절감 실전 가이드, 청구서에서 새는 돈을 잡는 8가지 점검 포인트 (0) | 2026.08.21 |
|---|---|
| 아마존 AWS 사용하다가 해킹당했을 때 대처법 (0) | 2018.08.27 |
