왜 백업이 필요한가?
"미리 한 땀 꿰매면 열 땀을 아낀다"는 오래된 속담이 있듯이, 컴퓨터 세계에서 그 '한 땀'은 바로 백업입니다. 실제 서비스를 운영하는 IT 인프라에서는 서버와 애플리케이션의 가동률을 100%에 최대한 가깝게 유지하는 것이 필수적입니다. 인프라를 튼튼하게 만드는 방법은 여러 가지가 있지만, 어떤 방법으로도 완벽하게 무장애 상태를 보장할 수는 없습니다. 그렇기 때문에 반드시 플랜 B, 즉 백업 전략이 필요합니다.
서버의 세 가지 계층과 백업의 핵심
서버는 크게 하드웨어, 운영체제와 애플리케이션, 데이터라는 세 계층으로 구성됩니다. 하드웨어에 장애가 발생하면 새 장비로 교체하면 되고, 운영체제와 애플리케이션 설치 역시 비교적 간단합니다. 그러나 진짜 교체하기 어려운 것은 애플리케이션이 사용하는 데이터와 설정 정보입니다. 장애가 발생했을 때 이 부분은 되살릴 수 없기 때문에, 정기적인 백업을 통해 비상 상황에서도 빠르게 복구할 수 있도록 준비해야 합니다.
이 글에서는 리눅스(및 대부분의 *nix 운영체제)에서 매일 자동으로 백업을 수행하는 셸 스크립트를 작성하는 과정을 단계별로 안내합니다. 예제 환경은 Apache 웹 서버와 MySQL 데이터베이스 서버가 구동 중이며, /home 파티션에 백업이 필요한 데이터 디렉터리가 있는 서버입니다. 아울러 전날의 Apache 접속 로그도 별도 디렉터리에 함께 백업합니다.
1단계: 백업 디렉터리 구조 만들기
먼저 백업 파일이 저장될 디렉터리를 생성해야 합니다. 여기서는 /opt 파티션에 BACKUP이라는 디렉터리를 만들고, 매일의 백업이 /opt/BACKUP/연도/월/일/ 형태로 정리되도록 구성합니다. 예를 들어 2008년 8월 11일의 백업은 /opt/BACKUP/2008/08/11/에 저장됩니다.
root 사용자로 다음 명령어를 차례로 실행하세요.
# mkdir -p /opt/backup/DATA/2008
# cd /opt/backup/DATA/2008
# mkdir 01 02 03 04 05 06 07 08 09 10 11 12
# cd /opt/backup/DATA/
# cp -r 2008 2009
# cd /opt/backup/
# cp -r DATA LOG
마지막 chown 명령을 실행하기 전에 아래 참고 사항을 먼저 확인하세요.
# chown -R calvin.calvin /opt/backup
이제 데이터용과 로그 파일용, 두 개의 백업 디렉터리 세트가 준비되었습니다. 참고: 이 글에서는 calvin이라는 사용자를 기준으로 설명하니, 실제 적용 시에는 본인의 사용자 이름으로 바꿔 주세요.
2단계: 자동 백업 스크립트 작성하기
아래 스크립트는 데이터 백업(MySQL 덤프, /etc 설정, 웹 문서, 애플리케이션 파일)과 로그 백업(Apache 접속 로그), 그리고 결과 알림 메일 발송까지 한 번에 처리합니다. 각 설정 값은 주석을 참고해 자신의 환경에 맞게 수정하세요.
#####################################################
# CODE BEGINS HERE
#####################################################
#!/bin/bash
# SERVER DATA BACKUP V1.0
#########################
# BACKUP CONFIG
#########################
#Configure the month, date, and day
YEAR=`date +"%Y"` # 2008
MONTH=`date +"%m"`# 11
DAY=`date +"%d"` # 14
YESTERDAY=`date --date="yesterday" +%Y-%m-%d` # 2008-11-13
YESTERDAY_DATE=`date --date=yesterday +%d` # 13
YESTERDAY_MONTH=`date --date=yesterday +%m` # 11
YESTERDAY_YEAR=`date --date=yesterday +%Y` # 2008
TODAY=`date +%Y-%m-%d` # 2008-11-14
TODAY_DATE=`date +%d` # 14
# directories to backup to
DATA_BACKUP_PARENT_DIR=/opt/backup/DATA/ # <-- Change this your data backup dir
LOG_BACKUP_PARENT_DIR=/opt/backup/LOG/ # <-- Change this your log backup dir
# Apache Document Root Directory
APACHE_DOCROOT=/var/www/html/
# MySQL Database config
DB_IP="localhost" # <-- Change this to the IP of your database server
DB_USER="calvin" # <-- Change this to your database username
DB_PASS="calvin_password" # <-- Change this to your database password
DB_NAME="clientlist" # <-- Change this to your database name
# Apache Log Dir
APACHE_LOG_DIR="/var/log/httpd/" # <-- Change this to the path data of your logs
# Application Files' Dir
APP_FILES="/home/calvin/application_files/" # <-- Change this to the path of the data directory
# Config Dir
CONFIG_DIR="/etc/" # <-- Change this to the path data directory
# Mail report address
EMAIL_ID="you@youremailid.com" # <-- Change this to your e-mail ID
#####################################################
# DATA BACKUP
#####################################################
# Create and go into backup directory
cd $DATA_BACKUP_PARENT_DIR/$YEAR/$MONTH
mkdir $DAY
cd $DAY
# Database backup
mysqldump -h ${DB_IP} -u ${DB_USER} -p${DB_PASS} ${DB_NAME} > ${DB_NAME}.db
tar -zcvf ${DB_NAME}.tar.gz ${DB_NAME}.db
rm -f ${DB_NAME}.db
# /etc backup
tar -zcf etc.tar.gz /etc
# Application backup
tar -zcf Apache_Doc_Root.tar.gz ${APACHE_DOCROOT}
tar -zcf App_Files.tar.gz ${APP_FILES}
#####################################################
# LOG BACKUP
#####################################################
# Create and go into backup directory
cd $LOG_BACKUP_PARENT_DIR/$YESTERDAY_YEAR/$YESTERDAY_MONTH
mkdir $YESTERDAY_DATE
cd $YESTERDAY_DATE
# HTTPD Log Backup
for i in ${APACHE_LOG_DIR}/access_log.${YESTERDAY}*; do cp $i .; done
for i in access_log.${YESTERDAY}*; do gzip $i; done
#####################################################
# Send out mail notifications
#####################################################
# Mail notify
du -shc $DATA_BACKUP_PARENT_DIR/$YEAR/$MONTH/$DAY/* | mail -s "Backup for ${HOSTNAME}::DATA done :)" ${EMAIL_ID}
du -shc $LOG_BACKUP_PARENT_DIR/$YESTERDAY_YEAR/$YESTERDAY_MONTH/$YESTERDAY_DATE/* | mail -s "Backup for ${HOSTNAME}::LOG done :)" ${EMAIL_ID}
#####################################################
# CODE ENDS HERE
#####################################################
3단계: 실행 권한 부여 및 테스트
작성한 스크립트를 /home/calvin/scripts/backup.sh처럼 적절한 경로에 저장한 뒤, 실행 권한을 부여합니다.
# chmod +x /home/calvin/scripts/backup.sh
이제 준비가 끝났습니다. 명령줄에서 직접 실행해 정상 동작하는지 확인해 보세요.
# /home/calvin/scripts/backup.sh
4단계: cron으로 매일 자동 실행 등록하기
선택 사항이지만, 이 스크립트를 cron 작업으로 등록하면 매일 지정한 시간에 자동으로 백업이 수행됩니다. 매일 새벽 4시에 실행하려면 다음과 같이 설정합니다.
# crontab -e
열린 파일에 새 줄을 추가하고 아래 내용을 입력합니다.
0 4 * * * /home/calvin/scripts/backup.sh > /dev/null
마무리
이것으로 완성입니다! 이제 서버는 매일 새벽 4시에 데이터, 데이터베이스, 설정 파일, 애플리케이션 파일, 로그 파일을 /opt/backup에 자동으로 백업합니다. 완전히 자동화된 리눅스 백업 시스템이 구축된 것입니다. 다음 단계로는 백업 파일을 암호화하거나 원격 서버로 전송하는 방식을 추가하면 더욱 안전한 백업 체계를 갖출 수 있습니다.