簡単にファイルバックアップができる Restic を試してみた。

こんにちは k-jun です。今回はファイルのバックアップを作製し、S3、GCS、Local Storage などあらゆる箇所にアップロードできる Restic を試してみます。

https://github.com/restic/restic

一般的なバックアップって一定間隔でファイルを永続ストレージにコピーするだけなんですが、意外とめんどくさいんですよね..。 今回はありがちな使用方法として MySQL の dump ファイルを s3 にバックアップしてみようと思います。

$ brew install restic

s3 bucket は pulumi で適当に作成する。

$ aws s3 ls | grep pulumi-bucket
2021-08-21 19:24:29 pulumi-bucket-f083d0a

repository を作成する処理が必要みたいなので、以下を実行する。パスワードも求められたので適当に入力。

$ restic -r s3:s3.amazonaws.com/pulumi-bucket-f083d0a init
enter password for new repository:
enter password again:
created restic repository f8b91f1822 at s3:s3.amazonaws.com/pulumi-bucket-f083d0a

Please note that knowledge of your password is required to access
the repository. Losing your password means that your data is
irrecoverably lost.

何が作成されたのかなぁと中身を見てみると、config と keys という謎のファイルとディレクトリが。 config は中身がなにかわからず... keys の方は見れるんかい。

$ aws s3 cp s3://pulumi-bucket-f083d0a/config - | head -n 1
4*<&G擬?y

$ aws s3 cp s3://pulumi-bucket-f083d0a/keys/600ef982619cfef9209acaa16249d6587b918a3ae254e994defcc550c4ef9b7d - | jq
{
  "created": "2021-08-21T19:27:21.880674+09:00",
  "username": "XXX",
  "hostname": "XXX",
  "kdf": "XXX",
  "N": 32768,
  "r": 8,
  "p": 7,
  "salt": "XXX",
  "data": "XXX"
}

あとは以下のようなコマンドでバックアップを作成できそう。

$ restic -r s3:s3.amazonaws.com/pulumi-bucket-f083d0a --verbose backup /tmp/backup

なので、先に MySQL の dump ファイルを用意します。何度もお世話になっている MySQL の Docker。 一応 Table を作製して、復元できるか試すことにします。

$ docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -e MYSQL_USER=test -e MYSQL_PASSWORD=test -e MYSQL_DATABASE=test mysql:5.7

$ cat /tmp/schema.sql
CREATE TABLE todo (
    id INT NOT NULL AUTO_INCREMENT,
    title TEXT NOT NULL,
    body TEXT NOT NULL,
    status BOOLEAN DEFAULT FALSE,
    PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4;
$ mysql -uroot -proot -h 127.0.0.1 -D test < /tmp/schema.sql
mysql: [Warning] Using a password on the command line interface can be insecure.

$ MYSQL_CHARSET='utf8mb4'
$ MYSQL_DATABASE='test'
$ MYSQL_BACKUP_DIR='/tmp/dump'
$ MYSQL_HOSTNAME='127.0.0.1'
$ MYSQL_USERNAME='test'
$ MYSQL_PASSWORD='test'
$ MYSQL_CHARSET='utf8mb4'
$ mysqldump -u$MYSQL_USERNAME -p$MYSQL_PASSWORD -h$MYSQL_HOSTNAME --single-transaction --default-character-set $MYSQL_CHARSET --databases $MYSQL_DATABASE | gzip > $MYSQL_BACKUP_DIR/$MYSQL_DATABASE.sql.gz

これを s3 に backup することとする。

$ restic -r s3:s3.amazonaws.com/pulumi-bucket-f083d0a --verbose backup $MYSQL_BACKUP_DIR/
open repository
enter password for repository:
repository f8b91f18 opened successfully, password is correct
created new cache in /Users/keijun.kumagai/Library/Caches/restic
lock repository
load index files
no parent snapshot found, will read all files
start scan on [/tmp/dump/]
start backup on [/tmp/dump/]
scan finished in 0.396s: 2 files, 875 B

Files:           2 new,     0 changed,     0 unmodified
Dirs:            2 new,     0 changed,     0 unmodified
Data Blobs:      2 new
Tree Blobs:      3 new
Added to the repo: 2.360 KiB

processed 2 files, 875 B in 0:00
snapshot 71166f33 saved

なんか生成されているし、いい感じ。

$ aws s3 ls s3://pulumi-bucket-f083d0a
                           PRE data/
                           PRE index/
                           PRE keys/
                           PRE snapshots/
2021-08-21 19:27:23        155 config

あとは、ファイルを削除して backup から復元してみます。

$ rm -fr /tmp/dump

$ restic -r s3:s3.amazonaws.com/pulumi-bucket-f083d0a restore 71166f33 --target /
enter password for repository:
repository f8b91f18 opened successfully, password is correct
restoring <Snapshot 71166f33 of [/tmp/dump] at 2021-08-21 21:48:38.213122 +0900 JST by keijun.kumagai@O-14731-MAC> to /

$ ls /tmp/dump
test.sql        test.sql.gz

おお復元。ファイルパスの指定はもう少しどうにかしてほしい感はあるけど、いい感じ。 他にも snapshot ごとの差分比較、tag 付けなどいろいろなことが出来るみたい。

意外と面白かったです。それでは今回はこのへんで。