borgによる差分バックアップシステムの構築

この記事では、バックアップシステムを構築します。

写真や動画等の各種データなどをファイルサーバに保存していますが、hddの故障や操作ミスでデータが消えてしまったら、取り返しがつきませんね。

そこで、今回は差分バックアップツールであるborgを利用して、バックアップシステムを構築します。

borgは差分バックアップを行いますので、比較的少ないデータ量で複数世代のバックアップを構築することが可能となります。

なお、今回はArchLinuxにおける差分バックアップシステムです。

1.borgのインストール

サーバにて以下のコマンドでborgをインストールします。

$ sudo pacman -S borg

2.バックアップスクリプトの準備

2-1.バックアップスクリプトの作成

/root/scripts配下にbackup.shを以下のように作成します。

#!/bin/bash

######################################
# 各種パラメータ
######################################
# ホスト名
hostname=`/bin/hostname`

# バックアップ日時
date=`/bin/date +"%Y%m%d_%H%M"`

# バックアップディレクトリ
backup_dir="/backup/${hostname}"

# 差分バックアップ世代数 ※以下は、直近7日間と1週間ごと(最大4週間分)のバックアップを保持
file_keep_days=7
file_keep_weeks=4

# バックアップ対象リストファイル名
backup_list_file=/root/scripts/backup_list
if [ ! -s ${backup_list_file} ]; then
    echo "${backup_list_file} is not found."
    logger -t `basename ${0}` "backup aborted."
    cleanup
    exit 1
fi

# バックアップ対象リスト
backup_list="$(cat "${backup_list_file}" | tr "\n" " ")"

# バックアップ対象外リストファイル名
excluded_backup_list_file=/root/scripts/excluded_backup_list

# 後処理関数
cleanup () {
    rm -rf ${temp_excluded_backup_list_file}
    rm -rf ${backup_log_file}
}

######################################
# 処理
######################################

# バックアップディレクトリの初期化
if [ ! -d ${backup_dir} ]; then
    mkdir -p ${backup_dir}
    borg init --encryption=none ${backup_dir}
fi

# バックアップディレクトリをバックアップ対象外リストに追加
temp_excluded_backup_list_file=`mktemp`
if [ -s ${excluded_backup_list_file} ]; then
    cat ${excluded_backup_list_file} > ${temp_excluded_backup_list_file}
fi
echo "${backup_dir}" >> ${temp_excluded_backup_list_file}

# バックアップ実行
backup_log_file=`mktemp`
logger -t `basename ${0}` "backup started."
borg create --exclude-from ${temp_excluded_backup_list_file} ${backup_dir}::${hostname}-${date} ${backup_list} > ${backup_log_file} 2>&1

code=$?
if [ ${code} -ne 0 ]; then
    logger -t `basename ${0}` "backup aborted."
    logger -t `basename ${0}` "$(cat "${backup_log_file}")"
    cleanup
    exit 1
fi

logger -t `basename ${0}` "backup finished."

# 古いバックアップ削除
borg prune -v --list --keep-daily=${file_keep_days} --keep-weekly=${file_keep_weeks} ${backup_dir} >> ${backup_log_file} 2>&1

# 後処理
cleanup

exit 0

スクリプトを保存しましたら、以下のコマンドで実行権限を与えます。

sudo chmod 700 backup.sh

2-2.バックアップディレクトリの準備

以下のコマンドでバックアップデータを保存するディレクトリを作成します。HDDの故障を考慮して、バックアップを保存するディレクトリはデータがあるHDDとは別のHDDに作成すると、なお良いと思います。

$ sudo mkdir /backup

2-2.バックアップ対象リストの作成

2-1.のスクリプトでは、/root/scripts/backup_listに記載されているパスのディレクトリやファイルをバックアップ対象と判断します。そのため、以下のように、/root/scripts/backup_listにバックアップしたい対象をフルパスで記述します。

/root
/home

2-3.バックアップ対象外リストの作成

2-1.のスクリプトでは、/root/scripts/excluded_backup_listに記載されているパスをバックアップ対象外と判断します。そのため、以下のように、/root/scripts/backup_listにバックアップから除外したい対象のフルパスで記述します。
なお、ワイルドカードも利用可能です。

/root/tmp
*.DS_Store
*.thumbnails

3.バックアップスクリプトの動作確認

以下のコマンドでバックアップスクリプトを実行します。

sudo /root/scripts/backup.sh

バックアップスクリプトの実行後に、バックアップディレクトリにサーバのホスト名と同じディレクトリが作成されていることを確認します。

#sudo ls /backup

【サーバホスト名】

borgではborg listコマンドで取得したバックアップのリストを表示可能ですので、以下のコマンドでバックアップリストを表示します。
以下コマンドでは、/backup/xxx-serverにバックアップを保存している場合。

# sudo borg list /backup/【サーバホスト名】
【サーバホスト名】-20180722_0939                Mon, 2018-07-22 09:39:15 [af91rcfe0r610brbcc35e429a7e593f6e657ef295ffa33ed46bbdb3e52bef55e]

さらに、以下のコマンドで取得したバックアップのリストが表示できます。

# sudo borg list /backup/【サーバホスト名】::【サーバホスト名】-20180722_0939

4.リストアの動作確認

borg extractコマンドでリストアができます。リストア先はカレントディレクトリになりますので、リストアしたいディレクトリに移動します。
ここでは、testディレクトリ配下にリストアします。

$ mkdir test
$ cd test

バックアップからすべてを復元する場合は、リストアしたいバックアップを以下のように指定します。

sudo borg extract  /backup/【サーバホスト名】::【サーバホスト名】-20180722_0939

特定のファイルやディレクトリを復元する場合は、リストアしたいフォルダやディレクトリを以下のように指定します。

sudo borg extract  /backup/【サーバホスト名】::【サーバホスト名】-20180722_0939 /home/mako/text.txt

5.バックアップスクリプトの自動化

systemdのtimerを利用して、バックアップスクリプトを毎日1時に実行するように設定します。

5-1.サービスファイルの作成

/etc/systemd/systemにbackup.serviceというサービスファイルを作成します。

[Unit]
Description=Daily Backup

[Service]
Type=simple
ExecStart=/root/scripts/backup.sh

5-2.タイマーファイルの作成

/etc/systemd/systemにbackup.timerというタイマーファイルを作成します。

[Unit]
Description=Daily backup Timer

[Timer]
OnCalendar=*-*-* 01:00:00
Unit=backup.service

[Install]
WantedBy=timers.target

5-3.タイマーの有効化

以下のコマンドでタイマーを有効化します。

sudo systemctl enable backup.timer

これで毎日1時にバックアップスクリプトが実行されます。

終わりに

今回は差分バックアップシステムの構築を紹介しました。これで、突然のhddの故障や操作ミスでデータが消えても最大で過去1ヶ月前までのバックアップからデータを復旧することができます。やっと一安心です。。。