안녕하세요! FreeBSD 서버를 운영할 때 데이터 백업은 선택이 아닌 필수입니다. 예기치 않은 문제로 데이터를 잃는 것만큼 끔찍한 일은 없죠. 오늘은 서버에 새 디스크를 추가하고, FreeBSD의 기본 파일 시스템인 UFS로 포맷한 뒤, rsync
와 cron
을 이용해 중요 디렉토리를 매일 자동으로 백업하는 과정을 처음부터 끝까지 정리해보려고 합니다.
이 가이드에서는 예시로 120GB 용량의 da0
디스크를 백업용으로 추가하고 설정하는 과정을 다룹니다.
Part 1: 백업 디스크 준비 및 포맷 (UFS)
먼저 백업용으로 사용할 새 디스크를 시스템에 장착하고 부팅한 후, FreeBSD에서 인식하는지 확인하고 UFS 파일 시스템으로 포맷합니다.
⚠️ 경고: 아래 과정은 지정된 디스크의 모든 데이터를 완전히 삭제합니다! 대상 디스크 이름(이 예제에서는 da0
)이 정확한지 반드시 여러 번 확인하고, 실수로 시스템 디스크(ada0
등)를 선택하지 않도록 각별히 주의하십시오!
대상 디스크 확인: gpart show
명령으로 시스템에 연결된 디스크와 파티션 정보를 확인하고, 포맷할 디스크의 이름(예: da0
)을 정확히 확인합니다.
root@nimfsoft:~ # gpart show
=> 40 976773088 ada0 GPT (466G)
40 532480 1 efi (260M)
532520 1024 2 freebsd-boot (512K)
533544 984 - free - (492K)
534528 4194304 3 freebsd-swap (2.0G)
4728832 972044288 4 freebsd-zfs (464G)
976773120 8 - free - (4.0K)
=> 63 252180417 da0 MBR (120G)
63 1985 - free - (993K)
2048 252178399 1 ntfs (120G)
252180447 33 - free - (17K)
Code language: PHP (php)
(선택 사항) 기존 파티션 마운트 해제: 대상 디스크에 기존 파티션이 있고 마운트되어 있다면 안전을 위해 해제합니다.
mount | grep da0
# 만약 마운트되어 있다면 umount /dev/da0sX 또는 umount /mount/point
Code language: PHP (php)
기존 파티션 테이블 삭제: 대상 디스크(da0
)의 파티션 정보를 완전히 지웁니다. 다시 한번 디스크 이름을 확인하세요!
gpart destroy -F da0
새 파티션 테이블 생성 (GPT): 현대적인 GPT 파티션 테이블을 생성합니다.
gpart create -s GPT da0
FreeBSD UFS 파티션 추가: 디스크 전체 공간을 사용하는 UFS 파티션을 만들고, 나중에 쉽게 식별할 수 있도록 레이블(backup_disk
)을 붙입니다.
gpart add -t freebsd-ufs -l backup_disk da0
UFS 파일 시스템 생성 (포맷): 생성된 파티션에 UFS 파일 시스템을 만듭니다. -U
옵션으로 Soft Updates를 활성화합니다.
newfs -U /dev/gpt/backup_disk
마운트 포인트 생성 및 테스트: 파일 시스템을 연결할 디렉토리를 만들고 수동으로 마운트하여 정상 작동하는지 확인합니다.
mkdir /mnt/backup_disk
mount /dev/gpt/backup_disk /mnt/backup_disk
df -h
(df -h
결과에 /mnt/backup_disk
가 보이면 성공)
자동 마운트 설정 (/etc/fstab
): 시스템 부팅 시 자동으로 마운트되도록 /etc/fstab
파일에 다음 줄을 추가합니다.
# Device Mountpoint FStype Options Dump Pass#
/dev/gpt/backup_disk /mnt/backup_disk ufs rw 2 2
Code language: PHP (php)
이제 디스크 준비가 완료되었습니다!
Part 2: 자동 백업 설정 (rsync + cron)
이제 준비된 /mnt/backup_disk
에 중요 데이터를 매일 자동으로 백업하도록 설정합니다. 여기서는 rsync
를 사용해 특정 디렉토리들을 미러링하는 방식을 사용합니다.
백업 전략 정의:
- 무엇을: 중요 설정(
/usr/local/etc
), 웹 데이터(/usr/local/www
), 사용자 홈(/home
), 기타 중요 데이터(/usr/local/backup
), 시스템 로그(/var/log
) 등 백업할 디렉토리를 결정합니다. - 어디로:
/mnt/backup_disk
아래에 각 소스별 하위 디렉토리를 만들어 저장합니다. - 어떻게:
rsync
로 동기화합니다.--delete
옵션으로 원본에서 삭제된 파일은 백업에서도 삭제합니다 (미러링). - 언제:
cron
을 이용해 매일 새벽 3시에 실행합니다.
백업 스크립트 작성: 자동 백업을 수행할 셸 스크립트를 작성합니다. 여기서는 /var/log
백업 중 로그 파일 변경 문제를 피하기 위해 로그를 /root
에 임시 저장 후 최종 로그 파일에 추가하는 방식을 사용합니다.
#!/bin/sh
# 백업 설정
BACKUP_DST="/mnt/backup_disk"
SOURCES="/var/log /usr/local/backup /usr/local/etc /usr/local/www /home" # 백업할 디렉토리 목록
FINAL_LOG_FILE="/var/log/rsync_backup.log"
TMP_LOG_FILE="/root/rsync_backup.tmp.$$" # 임시 로그 파일 (프로세스 ID 기반)
# 최종 로그 파일에 시작 로그 기록
echo "=== Rsync Backup started at $(date) ===" >> ${FINAL_LOG_FILE}
# 임시 로그 파일 초기화
> ${TMP_LOG_FILE}
# 각 소스 디렉토리에 대해 rsync 실행 (로그는 임시 파일에 기록)
(
overall_success=0 # 전체 성공 여부 플래그 (0: 성공, 1: 하나라도 실패)
for src in ${SOURCES}; do
# 경로에서 디렉토리 이름 추출 (예: /var/log -> var_log)
dest_subdir=$(echo ${src} | sed 's:/*$::' | sed 's:^/*::' | tr '/' '_')
dest_path="${BACKUP_DST}/${dest_subdir}"
echo "Syncing ${src} to ${dest_path} ..."
# 목적지 디렉토리 없으면 생성
mkdir -p ${dest_path}
# rsync 실행 (-v 옵션은 필요에 따라 추가/제거)
# --delete 옵션은 소스에 없는 파일을 백업에서도 삭제 (주의: 로그 등은 의도와 다를 수 있음)
rsync -a --delete ${src}/ ${dest_path}/
if [ $? -ne 0 ]; then
echo "!!! ERROR syncing ${src} !!!"
overall_success=1 # 실패 시 플래그 설정
fi
done
exit ${overall_success} # 루프 종료 시 성공/실패 상태 반환
) >> ${TMP_LOG_FILE} 2>&1 # 루프 전체 출력을 임시 로그에 추가
# 루프 종료 상태 저장
loop_exit_status=$?
# 임시 로그 파일 내용을 최종 로그 파일에 추가
cat ${TMP_LOG_FILE} >> ${FINAL_LOG_FILE}
# 최종 결과 로그 기록
if [ ${loop_exit_status} -eq 0 ]; then
echo "All rsync tasks completed successfully." >> ${FINAL_LOG_FILE}
else
echo "!!! Some rsync tasks FAILED. Check logs above. !!!" >> ${FINAL_LOG_FILE}
fi
# 임시 로그 파일 삭제
rm -f ${TMP_LOG_FILE}
# 최종 로그 파일에 완료 로그 기록
echo "=== Rsync Backup finished at $(date) ===" >> ${FINAL_LOG_FILE}
echo "" >> ${FINAL_LOG_FILE}
exit ${loop_exit_status}
Code language: PHP (php)
스크립트 실행 권한 부여:
chmod +x /usr/local/sbin/rsync_backup.sh
스크립트 수동 실행 테스트: /mnt/backup_disk
가 마운트된 상태에서 스크립트를 직접 실행하여 오류 없이 백업이 잘 수행되는지, 로그 파일(/var/log/rsync_backup.log
)이 정상적으로 기록되는지 확인합니다.
# root 권한으로 실행
/usr/local/sbin/rsync_backup.sh
Code language: PHP (php)
cron
작업 등록: root
사용자의 crontab에 스크립트를 등록하여 매일 새벽 3시에 자동 실행되도록 합니다.
crontab -e
편집기에서 다음 줄 추가:
# Minute Hour Day Month DayOfWeek Command
0 3 * * * /usr/local/sbin/rsync_backup.sh
Code language: PHP (php)
저장하고 종료합니다.
Part 3: 확인 및 고려사항
- 로그 확인: 매일 백업 실행 후
/var/log/rsync_backup.log
파일을 확인하여 성공 여부와 특이사항을 점검하세요. - 백업 내용 확인: 가끔씩
/mnt/backup_disk
아래의 백업된 파일들이 최신 상태인지, 필요한 파일들이 모두 있는지 직접 확인하는 것이 좋습니다. - 일시적 멈춤 현상: 대량의
rsync
작업 직후 백업 디스크에ls
등으로 접근 시 잠시 멈춘 것처럼 보일 수 있습니다. 이는 운영체제가 쓰기 캐시를 디스크에 기록(sync)하는 과정에서 발생하는 일시적인 I/O 지연일 가능성이 높으니 잠시 기다려보세요. - 복원 테스트: 가장 중요합니다! 아무리 백업이 잘 되어도 복원이 안 되면 소용없습니다. 정기적으로 백업된 데이터로부터 실제 복구를 시도해보는 테스트를 반드시 수행해야 합니다.
- 백업 용량 관리: 현재
rsync
스크립트는--delete
옵션으로 미러링만 할 뿐, 날짜별 전체 백업본을 만들거나 오래된 백업본 세트를 삭제하지는 않습니다. 백업 디스크 용량이 부족해지지 않도록 주기적으로 관리하거나,tar
압축 백업과 오래된 파일 삭제 로직을 추가하는 등 전략 수정이 필요할 수 있습니다. - 데이터베이스 백업: 데이터베이스는
rsync
로 파일만 복사하는 것이 아니라,mysqldump
나pg_dump
등으로 먼저 덤프 파일을 생성한 후 그 덤프 파일을 백업 대상에 포함시켜야 안전합니다.
마무리
이제 FreeBSD 서버에 별도의 백업 디스크를 준비하고, rsync
와 cron
을 이용해 중요 데이터를 자동으로 백업하는 시스템을 구축했습니다. 이 가이드가 안정적인 서버 운영에 도움이 되기를 바랍니다. 각자의 환경과 필요에 맞게 백업 대상이나 스크립트 내용을 적절히 수정하여 사용하시고, 무엇보다 정기적인 점검과 복원 테스트를 잊지 마세요!
답글 남기기