|||||||||||||||||||||

なんぶ電子

- 更新: 

世代管理用のファイルシステムBRTFS

Debian

BTRFSはB-tree file systemの略で、このファイルシステムはドキュメントやコード等の世代管理やバックアップに最適な機能が備えられています。

今回はDebian13を使って、このBTRFSを使って、世代管理とリモートへバックアップをしたいと思います。

ディスクの増設

ここでは既にDebianOSは動いていると仮定して、最初に物理ディスクを増設します。

なるべく物理ディスクを分けた方がいいですが、無理ならパーテーションを区切ってスペースを設けます。

OSを含んだ全体をBTRFSにするのは得策ではないようです。

また、バックアップ用のディスクなので、SSDよりHDDにしておいた方がいいと思います。

取り付けたら、OSを起動させlsblkで認識しているかを確認します。

# lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda      8:0    0 465.8G  0 disk
|-sda1   8:1    0   976M  0 part /boot/efi
|-sda2   8:2    0 460.8G  0 part /
`-sda3   8:3    0     4G  0 part [SWAP]
sdb      8:16   0 931.5G  0 disk
sr0     11:0    1  1024M  0 rom

パーテーションの作成

fdiskでパーテーションを作ります。

GPTで作成する場合は、gコマンドを入力します。

# fdisk /dev/sdb
g
Created a new GPT disklabel (GUID:....)
n
...
w
...

パーテーションタイプはデフォルトのLinux filesystemにしておきます。

btrfs領域のイニシャル

btrfs-progsをインストールし、フォーマットをします。

# apt install btrfs-progs
# mkfs.btrfs /dev/sdb1
/dev/sdb1 appears to contain an existing filesystem (vfat)
ERROR: use the -f option to force overwrite of /dev/sdb1
# mkfs.btrfs -f /dev/sdb1
...
# btrfs filesystem label /dev/sdb1 backupdisk

ディスクを再利用していたりすると、既にファイルシステムが存在すると警告を出します。そのままだとフォーマットが進まないので、問題なければ-fオプションをつけて実行します。

また管理時に分かりやすくするために、ディスクにラベルを付けています。すでにマウントしている場合はマウントポイントを指定します。

fstabを編集して常時マウントさせるようにします。

/etc/fstab

LABEL=backupdisk /mnt/bkupdisk btrfs defaults,compress=zstd,noatime,space_cache=v2 0 0

fstabのオプションを説明しておきます。

  • defaults

    rw(読み書き),suid(SUID:/SGID:ビット有効),dev(デバイスファイル有効),exec(ファイル実行可能),auto(自動マウント),nouser(ユーザーマウント不可),async(非同期IO)

  • compress=zstd

    zstdで圧縮します

  • noatime

    ファイルアクセス毎のタイムスタンプの書き込みを抑制し、IOを減らします。

  • space_cache=v2

    空き領域をキャッシュしておく設定です。v1とv2があり、v2としておきます。

  • autodefrag

    オートデフラグ、細かなファイルの更新が多いなら設定します。Linuxのカーネルバージョン5.16.5未満の5.16.xの場合はデフラグの無限ループの不具合があるそうなので、このオプションを付けない方がいいです。

  • nofail

    状況により、今回はバックアップサーバーで必須ディスクなので、このオプションはつけません

サブボリューム

ファイルシステムをBTRFSにしたのは、スナップショットをディスク効率的に使って高速でとる為です。

スナップショットは、以降で設定する「サブボリューム」単位で管理することになります。

またzstdによる圧縮もメリットのひとつになります。

サブボリュームを作成するには btrfs subvolume create コマンドを使います。コマンドに続いてサブボリュームとするディレクトリを指定します。

サブボリューム作成時は既存のディレクトリは指定できません(既存ディレクトリを対象にしたい場合は退避して中身の移動をします)。また、BTRFS外の場所には作成できません。

コマンドを実行するとそこにディレクトリが生成され、サブボリュームとして管理されます。

サブボリュームとして作成したディレクトリを削除したい場合は、btrfs subvolume delete コマンドで削除します。

btrfs subvolume create /mnt/bkupdisk/test1
...
btrfs subvolume create /mnt/bkupdisk/test2
...
btrfs subvolume create /mnt/bkupdisk/test3
...
btrfs subvolume delete /mnt/bkupdisk/test2

作成したサブボリュームの確認をしたい場合は btrfs subvolume list を使います。

# btrfs subvolume list /mnt/bkupdisk
ID 256 gen 18 top level 5 path test1
ID 260 gen 20 top level 5 path test2
ID 261 gen 20 top level 5 path test3

サブボリュームはネストして持てます。たとえばtest1の下にtest15というサブボリュームを作れます。

ただし、test1のスナップショットを取った時に、test15はそこには含まれないので注意が必要です。スナップショットは完全にサブボリューム単位で管理されます。

スナップショットの作成と運用

基本的なスナップショットの取り方は次のようになっています。

btrfs subvolume snapshot -r [対象サブボリュームへのパス] [保存先パス]

ここでも保存先は未存在のパスを指定する必要があります。保存先にはコマンド実行時のサブボリュームの中身が入ります。

-rオプションはリードオンリーオプションです。バックアップ目的の場合は一般的にオプションを付けるのが普通です。

ここで作成したスナップショットは、先ほど実行したサブボリュームのリストに加わります。

削除はサブボリュームと同様に行えます。

また、btrfs subvolume list -s と -sオプションをつけるとスナップショットだけの一覧となります。

# btrfs subvolume snapshot -r /mnt/bkupdisk/test2 /mnt/bkupdisk/snapshot
...
# btrfs subvolume list
ID 256 gen 18 top level 5 path test1
ID 260 gen 21 top level 5 path test2
ID 261 gen 20 top level 5 path test3
ID 267 gen 21 top level 5 path snapshot

復元時は、-rオプションを付けない snapshotを使い保存先とサブボリュームへのパスを逆にします。

btrfs subvolume snapshot [保存先パス] [対象サブボリュームへのパス]

先ほど実行したsnapshotをとるコマンドそのものですので、存在しないディレクトリを指定して新たにスナップショットを作ることもできます。

ファイル単位で復元したい場合は、スナップショットにはファイル構造がそのまま存在しますので、通常のcpコマンドを使います。

世代管理

スナップショットの取り方と復元を覚えたら、あとは何日残すか等の世代管理を設定し、cronで自動化します。

たとえば7日毎に削除するスクリプトは次のような感じに書くことができ、このスクリプトをcronに登録します。

daily-snap.sh

#!/bin/bash
set -e

SRC=/mnt/bkupdisk/data
DST=/mnt/bkupdisk/.snapshot/
TODAY=$(date +%F)

btrfs subvolume snapshot -r "$SRC" "$DST/data_$TODAY"

cd "$DST"
ls -1 data_* | sort | head -n -7 | xargs -r btrfs subvolume delete

btrfs subvolume list 中の gen

btrfs subvolume list 中に出てくる genは世代を意味するものですが、このgenはファイルシステム全体共通のカウンタ値で、スナップショットの作成などの操作によってインクリメントされます。

たとえば、test2のスナップショットを作った時のgenが(作る時に1加算されれ)30だととすると、スナップショットにも30というgenが付きます。そのあとに、test1のスナップショットをつくると、test1のgenは31となり、そのスナップショットのgenも31となります。

サブボリュームの中にファイルを追加したりするとgenの値はその時点のものとなります。リードオンリーにしたスナップショットは当時のgenから変更されることはありません。

サブボリュームのマウント

サブボリュームを指定してのマウントが可能です。イメージとしては mountの --bind オプションでディレクトリを別の場所へマウントする時と同じです。元の場所とマウンティングポイントのどちらを経由しても同じ実体を編集することができます。

マウントの方法は、さきほどの list で出力される名前でする方法と、IDで指定する方法があります。

mount -o subvol=test1 /dev/sdb1 /mnt/submount
mount -o subvolid=256 /dev/sdb1 /mnt/submount

サブボリュームのquota

BTRFSでは、サブボリューム毎に容量の制限(quota)ができます。そのためにはまず設定を有効にさせなければいけません。

過去に不安定だった経緯もあり、quotaを利用しないなら無効にしておいた方がよいとの説明があります。

有効にするはマウントポイントを指定して、次のコマンドを実行します。

#btrfs quota enable /mnt/bkupdisk

制限を指定するには、btrfs qgroup limit を使います。limitのあとサイズを指定します。取り消す場合は noneを指定します。

# btrfs qgroup limit 10G /mnt/bkupdisk/test1

現在の状況を確認するにはbtrfs qgroup showを使います。

Rferencedで共通利用量、Exclusiveで排他的使用量を表します。

# btrfs qgroup show /mnt/bkupdisk
Qgroupid    Referenced    Exclusive   Path
--------    ----------    ---------   ----
0/5           16.00KiB     16.00KiB   <toplevel>
0/256         16.00KiB     16.00KiB   test1

send と receive

BorgBackupを使うので今回は使いませんが、別のマシンと同期するためのコマンドもあります。

btrfs sendコマンドでサブボリュームを作成するためのストリームが作成されます。

ストリームを後で説明するbtrfs receiveコマンドで処理する事でふたつのマシン間でサブボリュームを受け渡しできます。

この時に指定するサブボリュームはリードオンリーである必要があります。

# btrfs send /mnt/bkupdisk/test1 | btrfs receive /mnt/bkupdisk

-pオプションを付与すると、ふたつのサブボリュームの差分を抽出することができます。

# btrfs send -p /mnt/bkupdisk/test1 /mnt/bkupdisk/test2 | btrfs receive /mnt/bkupdisk

-fオプションを付与すると、ストリームのかわりにファイルを作成します。この時のファイルは別のファイルシステムへ出力する事ができます。

btrfs receiveコマンドは先の、btrfs send コマンドで出力したストリームを受け取るコマンドです。-fをつけることにより、同様に-fオプションで出力したファイルを受信することができます。

引き数に渡すのは、btrfsのマウントポイントとなるディレクトリとなります。

sendの-pオプションで差分を送信する時は、receive側も元の環境と同じ親ディレクトリがある前提となっています。

sendからパイプするreceive側のコマンドをsshコマンドに置き換えリモート側でシェルを許可すれば、一文でリモートへのバックアップも実現できます。

初回は-pオプションを抜いた全件を送り、以降は差分を送り続けることでふたつのマシンの間で同期をとることができます。

筆者紹介


自分の写真
がーふぁ、とか、ふぃんてっく、とか世の中すっかりハイテクになってしまいました。プログラムのコーディングに触れることもある筆者ですが、自分の作業は硯と筆で文字をかいているみたいな古臭いものだと思っています。 今やこんな風にブログを書くことすらAIにとって代わられそうなほど技術は進んでいます。 生活やビジネスでPCを活用しようとするとき、そんな第一線の技術と比べてしまうとやる気が失せてしまいがちですが、おいしいお惣菜をネットで注文できる時代でも、手作りの味はすたれていません。 提示されたもの(アプリ)に自分を合わせるのでなく、自分の活動にあったアプリを作る。それがPC活用の基本なんじゃなかと思います。 そんな意見に同調していただける方向けにLinuxのDebianOSをはじめとした基本無料のアプリの使い方を紹介できたらなと考えています。

広告