개요
데이터베이스 마이그레이션은 시스템 운영자에게 있어서 가장 긴장되는 순간이 아닐까 생각합니다.
특히 운영 서버에서 동작 중인 서비스의 데이터를 옮기는 작업은 단 하나의 데이터도 잃어서는 안 되기에 더욱 신중해야 합니다.
이번 게시글에서는 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