리눅스에서 웹/DB를 외부로 원격 백업하기

현재 이 블로그는 Oracle Cloud Free Tier 중 ARM 기반 Ampere A1 인스턴스를 기반으로 돌아가고 있다. 성능적으로 불만은 전혀 없지만 가끔 ARM이라 쓰고 싶은 패키지의 빌드가 안되는 경우가 있어서 짜증나는 경우가 조금 있는데, 어쨌든, 이 글에서 그런 이야기를 할 것은 아니고. 오라클 클라우드 무료버전을 쓰다가 앞뒤 자르고 그냥 이용이 제한되는 경우가 있다고 몇번 불만을 토로하는 글을 본 적이 있다. 따라서, 데이터의 안전성을 보장하기 위해서 사양이 떨어지는 대신 좀 오랫동안 쓰고 있는 내 서버에 원격으로 백업하는 스크립트를 대충 복붙도 하고, 수정도 해서 만들어 두었다.

개념은 이렇다. (1) 원본 서버에서 장기간을 커버할 수 있는 백업파일을 만들어 두면 (2) 백업 서버에서 원격으로 접속해서 파일을 복사해간다. 백업은 월화수목금토일 / 1234주차 / 홀짝월로 총 13개 파일이 유지되며 자동으로 덮어씌운다. 이를 GFS 순환이라고 부른다.

아래 스크립트를 원본 서버의 cron.daily에 만들자. 필요한 부분은 적절히 수정해서 쓰자.

#!/bin/bash
####################################
#
# Backup to NFS mount script with
# grandfather-father-son rotation.
#
####################################

# What to backup.
backup_files="/where/to/backup/1 /where/to/backup/2"
database_id="idid"
database_pw="pwpw"

# Where to backup to.
dest="/var/backups/wholeweb"
dest_db="/var/backups/database"

# Setup variables for the archive filename.
day=$(date +%A)
hostname=$(hostname -s)

# Find which week of the month 1-4 it is.
day_num=$(date +%-d)
if (( $day_num <= 7 )); then
        week_file="$hostname-week1.tgz"
elif (( $day_num > 7 && $day_num <= 14 )); then
        week_file="$hostname-week2.tgz"
elif (( $day_num > 14 && $day_num <= 21 )); then
        week_file="$hostname-week3.tgz"
elif (( $day_num > 21 && $day_num < 32 )); then
        week_file="$hostname-week4.tgz"
fi

# Find if the Month is odd or even.
month_num=$(date +%m)
month=$(expr $month_num % 2)
if [ $month -eq 0 ]; then
        month_file="$hostname-month2.tgz"
else
        month_file="$hostname-month1.tgz"
fi

# Create archive filename.
if [ $day_num == 1 ]; then
    archive_file=$month_file
elif [ $day != "Saturday" ]; then
        archive_file="$hostname-$day.tgz"
else
    archive_file=$week_file
fi

# Print start status message of DB backup process.
echo "Backing up $backup_databases to $dest_db"
date
echo

# Backup the databases using mariabackup.
rm -rf $dest_db/*
mysqldump -u$database_id -p$database_pw db1 > $dest_db/db1.sql
mysqldump -u$database_id -p$database_pw db2 > $dest_db/db2.sql
mysqldump -u$database_id -p$database_pw db3 > $dest_db/db3.sql

# Print start status message of Web and DB backup process.
echo "Backing up $backup_files to $dest/$archive_file"
date
echo

# Backup the files using tar.
tar --zstd -cf $dest/$archive_file $backup_files

# Print end status message.
echo
echo "Backup finished"
date

# Long listing of files in $dest to check file sizes.
ls -lh $dest/Code language: PHP (php)

이렇게 원본 서버에 백업파일이 준비되면 아래처럼 백업서버의 cron.daily에 작성한다.

#!/bin/bash
rsync -az -e " ssh -i /path/to/key " 원본서버userid@원본서버ip:/var/backups/wholeweb /백업서버의/백업경로/Code language: JavaScript (javascript)

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *