데이터베이스 백업과 복구 전략


데이터베이스 백업과 복구는 시스템 운영의 핵심입니다. 장애 발생 시 데이터 손실을 최소화하고 신속하게 서비스를 복구하기 위한 전략을 알아봅니다.



언제 사용하나요?



  • 하드웨어 장애 대비

  • 사용자 실수로 인한 데이터 삭제 복구

  • 랜섬웨어/보안 사고 대응

  • 마이그레이션 및 환경 복제



백업 유형


1. 전체 백업 (Full Backup)
- 모든 데이터 복사
- 복구 가장 간단
- 시간/공간 많이 소요

2. 증분 백업 (Incremental)
- 마지막 백업 이후 변경분만
- 빠른 백업
- 복구 시 모든 증분 필요

3. 차등 백업 (Differential)
- 마지막 전체 백업 이후 변경분
- 증분보다 큰 용량
- 복구 시 전체 + 마지막 차등만 필요

추천 전략:
- 일요일: 전체 백업
- 월~토: 증분 또는 차등 백업


MySQL/MariaDB 백업


# mysqldump - 논리 백업
# 전체 백업
mysqldump -u root -p --all-databases > full_backup.sql

# 특정 데이터베이스
mysqldump -u root -p mydb > mydb_backup.sql

# 특정 테이블
mysqldump -u root -p mydb users orders > tables_backup.sql

# 옵션
mysqldump -u root -p
--single-transaction # InnoDB 일관성
--routines # 프로시저 포함
--triggers # 트리거 포함
--events # 이벤트 포함
--quick # 대용량 테이블
mydb > backup.sql

# 복원
mysql -u root -p mydb < backup.sql

# 바이너리 로그 백업 (Point-in-Time 복구용)
mysqlbinlog mysql-bin.000001 > binlog_backup.sql


PostgreSQL 백업


# pg_dump - 논리 백업
pg_dump -U postgres mydb > mydb_backup.sql

# 커스텀 포맷 (압축)
pg_dump -U postgres -Fc mydb > mydb_backup.dump

# 전체 클러스터
pg_dumpall -U postgres > full_backup.sql

# 복원
psql -U postgres mydb < mydb_backup.sql
pg_restore -U postgres -d mydb mydb_backup.dump

# 병렬 백업/복원 (대용량)
pg_dump -U postgres -Fd -j 4 mydb -f backup_dir/
pg_restore -U postgres -d mydb -j 4 backup_dir/


Oracle 백업


-- RMAN (Recovery Manager)
-- 전체 백업
RMAN> BACKUP DATABASE;

-- 증분 백업
RMAN> BACKUP INCREMENTAL LEVEL 0 DATABASE; -- 기준
RMAN> BACKUP INCREMENTAL LEVEL 1 DATABASE; -- 증분

-- 아카이브 로그 포함
RMAN> BACKUP DATABASE PLUS ARCHIVELOG;

-- 복원
RMAN> RESTORE DATABASE;
RMAN> RECOVER DATABASE;

-- Data Pump (논리 백업)
expdp system/password DIRECTORY=backup_dir DUMPFILE=full.dmp FULL=Y
impdp system/password DIRECTORY=backup_dir DUMPFILE=full.dmp FULL=Y


자동화 스크립트


#!/bin/bash
# daily_backup.sh

# 설정
DB_USER="root"
DB_PASS="password"
DB_NAME="mydb"
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7

# 백업 실행
mysqldump -u $DB_USER -p$DB_PASS
--single-transaction
--routines --triggers
$DB_NAME | gzip > $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz

# 결과 확인
if [ $? -eq 0 ]; then
echo "백업 성공: ${DB_NAME}_${DATE}.sql.gz"
else
echo "백업 실패!" | mail -s "DB Backup Failed" admin@example.com
exit 1
fi

# 오래된 백업 삭제
find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete

# crontab 등록
# 0 2 * * * /scripts/daily_backup.sh >> /var/log/backup.log 2>&1


Point-in-Time 복구 (PITR)


# MySQL - 바이너리 로그 사용
# 1. 전체 백업 복원
mysql -u root -p mydb < full_backup.sql

# 2. 특정 시점까지 바이너리 로그 적용
mysqlbinlog --stop-datetime="2024-01-15 10:30:00"
mysql-bin.000001 mysql-bin.000002 | mysql -u root -p

# PostgreSQL - WAL 사용
# 1. 기본 백업 복원
# 2. recovery.conf 설정
recovery_target_time = "2024-01-15 10:30:00"
# 3. 서버 시작 시 WAL 적용


클라우드 백업


# AWS S3로 백업
mysqldump -u root -p mydb | gzip |
aws s3 cp - s3://my-bucket/backup/mydb_$(date +%Y%m%d).sql.gz

# 복원
aws s3 cp s3://my-bucket/backup/mydb_20240115.sql.gz - |
gunzip | mysql -u root -p mydb

# AWS RDS 자동 백업
# - 자동 스냅샷 (보존 기간 설정)
# - 수동 스냅샷 (영구 보존)
# - Point-in-Time 복구 지원


복구 테스트


복구 테스트 체크리스트:
1. 정기적 복구 테스트 (최소 분기별)
2. 별도 환경에서 복원 검증
3. 데이터 무결성 확인
4. 애플리케이션 연동 테스트
5. 복구 소요 시간 측정 (RTO)
6. 데이터 손실 범위 확인 (RPO)


RPO와 RTO






용어설명예시
RPO허용 가능한 데이터 손실 기간1시간 = 1시간치 데이터 손실 허용
RTO서비스 복구 목표 시간4시간 = 4시간 내 복구 완료