Profile picture

[Linux] mysql 데이터베이스 마이그레이션(migration) 가이드

JaehyoJJAng2025년 08월 25일

개요

데이터베이스 마이그레이션은 시스템 운영자에게 있어서 가장 긴장되는 순간이 아닐까 생각합니다.


특히 운영 서버에서 동작 중인 서비스의 데이터를 옮기는 작업은 단 하나의 데이터도 잃어서는 안 되기에 더욱 신중해야 합니다.


이번 게시글에서는 MySQL 데이터베이스를 100% 안전하게 다른 서버로 마이그레이션 하는 방법에 대해 실습을 진행해보려고 합니다.


마이그레이션 체크리스트

실제 운영 서버 마이그레이션 진행 시 아래 체크리스트를 반드시 확인 해주시는 것을 권장드립니다!


물론 실제 운영 서버 마이그레이션을 진행하기 전에,

테스트 서버에서 마이그레이션이 정상적으로 진행되는지 완벽하게 테스트를 진행해봐야겠죠?


  • MySQL 버전 호환성: 소스 서버와 타겟 서버의 MySQL 버전 확인
  • 문자셋(Character Set): 양쪽 서버의 기본 문자셋 일치 여부
  • 저장 공간: 타겟 서버의 디스크 여유 공간 (백업 파일 크기의 2배 이상 권장)
  • 네트워크 대역폭: 대용량 파일 전송을 위한 네트워크 상태
  • 서비스 중단 가능 시간: 필요시 서비스 중단 가능한 시간대 확인

데이터 백업하기

1. A 서버 전체 데이터베이스 백업하기

mysqldump를 이용한 전체 백업

가장 안전하고 널리 사용되는 방법은 mysqldump 명령어를 사용하는 거겠죠?


이 방법은 SQL 형태로 데이터를 추출하므로 버전 간 호환성이 매우 뛰어나다는 장점이 있습니다.

# 전체 데이터베이스 백업 (구조 + 데이터 + 프로시저/함수 포함)
mysqldump -u root -p \
  --all-databases \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  --add-drop-database \
  --complete-insert \
  --extended-insert \
  --lock-tables=false \
  > full_backup_$(date +%Y%m%d_%H%M%S).sql

위 코드에서 수행된 주요 옵션을 살펴볼게요.

  • -single-transaction: InnoDB 테이블의 일관성 있는 백업 보장
  • -routines: 저장 프로시저와 함수 포함
  • -triggers: 트리거 포함
  • -events: 이벤트 스케줄러 포함
  • -complete-insert: 컬럼명을 포함한 완전한 INSERT 문 생성
  • -lock-tables=false: 백업 중 테이블 잠금 방지 (서비스 영향 최소화)

백업 파일 압축하기

백업 파일이 클 경우에는, 압축하여 전송 시간을 단축하는 것 또한 매우 중요하다고 생각하빈다.

# 백업과 동시에 압축
mysqldump -u root -p --all-databases [옵션들] | gzip > full_backup_$(date +%Y%m%d_%H%M%S).sql.gz

# 또는 이미 생성된 백업 파일 압축
gzip full_backup_20241201_143022.sql

2. 특정 데이터베이스만 백업하기

전체 데이터베이스가 아닌 특정 데이터베이스만 마이그레이션이 필요한 경우에는 아래 코드를 참고하시면 됩니다.

# 단일 데이터베이스 백업
mysqldump -u root -p \
  --databases mydatabase \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  > mydatabase_backup_$(date +%Y%m%d_%H%M%S).sql

# 여러 데이터베이스 백업
mysqldump -u root -p \
  --databases db1 db2 db3 \
  --single-transaction \
  > multiple_db_backup_$(date +%Y%m%d_%H%M%S).sql

3. 특정 테이블만 백업하기

대용량 데이터베이스에서 일부 테이블만 마이그레이션이 필요한 상황이 있을 수 있어요.

# 단일 테이블 백업
mysqldump -u root -p \
  mydatabase mytable \
  --single-transaction \
  > mytable_backup_$(date +%Y%m%d_%H%M%S).sql

# 여러 테이블 백업
mysqldump -u root -p \
  mydatabase table1 table2 table3 \
  --single-transaction \
  > selected_tables_backup_$(date +%Y%m%d_%H%M%S).sql

# 특정 조건의 데이터만 백업 (WHERE 절 사용)
mysqldump -u root -p \
  mydatabase mytable \
  --where="created_at >= '2024-01-01'" \
  --single-transaction \
  > mytable_partial_backup.sql

테이블 구조만 백업하기

데이터 없이 스키마(Scheme) 구조만 가져와야 하는 경우도 있죠?

# 구조만 백업
mysqldump -u root -p \
  --no-data \
  mydatabase \
  > mydatabase_schema_only.sql

데이터 복원하기

4. B 서버로 데이터 복원하기

백업 파일 전송

먼저 A 서버에서 B 서버로 백업 파일을 안전하게 전송해야 합니다.

# SCP를 이용한 파일 전송
scp full_backup_20241201_143022.sql.gz user@B서버IP:/backup/

# rsync를 이용한 전송 (대용량 파일에 효율적)
rsync -avz --progress full_backup_20241201_143022.sql.gz user@B서버IP:/backup/

B 서버에서 데이터 복원

B 서버에 접속해 백업 파일을 복원해줍시다.

# 압축 파일인 경우 먼저 압축 해제
gunzip full_backup_20241201_143022.sql.gz

# 전체 데이터베이스 복원
mysql -u root -p < full_backup_20241201_143022.sql

# 특정 데이터베이스 복원
mysql -u root -p mydatabase < mydatabase_backup_20241201_143022.sql

# 진행 상황을 보면서 복원 (pv 명령어 필요)
pv full_backup_20241201_143022.sql | mysql -u root -p
    Tag -

Loading script...