2010-09-22 追記: スクリプトともう少し詳しい記事書いたよ
btrfs は面白そうだけど、いきなり重要な所に使うのは怖い、 と言う事で家のバックアップハーティションを btrfs にしてみた。 透過圧縮もサポートしてるし、cow だからバックアップには向いてそう。
btrfs のサブボリュームというのは、単にメインボリュームの中のサブディレクトリとして見える。 そして、スナップショットはボリューム単位で作成可能で、 これもまた単にディレクトリに見える(と言うか、呼び方は違うが実質はサブボリューム)。
と言う事で、
単純にこれだけで pdumpfs や faubackup とか rsync --link-dest と同じ事が高速かつ手軽に出来るはず。
例えばこんなの。 重要なのは最後の3行なので、そこだけ見ればOK。
#!/bin/bash set -e backup_base=/backup target="${1%/}" shift if (echo "${target}" | egrep -q "^[0-9a-zA-Z.-]+:"); then host=${target%:*} dest="${target#*:}" else host=$(hostname) dest="${target}" fi dest="${dest////_}" dest="${backup_base}/${host}/${dest#_}" if [ -z "${target}" ]; then echo "Usage: $0 <target_dir> [rsync-options]" >&2 exit 255 fi if [ ! -d "${dest}" ]; then mkdir -p "${dest}" fi if [ ! -d "${dest}/cur" ]; then btrfsctl -S cur "${dest}" fi || true rsync -acSHXA --numeric-ids --del "$@" "${target}/" "${dest}/cur/" btrfsctl -c "${dest}/cur" >/dev/null || true btrfsctl -s "${dest}/$(date +%Y-%m-%dT%H:%M:%S)" "${dest}/cur" > /dev/null || true
今のところ、スナップショットをとる前に btrfsctl -c で sync する必要があるようだ。
まあとにかく、"/path/to/btr-backup /etc" のような感じで起動すると、 /backup/ホスト名/対象/cur にコピーしてから、タイムスタンプのスナップショットを作る。 こんな感じで。
sugi@tempest:/backup/tempest/etc% ls -il | tail -3 256 drwxr-xr-x 1 root root 10532 2010-04-09 06:16 2010-04-10T04:19:22/ 256 drwxr-xr-x 1 root root 10532 2010-04-10 14:33 2010-04-11T04:19:55/ 256 drwxr-xr-x 1 root root 10532 2010-04-10 14:33 cur/
i-node 番号が全部 256 になっているので、普通のディレクトリじゃないことが分かりますね。
落とし穴/問題は、
と言ったところか。今のところ巧く動いている。暫く使ってみよう。
rm -rf では消えないので注意。cow だから当たり前だけど、rm で中身を消すと、 ファイルは見えなくなって余計使用量が増える。
しかし困った事に、リリースされている btrfs-tools v0.19 では スナップショットやサブボリュームの削除が出来ない。
現状で削除する場合は、新しいカーネル(確認してない。 2.6.31 以上か?)で、 btrfs-progs-unstable を git レポジトリから取って来てビルドする必要がある。
その上で btrfsctl の作り直し版の様な、統合コマンドの "btrfs" を使って削除する。 例えば
btrfs subvolume delete /backup/tempest/etc/2010-04-07T04:19:21
とすれば消える。スナップショットとサブボリュームの区別は無いので、 スナップショットを消す場合も subvolume delete で OK. rsync 等で作った場合と違って、消す作業は一瞬なのがいいね。