데이터베이스 마이그레이션의 필요성
데이터베이스 마이그레이션은 단순히 데이터를 옮기는 작업을 넘어, 서비스의 안정성과 확장성을 확보하기 위한 핵심적인 과정입니다. 흔히 이사에 비유되곤 하는 이 작업은 다음과 같은 기술적 요구 사항으로 인해 발생합니다.
- 인프라 확장성 확보: 데이터 유입량이 급증하여 현재 스토리지나 컴퓨팅 자원으로는 감당하기 어려운 경우.
- 기술 부채 해소: 보안 취약점이 발견된 구형 엔진(예: MySQL 5.6 이하)을 최신 버전으로 업그레이드해야 하는 경우.
- 성능 최적화: 단일 인스턴스의 부하를 분산하기 위해 샤딩을 도입하거나 클라우드 네이티브 환경으로 이전하는 경우.
- 비용 효율화: 온프레미스 장비의 유지보수 비용을 줄이기 위해 클라우드 관리형 서비스(RDS 등)로 전환하는 경우.
마이그레이션 전략: 서비스 환경에 따른 선택
1. 오프라인 마이그레이션 (Offline Migration)
서비스를 일시적으로 중단하고 데이터를 한 번에 옮기는 방식입니다. 데이터 정합성 보장이 가장 확실하며 절차가 단순하지만, 중단 시간(Downtime)이 발생한다는 단점이 있습니다.
주요 단계: 서비스 중단 → 데이터 덤프(Export) → 데이터 복원(Import) → 검증 → 서비스 재개
#!/bin/bash
# 오프라인 데이터베이스 이전 자동화 스크립트 예시
# 변수 설정
SRC_HOST="legacy-db.internal"
DEST_HOST="new-cluster.cloud"
DB_NAME="service_production"
BACKUP_FILE="/tmp/db_migration_$(date +%Y%m%d).sql"
echo "[1/5] 어플리케이션 트래픽 차단 및 서비스 중지..."
# systemctl stop app-nodes
echo "[2/5] 소스 데이터베이스에서 데이터 추출 중..."
mysqldump -h $SRC_HOST -u admin -p \
--single-transaction \
--routines --triggers --events \
$DB_NAME > $BACKUP_FILE
echo "[3/5] 타겟 데이터베이스로 데이터 로드 중..."
mysql -h $DEST_HOST -u admin -p $DB_NAME < $BACKUP_FILE
echo "[4/5] 데이터 정합성 검증..."
# checksum 또는 row count 비교 로직 실행
python3 verify_counts.py --src $SRC_HOST --dest $DEST_HOST
echo "[5/5] 엔드포인트 설정 업데이트 및 서비스 시작..."
# sed -i 's/legacy-db/new-cluster/g' /etc/app/config.yaml
# systemctl start app-nodes
echo "마이그레이션이 성공적으로 완료되었습니다."
2. 온라인 마이그레이션 (Zero-Downtime Migration)
서비스 중단 시간을 최소화하거나 아예 없애는 방식입니다. 소스 DB의 데이터를 실시간으로 타겟 DB에 복제(Replication)하면서 전환 시점에만 엔드포인트를 교체합니다.
핵심 매커니즘: 초기 스냅샷 전송 후 CDC(Change Data Capture) 기술을 이용하여 변경분(Incremental Data)을 지속적으로 동기화합니다.
import time
import logging
class MigrationOrchestrator:
"""무중단 데이터 마이그레이션 제어 클래스"""
def __init__(self, src_conn, dest_conn):
self.src = src_conn
self.dest = dest_conn
self.is_ready_to_cutover = False
def start_process(self):
try:
# 1단계: 전체 데이터 스냅샷 동기화
self._initial_full_sync()
# 2단계: 실시간 증분 데이터 추적 및 동기화
self._stream_incremental_changes()
# 3단계: 정합성 체크 및 전환 대기
if self._validate_integrity():
self.is_ready_to_cutover = True
print("전환 준비 완료: 지연 시간(Lag)이 임계치 미만입니다.")
except Exception as e:
logging.error(f"마이그레이션 중 오류 발생: {e}")
self._rollback()
def _stream_incremental_changes(self):
"""CDC 또는 Binlog 기반 복제 모니터링"""
while not self.is_ready_to_cutover:
replication_lag = self._get_sync_lag()
print(f"현재 동기화 지연 시간: {replication_lag}초")
# 지연 시간이 1초 미만일 때 전환 프로세스 진입 가능
if replication_lag < 1:
break
time.sleep(5)
def _get_sync_lag(self):
# 타겟 DB에서 복제 상태 확인 쿼리 실행 (예: SHOW SLAVE STATUS)
return 0.5 # 샘플 반환값
def _validate_integrity(self):
"""핵심 테이블의 행 수 및 체크섬 비교"""
print("데이터 검증 수행 중...")
# 핵심 비즈니스 테이블 샘플링 검사 로직
return True
def _rollback(self):
print("작업 취소 및 롤백 수행")
# 인스턴스 생성 및 실행
# orchestrator = MigrationOrchestrator(src_db_config, dest_db_config)
# orchestrator.start_process()
성공적인 이전을 위한 체크리스트
안전한 마이그레이션을 위해 실행 전 다음 사항을 반드시 점검해야 합니다.
- 네트워크 대역폭: 데이터 전송 시 실시간 서비스의 네트워크 성능에 영향을 주지 않는지 확인합니다.
- 권한 설정: 타겟 DB에 애플리케이션이 접근할 수 있는 적절한 IAM 역할 또는 유저 권한이 설정되었는지 확인합니다.
- 파라미터 그룹: 소스와 타겟 DB 간의 Timezone, Character Set 등의 설정이 일치하는지 검증합니다.
- 롤백 시나리오: 전환 후 예상치 못한 오류 발생 시 이전 데이터베이스로 즉시 되돌릴 수 있는 방안을 마련해 두어야 합니다.