Linuxの増分バックアップをする(サーバへバックアップ)

[この記事の続き](https://qiita.com/ykgeek/items/988db214b7ccaedca27c)です。詳細はこの記事で紹介しているのでそちらをご覧ください。
この記事ではサーバへバックアップする方法を紹介します。

~~リストア方法は現在記事を用意しているのでお待ちください。
(rsyncを使って逆のことをすればいいだけなのでそんなに難しくはありませんが…)~~

追記(2020/03/12)
お待たせしました。リストア方法も用意しました。詳しくは[こちら](https://qiita.com/ykgeek/items/6683a8ac6f1497b4eb25)
rsyncのコマンドにH,A,Xオプションを追加しました。

**使用する際は必ず復元できるところまで確認してから使用してください。**

# TL;DR
ここで紹介する方法は端末backupsvから端末host1のデータを転送してバックアップする方法です。イメージとしては下記のようにbackupsvからhost1のデータを引っ張ってきて保存する感じです。

host1 ---> backupsv(バックアップスクリプトを実行する端末)

複雑にはなりますが、複数のLinux端末をまとめてバックアップする際に便利です。
下記のスクリプトをバックアップを保存するサーバに置いてrootで実行してください。

```bash:backup
#! /bin/bash

# Backup source information
# Hostname
BUHOST="host1"
# Source directory (Backup all directories and files)
SYSTEMPATH="/"

# Backup destination information
# Destination directory
BACKUPBASEDIR="/path/to/backup"

# Backup exclude flags
EXCLUDEFLAG=`echo "--exclude="{/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}`
#EXCLUDEFLAG="--exclude=/dev/* --exclude=/proc/* --exclude=/sys/* --exclude=/tmp/* --exclude=/run/* --exclude=/mnt/* --exclude=/media/* --exclude=/lost+found"


# Prepare for each host directory
BACKUPDIR="${BACKUPBASEDIR}/${BUHOST}"
if [ ! -d ${BACKUPDIR} ]; then
  mkdir -p ${BACKUPDIR}
fi

#Find previous backup
OLDDATE="NewBackup"
if [ -f ${BACKUPDIR}/latest ]; then
  OLDDATE=$(cat ${BACKUPDIR}/latest)
fi
NEWDATE=$(date +%Y%m%d)

# Get backup path
OLDBU=${BACKUPDIR}/${OLDDATE}
NEWBU=${BACKUPDIR}/${NEWDATE}

# Skip backup if already backup today
if [ ${OLDDATE} = ${NEWDATE} ];then
  echo "Already backed up today."
  exit 0
fi

echo "Backing up ${OLDDATE} -> ${NEWDATE}"
echo "Continue after 5sec..."

sleep 5

# Backup using rsync
rsync -aHAXz --info=progress2 --numeric-ids --rsync-path='sudo rsync' ${EXCLUDEFLAG} --link-dest=${OLDBU} ${BUHOST}:${SYSTEMPATH} ${NEWBU}

# Check backup status
if [ ! "$?" = "0" ];then
  echo "Backup failed."
  exit 1
fi

# Save latest backup date
echo ${NEWDATE} > ${BACKUPDIR}/latest

echo "Backup complete."

```

# メリット、デメリット
外付けHDDで保存する際とあまり変わりませんが、こちらはバックアップ用にサーバを用意するので、複数台の端末をバックアップする際に一箇所からまとめてバックアップできます。

デメリットとしては、ssh経由で通信するためクライアント側(もしくはサーバ側)にsshサーバを立てておく必要があります。
また、権限などの情報も保持するためにrsyncをroot権限で実行できる必要があります。(rootで実行できる環境であれば問題ありませんが、必要であればsudoersに設定を追加する必要があります)
またsshの設定をしておく必要があります。

# バックアップの流れ
前回の記事で説明しているのでここでは変更点のみをピックアップして説明していきます。

## バックアップする場所と保存先を指定
```bash:backup
# Backup source information
# Hostname
BUHOST="host1"
# Source directory (Backup all directories and files)
SYSTEMPATH="/"

# Backup destination information
# Destination directory
BACKUPBASEDIR="/path/to/backup"
```
今回はBUHOSTで(sshでの)ホスト名を指定しています。
また、BACKUPBASEDIRでバックアップディレクトリを指定します。（さらにその中にホストごとのディレクトリが自動生成されます）

## バックアップから除外するディレクトリを指定
同じなので省略

## 前回と今回のバックアップの保存先を取得
```bash:backup
# Prepare for each host directory
BACKUPDIR="${BACKUPBASEDIR}/${BUHOST}"
if [ ! -d ${BACKUPDIR} ]; then
  mkdir -p ${BACKUPDIR}
fi

#Find previous backup
...
```
バックアップ先のディレクトリに指定したホスト用のディレクトリが存在するか確認し、なければ生成します。
他は前回と同じです。

## バックアップ
```bash:backup
...

# Backup using rsync
rsync -aHAXz --info=progress2 --numeric-ids --rsync-path='sudo rsync' ${EXCLUDEFLAG} --link-dest=${OLDBU} ${BUHOST}:${SYSTEMPATH} ${NEWBU}

# Check backup status
...
```
rsyncのコマンドのの前後は前回と同じです。
今回はリモートでデータを送受信しているためオプションが多少異なります。

| オプション     | 説明                                |
|--------------|-------------------------------------|
| -z           | データを圧縮して送受信                  |
| --rsync-path | リモート側のrsyncコマンドのパスを指定する |

ちなみに--rsync-pathを指定してリモート側でもrsyncをrootで実行できるようにしています。

# あとがき
こちらもなかなか分かりにくい説明になってしまいました。
改善点や間違い等ありましたらご指摘いただければ幸いです。