Category Archives: zfs

[zfs] zfsnap2を使った日々のzfs snapshot(削除編)

Pocket

zfsnap2(以降、zfsnap)をperiodicで自動取得する方法はこちらで触れた。
同期時でも触れた通り、zfsnapには自動削除するperiodic scriptもある。
が、実はそのままでは動かない。
変更内容を本記事で示す。

結論

付属のスクリプトではdestroyするfsの指定がないので補う。
具体的には以下の個所。

 
<         xPREFIXx/zfsnap destroy $OPTIONS -p "hourly- daily- weekly- monthly- reboot- $xPERIODICx_zfsnap_delete_prefixes" $xPERIODICx_zfsnap_delete_fs -r $xPERIODICx_zfsnap_delete_recursive_fs
---
>         xPREFIXx/zfsnap destroy $OPTIONS -p "hourly- daily- weekly- monthly- reboot- $xPERIODICx_zfsnap_delete_prefixes"

 

 

同時に、/etc/periodic.confで$xPERIODICx_zfsnap_delete_fs、$xPERIODICx_zfsnap_delete_recursive_fsの指定も行うこと。

結果

dailyの削除スクリプト例(dailyのみ)

 
#!/bin/sh

# This file is licensed under the BSD-3-Clause license.
# See the AUTHORS and LICENSE files for more information.

# If there is a global system configuration file, suck it in.
if [ -r /etc/defaults/periodic.conf ]; then
    . /etc/defaults/periodic.conf
    source_periodic_confs
fi

# daily_zfsnap_delete_enable   - Delete old snapshots periodicaly (values: YES | NO)
# daily_zfsnap_delete_flags    - `zfsnap destroy` flags
# daily_zfsnap_delete_verbose  - Verbose output (values: YES | NO)
# daily_zfsnap_delete_prefixes - Space-separated list of prefixes of expired zfsnap snapshots to delete
#                                     'hourly-', 'daily-', 'weekly-', 'monthly-', and 'reboot-' prefixes are hardcoded
# daily_zfsnap_delete_fs                - Space-separated ZFS filesystems to create non-recursive snapshots
# daily_zfsnap_delete_recursive_fs      - Space-separated ZFS filesystems to create recursive snapshots

case "${daily_zfsnap_delete_enable-"NO"}" in
    [Yy][Ee][Ss])
        OPTIONS="$daily_zfsnap_delete_flags"

        case "${daily_zfsnap_delete_verbose-"NO"}" in
            [Yy][Ee][Ss]) OPTIONS="$OPTIONS -v" ;;
        esac

        /usr/local/sbin/zfsnap destroy $OPTIONS -p "hourly- daily- weekly- monthly- reboot- $daily_zfsnap_delete_prefixes" $daily_zfsnap_delete_fs -r $daily_zfsnap_delete_recursive_fs
        exit $?
        ;;

    *)
        exit 0
        ;;
esac

# vim: set ts=4 sw=4:

/etc/periodic.confの例(dailyのみ)

# zfsnap_daily
daily_zfsnap_enable="YES"
daily_zfsnap_recursive_fs="vault"
daily_zfsnap_verbose="YES"
daily_zfsnap_flags="-s -S -z"
daily_zfsnap_ttl="1w1d"
daily_zfsnap_delete_enable="YES"
daily_zfsnap_delete_flags="-s -S"
daily_zfsnap_delete_verbose="YES"
daily_zfsnap_delete_recursive_fs="vault"

上手くいけばdaily outputで以下のような内容が通知される。

/sbin/zfs destroy vault/chamber@daily-2018-12-21_04.00.00--1w1d ... DONE
/sbin/zfs destroy vault/itunes@daily-2018-12-21_04.00.00--1w1d ... DONE
/sbin/zfs destroy vault@daily-2018-12-21_04.00.00--1w1d ... DONE

[zfs]ディスク交換、zpool容量の拡張

Pocket

HDDがいっぱいになってきたので容量の大きい別のHDDに移した。
zfsなのでmirrorをしつつ入れ替えができる。
その時のメモ。

端的に言えばディスク交換後zpool online -eをすればよい。
以下、経緯。

ディスク追加

2.5TのHDD, ada1上に作られたzpool、vaultがあり、残容量は150Gである。
もともとzfsは残容量が少なくなると格段にパフォーマンスが落ちると言われていて、これはちょっと危険な状態である。

ada1 at ahcich1 bus 0 scbus1 target 0 lun 0
ada1: <WDC WD25EZRX-00MMMB0 80.00A80> ATA8-ACS SATA 3.x device
ada1: Serial Number WD-WMAWZ0230443
ada1: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada1: Command Queueing enabled
ada1: 2384658MB (4883781168 512 byte sectors)
ada1: quirks=0x1<4K>

# zpool status
  pool: vault
 state: ONLINE
  scan: none requested
config:

        NAME           STATE     READ WRITE CKSUM
        vault          ONLINE       0     0     0
          gpt/disk_01  ONLINE       0     0     0

# zfs list
NAME            USED  AVAIL  REFER  MOUNTPOINT
vault          2.05T   150G    88K  /vault
vault/chamber  1017G   150G  1017G  /chamber
vault/itunes   1.06T   150G  1.05T  /itunes

そこで、zpoolにmirrorとして容量の大きいディスクを追加し、その後オリジナルのディスクを外す、という手順。

追加するのは以下のディスク。3T。
2.5Tから3Tじゃ焼け石に水ですがね…。

ada2 at ahcich2 bus 0 scbus2 target 0 lun 0
ada2: <WDC WD30EZRX-00D8PB0 80.00A80> ACS-2 ATA SATA 3.x device
ada2: Serial Number WD-WMC4N0765033
ada2: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada2: Command Queueing enabled
ada2: 2861588MB (5860533168 512 byte sectors)
ada2: quirks=0x1<4K>

既存のzpoolにmirrorとしてディスクを追加するには、zpool attachを使う。
zpool attachに続けてzpool名、既存ディスク、追加ディスクの順で指定。
以下の例では、ディスクの指定をada2などのデバイス名ではなくGPT名で行っている。


# zpool attach vault gpt/disk_01 gpt/disk_02

以下のようにzpoolがmirror構成になり、resilveringが始まる。

# zpool status
  pool: vault
status: One or more devices is currently being resilvered.  The pool will
        continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
 scrub: resilver in progress for 0h0m, 0.01% done, 7h1m to go
config:

        NAME             STATE     READ WRITE CKSUM
        vault            ONLINE       0     0     0
          mirror-0       ONLINE       0     0     0
            gpt/disk_01  ONLINE       0     0     0
            gpt/disk_02  ONLINE       0     0     0

しばらく待つと;

  pool: vault
 state: ONLINE
  scan: resilvered 2.04T in 6h48m with 0 errors on Sun Dec 16 19:15:11 2018
config:

        NAME             STATE     READ WRITE CKSUM
        vault            ONLINE       0     0     0
          mirror-0       ONLINE       0     0     0
            gpt/disk_01  ONLINE       0     0     0
            gpt/disk_02  ONLINE       0     0     0

resilvering終了。

 

旧ディスクの除去

2.5Tと3Tのディスクでmirrorを構成しているので、当然ながら残容量に変化はない。

NAME            USED  AVAIL  REFER  MOUNTPOINT
vault          2.05T   150G    88K  /vault
vault/chamber  1017G   150G  1017G  /chamber
vault/itunes   1.06T   150G  1.05T  /itunes

では旧ディスクを外す。
mirrorからディスクを外すにはdetachを使う。
zpool detachに続けてzpool名、ディスク名を指定。

# zpool detach vault gpt/disk_01
# zpool status
  pool: vault
 state: ONLINE
  scan: resilvered 2.04T in 6h48m with 0 errors on Sun Dec 16 19:15:11 2018
config:

        NAME          STATE     READ WRITE CKSUM
        vault         ONLINE       0     0     0
          gpt/disk_02 ONLINE       0     0     0

errors: No known data errors

ご覧の通りmirror構成が解除される。

容量の拡張

さてこの状態ではまだ残容量が増えない。

NAME            USED  AVAIL  REFER  MOUNTPOINT
vault          2.05T   150G    88K  /vault
vault/chamber  1017G   150G  1017G  /chamber
vault/itunes   1.06T   150G  1.05T  /itunes

ただ物理ディスクは3Tなので、zpoolに「安心して容量を増やしたまえ」と通知する。
通知にはzpool online -eを使う。
zpool onlineは物理ディスクを有効にするコマンドだが、-eを付ければ、使用可能な領域をすべて使うようにできる。
manを以下に引用する。

     zpool online [-e] pool device ...

         Brings the specified physical device online.

         This command is not applicable to spares or cache devices.

         -e      Expand the device to use all available space. If the device
                 is part of a mirror or raidz then all devices must be
                 expanded before the new space will become available to the
                 pool.

ご覧の通り残容量が増えた。
たったの450Gだけど。

# zpool online -e vault gpt/disk_02
$ zfs list
NAME            USED  AVAIL  REFER  MOUNTPOINT
vault          2.05T   599G    88K  /vault
vault/chamber  1017G   599G  1017G  /chamber
vault/itunes   1.06T   599G  1.05T  /itunes

[zfs] zfsnap2を使った日々のzfs snapshot(取得編)

Pocket

zfsnap2(面倒くさいので以降zfsnap)のおかげで気軽にzfs snapshotできるようになった。
あとはこれをcronに仕込んで日々、snapshotを取得、削除するだけである。

zfsnapをpkg、あるいはportsからインストールすると、cron用のシェルスクリプトも付いてくる。
これを加工してperiodic用のディレクトリに放り込めば、あとは全部、zfsnapがやってくれる。

基本はここを見ながら。
https://github.com/zfsnap/zfsnap/wiki/zfSnap-periodic.conf

なお、本稿で扱う周期、契機は日週月次に限る。

全体の流れ

  1. スナップショットの方針を決める
  2. cron用シェルスクリプトを日・週・月ごとのperiodicディレクトリにコピーし、ファイル名を変更する
  3. スクリプトの内容を修正する
  4. /etc/periodic.confにバックアップ方針に沿った設定を書き加える

では早速。

スナップショット方針を決める

ここでは簡単に、あるzpool丸ごとに対して;

  • 毎日のスナップショットは1週間と1日、保存する
  • 毎週のスナップショットは1か月と1日、保存する
  • 毎月のスナップショットは1年と1週間、保存する

とする

[補足]periodicから実行されるときのsnapname

zfsnap付属のスクリプトを使うと、snapnameの頭にdaily, weekly, monthlyと付く。
もちろん変更可能だが、本稿ではそのまま使う。

zfsnapのcron用スクリプトはどこにある

cron用スクリプトは、zfsnapインストール時にshareにコピーされる。
例えば以下のようにして探す

$ pkg list|grep zfsnap
/usr/local/etc/bash_completion.d/zfsnap.sh
/usr/local/man/man8/zfsnap.8.gz
/usr/local/sbin/zfsnap
/usr/local/share/doc/zfsnap/AUTHORS
/usr/local/share/doc/zfsnap/NEWS
/usr/local/share/doc/zfsnap/PORTABILITY
/usr/local/share/doc/zfsnap/README.md
/usr/local/share/examples/zfsnap/completion/zfsnap-completion.bash
/usr/local/share/examples/zfsnap/completion/zfsnap-completion.tcsh
/usr/local/share/examples/zfsnap/completion/zfsnap-completion.zsh
/usr/local/share/examples/zfsnap/periodic/xPERIODICx_zfsnap.sh
/usr/local/share/examples/zfsnap/periodic/xPERIODICx_zfsnap_delete.sh
/usr/local/share/licenses/zfsnap2-2.0.0.b3/BSD3CLAUSE
/usr/local/share/licenses/zfsnap2-2.0.0.b3/LICENSE
/usr/local/share/licenses/zfsnap2-2.0.0.b3/catalog.mk
/usr/local/share/zfsnap/commands/destroy.sh
/usr/local/share/zfsnap/commands/recurseback.sh
/usr/local/share/zfsnap/commands/snapshot.sh
/usr/local/share/zfsnap/core.sh
/usr/local/share/zsh/site-functions/_zfsnap

上記のうち以下が狙いのスクリプトである。
スナップショット取得用、削除用の2種類。
なお削除用はそのままでは期待する動作にならないので別記事で扱う。
/usr/local/share/examples/zfsnap/periodic/xPERIODICx_zfsnap.sh
/usr/local/share/examples/zfsnap/periodic/xPERIODICx_zfsnap_delete.sh

スクリプトのコピーとファイル名の変更

さてこれを、日・週・月のperiodicディレクトリにコピーし設定していくが、まずは日次で試す。
日ごとのperiodicディレクトリは/usr/local/etc/periodic/dailyである。
ここにコピーし、ファイル名を変える。
ファイル名のxPERIODICxを、日次・週次・月次、どの周期用かに合わせて変える。
具体的にはそれぞれdaily, weekly, monthlyに。
以下の例では日次のスクリプトなので、dailyに変えている。
prefixの番号は好きなようにしたまえ。


$ cd /usr/local/etc/periodic/daily
$ sudo cp /usr/local/share/examples/zfsnap/periodic/* .
$ sudo mv ./xPERIODICx_zfsnap.sh ./500.daily_zfsnap.sh
$ sudo mv ./xPERIODICx_zfsnap_delete.sh  ./500.daily_zfsnap_delete.sh
$ ls
411.pkg-backup                  500.daily_zfsnap_delete.sh      998.ntpdate
490.status-pkg-changes          500.daily_zfsnap.sh             smart

スクリプトの修正

スクリプト(取得用)の内容は以下の通りである。
変える場所はxPERIODICxとxPREFIXxである。
xPERIODICxは周期に合わせて、xPREFIXxはzfsnapの置いてあるパス、つまり/usr/local/sbin/zfsnapに。


#!/bin/sh

# This file is licensed under the BSD-3-Clause license.
# See the AUTHORS and LICENSE files for more information.

# If there is a global system configuration file, suck it in.
if [ -r /etc/defaults/periodic.conf ]; then
    . /etc/defaults/periodic.conf
    source_periodic_confs
fi

# xPERIODICx_zfsnap_enable          - Enable xPERIODICx snapshots (values: YES | NO)
# xPERIODICx_zfsnap_flags           - `zfsnap snapshot` flags
# xPERIODICx_zfsnap_fs              - Space-separated ZFS filesystems to create non-recursive snapshots
# xPERIODICx_zfsnap_recursive_fs    - Space-separated ZFS filesystems to create recursive snapshots
# xPERIODICx_zfsnap_ttl             - Explicit TTL value
# xPERIODICx_zfsnap_verbose         - Verbose output (values: YES | NO)
# xPERIODICx_zfsnap_enable_prefix   - Create snapshots with prefix (values: YES | NO) (Default = YES)
# xPERIODICx_zfsnap_prefix          - set prefix for snapshots (Default = xPERIODICx)

case "${xPERIODICx_zfsnap_enable-"NO"}" in
    [Yy][Ee][Ss])
        OPTIONS="$xPERIODICx_zfsnap_flags"

        case "${xPERIODICx_zfsnap_verbose-"NO"}" in
            [Yy][Ee][Ss]) OPTIONS="$OPTIONS -v" ;;
        esac

        case "${xPERIODICx_zfsnap_enable_prefix-"YES"}" in
            [Yy][Ee][Ss]) OPTIONS="$OPTIONS -p ${xPERIODICx_zfsnap_prefix:-"xPERIODICx-"}" ;;
        esac

        case 'xPERIODICx' in
            'hourly')
                default_ttl='3d'
                ;;
            'daily'|'reboot')
                default_ttl='1w'
                ;;
            'weekly')
                default_ttl='1m'
                ;;
            'monthly')
                default_ttl='6m'
                ;;
            *)
                printf '%s\n' "ERR: Unexpected error" >&2
                exit 1
                ;;
        esac

        xPREFIXx/zfsnap snapshot $OPTIONS -a ${xPERIODICx_zfsnap_ttl:-"$default_ttl"} $xPERIODICx_zfsnap_fs -r $xPERIODICx_zfsnap_recursive_fs
        exit $?
        ;;

    *)
        exit 0
        ;;
esac

# vim: set ts=4 sw=4:

vimなら:%s/xPERIODICx/daily/g などとコマンド叩いて一括置換する。
以下が修正後。


#!/bin/sh

# This file is licensed under the BSD-3-Clause license.
# See the AUTHORS and LICENSE files for more information.

# If there is a global system configuration file, suck it in.
if [ -r /etc/defaults/periodic.conf ]; then
    . /etc/defaults/periodic.conf
    source_periodic_confs
fi

# daily_zfsnap_enable          - Enable daily snapshots (values: YES | NO)
# daily_zfsnap_flags           - `zfsnap snapshot` flags
# daily_zfsnap_fs              - Space-separated ZFS filesystems to create non-recursive snapshots
# daily_zfsnap_recursive_fs    - Space-separated ZFS filesystems to create recursive snapshots
# daily_zfsnap_ttl             - Explicit TTL value
# daily_zfsnap_verbose         - Verbose output (values: YES | NO)
# daily_zfsnap_enable_prefix   - Create snapshots with prefix (values: YES | NO) (Default = YES)
# daily_zfsnap_prefix          - set prefix for snapshots (Default = daily)

case "${daily_zfsnap_enable-"NO"}" in
    [Yy][Ee][Ss])
        OPTIONS="$daily_zfsnap_flags"

        case "${daily_zfsnap_verbose-"NO"}" in
            [Yy][Ee][Ss]) OPTIONS="$OPTIONS -v" ;;
        esac

        case "${daily_zfsnap_enable_prefix-"YES"}" in
            [Yy][Ee][Ss]) OPTIONS="$OPTIONS -p ${daily_zfsnap_prefix:-"daily-"}" ;;
        esac

        case 'daily' in
            'hourly')
                default_ttl='3d'
                ;;
            'daily'|'reboot')
                default_ttl='1w'
                ;;
            'weekly')
                default_ttl='1m'
                ;;
            'monthly')
                default_ttl='6m'
                ;;
            *)
                printf '%s\n' "ERR: Unexpected error" >&2
                exit 1
                ;;
        esac

        /usr/local/sbin/zfsnap snapshot $OPTIONS -a ${daily_zfsnap_ttl:-"$default_ttl"} $daily_zfsnap_fs
 -r $daily_zfsnap_recursive_fs
        exit $?
        ;;

    *)
        exit 0
        ;;
esac

# vim: set ts=4 sw=4:

削除用も同じようにしたら、periodic.confに指示を書き入れる。

/etc/periodic.confにおけるzfsnap設定の書式

/etc/periodic.confは無ければ作る。

zfsnapのperiodic向け書式は以下の通り。
https://github.com/zfsnap/zfsnap/wiki/zfSnap-periodic.conf

以下、日次のものとして記す。
週、月次の場合はdailyをそれぞれweekly, monthlyに変えればよい。

snapshot取得の有効化

daily_zfsnap_enable
YES/NOで指定

共通オプション(generic option)

daily_zfsnap_flags
例えばscrub, resilver中は避け、日付シリアルの秒を切り捨て、というような設定をここで行う。。
-v, -dを指定しないこと。
初めて作るときにはテスト実行オプションを付けて試験する。

zfs, zpoolの指定

daily_zfsnap_fs
daily_zfsnap_recursive_fs
recursiveとなっているのは、当然ながら子孫も含めて再帰的に取得される
複数あるなら、スペースを空けて列挙

冗長アウトプット指定

daily_zfsnap_verbose
YES/NOで指定

保存期間指定

daily_zfsnap_ttl
指定がなければ日次は1週間、週次は1か月、月次は6か月になる。

スナップショット削除有効化

daily_zfsnap_delete_enable
YES/NOで指定

periodic.conf例

ということで、periodic.confに追加したのは以下の通り。


# zfsnap_daily
daily_zfsnap_enable="YES"
daily_zfsnap_recursive_fs="vault"
daily_zfsnap_verbose="YES"
daily_zfsnap_delete_enable="YES"
daily_zfsnap_flags="-n -s -S -z"
daily_zfsnap_ttl="1w1d"

試験

zfsnap_flagsに-nを付けた状態で試験。


$ sudo /usr/local/etc/periodic/daily/500.daily_zfsnap.sh
/sbin/zfs snapshot  vault/chamber@daily-2018-12-03_02.14.00--1w1d
/sbin/zfs snapshot  vault/itunes@daily-2018-12-03_02.14.00--1w1d

大丈夫そうなので-nを外す。

最終的なperiodic.confの結果

週次、月次で同じようにperiodic用のスクリプトを作成する。


$ pwd
/usr/local/etc/periodic
$ find ./ -name '*zfsnap*'
./weekly/999.weekly_zfsnap.sh
./weekly/999.weekly_zfsnap_delete.sh
./daily/500.daily_zfsnap.sh
./daily/500.daily_zfsnap_delete.sh
./monthly/910.monthly_zfsnap.sh
./monthly/910.monthly_zfsnap_delete.sh

最終的なperiodic.confの結果は以下の通り。


# zfsnap_weekly
weekly_zfsnap_enable="YES"
weekly_zfsnap_recursive_fs="vault"
weekly_zfsnap_verbose="YES"
weekly_zfsnap_delete_enable="YES"
weekly_zfsnap_flags="-s -S -z"
weekly_zfsnap_ttl="1m1d"
# zfsnap_daily
daily_zfsnap_enable="YES"
daily_zfsnap_recursive_fs="vault"
daily_zfsnap_verbose="YES"
daily_zfsnap_delete_enable="YES"
daily_zfsnap_flags="-s -S -z"
daily_zfsnap_ttl="1w1d"
# zfsnap_monthly
monthly_zfsnap_enable="YES"
monthly_zfsnap_recursive_fs="vault"
monthly_zfsnap_verbose="YES"
monthly_zfsnap_delete_enable="YES"
monthly_zfsnap_flags="-s -S -z"
monthly_zfsnap_ttl="1y1d"

翌日以降、root宛には以下のようなメールが届くので、結果はここで確認する。

/sbin/zfs snapshot -r vault@daily-2018-12-02_04.47.0<wbr />0--1w1d ... DONE

[zfs][zpool] らくらくスナップショットzfsnap2

Pocket

zfsは本当に本当に便利で助かるのだが、それでも面倒なことはある。
私にとって面倒なのは、スナップショット作成とスナップショットの差分転送である。

スナップショットの簡素化について。
スナップショットを作成する際には、ファイルシステムやボリュームに続けてスナップショットの名前、スナップネームを指定する必要がある。
スナップネームはスナップショットを特定するために必要なものなので文句を言う筋合いはないのだが、いちいち名前を付けるのが面倒なんである。日付でもなんでも自動的に付けてほしい。

なんとか改善したくていろいろ調べてみた。

スナップショット取得補助ツール

スナップショット関連ではzfstools, zfsnap2, zapの三つを調べた。
結論から言うと、zfsnap2を選択した。

zfstools

https://github.com/bdrewery/zfstools
https://www.freshports.org/sysutils/zfstools/
よさそうだけどruby依存なのでその一点で対象外に。
このツールのためだけにrubyを入れますか、という話で。
なるべく依存の少ないツールがよい。

zap

https://www.freshports.org/sysutils/zap
https://github.com/Jehops/zap
よさそうだけど、zfsに独自のプロパティ(zap:)を設定する必要があるっぽい。
独自プロパティの設定が、zfsとして許容されている作法であっても、対象のファイルシステムに何らかの手を加えるのは躊躇する

zfsnap2

https://www.freshports.org/sysutils/zfsnap2
https://github.com/zfsnap/zfsnap
単純なシェルスクリプト。
よさそう。

zfsnap2 お手軽snapshot

まず、zfsnap2は、取得すると日付シリアルをsnapnameに付けてくれる。
例えば。

 
vault/chamber@2018-11-11_09.48.00--1y
 

ご覧の通り2018/11/11 09:48:00と日付をsnapnameに付ける
なお、末尾に1yと書いてあるがこれは1年という意味である。
これは何かというと(次項につづく)

zfsnap2 snapshot削除の仕組みとTTL

snapshotは取得するだけでなく、消す方の面倒を見ることも重要。
zfsnap2は、取得したタイムスタンプとTTL(Time To Live)をsnapnameに含めておくのがアイデア(他みも同じようなツールあるかもしれないけど)。
先ほどの例でいえば、末尾の1yがそれ。1yだから1 year、1年ですな。

vault/chamber@2018-11-11_09.48.00--1y

上記の通り、取得日付、保存期間をsnapname自体に持たせるので、ツール側では状態を記憶しておく必要がない。
削除を指示されたら、zfsnap2はその都度、snapnameだけを見て判断・処理をするということ。
何より人間もsnapnameから保存期限を判断できる。これはよい。

とりあえず使う

管理者権限でzfsnap snapshotに続けてzfs/zpoolを指定するだけ。
日付も付けてくれる。

# zfsnap snapshot zroot/var/tmp
$ zfs list -t snapshot|grep 'zroot/var/tmp'
zroot/var/tmp@20181120                   56K      -    88K  -
zroot/var/tmp@2018-12-01_22.19.13--1m      0      -    88K  -

zfsnap書式概要

詳細はman等するとして、概要を示す。
書式は以下の通り。

zfsnap コマンド <共通オプション> <個別オプション> zpool/zfs

zfsnapのコマンド

コマンドにはsnapshot, destroy, recursebackの三つがある。
それらに続けてzpool, zfsを指定する。こちらの指定は複数でもよい。
共通オプション(generic option)は、その名の通り、共通的なオプション。
個別オプションはzpool, zfsごとのオプションである。

コマンドのsnapshot, destroyは当然ながらそれぞれsnapshot作成、削除。
recursebackは、zfs rollbackの拡張で、rollbackの際、指定のdataset配下すべてをrollbackするもの。
本稿では扱わない。

共通オプション(generic option)

主なものだけ示す

-s  : resilver中は作業しない
-S : scrub中は作業しない
-z : 日付シリアルの秒切り捨て(18:06:15を18:06:00にする)
-n : dry run。テスト実行。ファイルシステムに変更を加えない。
-v : 冗長output

-s, -Sは常時付けておいたほうがいいかな。

個別オプション

個別オプションなので、これに続けて指定されたzpool/zfsにのみ効果がある。
主なものだけ示す

-a : TTL。指定がなければ1m = 1か月
-r : 再帰オプション。再帰的にsnapshotを取得
-R : 非再帰オプション。再帰的なsnapshotを取得「しない」

TTLオプション

以下のうち、必要なものだけをズラズラ書けばよい

y : 年(365日)
m : 月(30日)
w : 週(7日)
d : 日
h : 時
M : 分
s : 秒

1週間と1日なら-a 1w1d。
2か月なら-a 2m。

実行例

以上を踏まえて;
resilver, scrub中は実行せず、日付シリアルの秒切り捨て、冗長アウトプットでsnapshotをテスト実行。
対象zfsその1はzroot/usrで、再帰的に取得し、TTLは1週間と1日。その2はzroot/ROOTで、再帰的に取得「せず」、TTLは1分。
という実行例。

# zfsnap snapshot -sSvzn -a1w1d -r zroot/usr -R -a1M zroot/ROOT
/sbin/zfs snapshot -r zroot/usr@2018-12-01_22.33.00--1w1d
/sbin/zfs snapshot  zroot/ROOT@2018-12-01_22.33.00--1M

よさそうなのでテスト実行オプションを省いて本番実行すると;

# zfsnap snapshot -sSvz -a1w1d -r zroot/usr -R -a1M zroot/ROOT
/sbin/zfs snapshot -r zroot/usr@2018-12-01_22.34.00--1w1d ... DONE
/sbin/zfs snapshot  zroot/ROOT@2018-12-01_22.34.00--1M ... DONE

zfs listで結果を確認。zroot/usrにのみ配下にもスナップショットが出来ている。

$ zfs list -t snapshot | grep '2018-12-01'
zroot/ROOT@2018-12-01_22.34.00--1M             0      -    88K  -
zroot/usr@2018-12-01_22.34.00--1w1d            0      -    88K  -
zroot/usr/home@2018-12-01_22.34.00--1w1d       0      -  5.97M  -
zroot/usr/ports@2018-12-01_22.34.00--1w1d      0      -    88K  -
zroot/usr/src@2018-12-01_22.34.00--1w1d        0      -    88K  -

では削除のほうも。
zroot/ROOT、zroot/usr配下のTTL切れsnapshotを削除
ただしzroot/ROOTは非再帰的、zroot/usrは再帰的に。
テスト実行。

# zfsnap destroy -sSvn -R zroot/ROOT -r zroot/usr
/sbin/zfs destroy zroot/ROOT@2018-12-01_22.34.00--1M

期限切れはzroot/ROOT@2018-12-01_22.34.00–1Mのみ。
じゃ、それで本番実行

# zfsnap destroy -sSv -R zroot/ROOT -r zroot/usr
/sbin/zfs destroy zroot/ROOT@2018-12-01_22.34.00--1M ... DONE

以上。

[ZFS][zpool]zpoolのHDDをスタンバイモードにして消費電力を減らそう

Pocket

我が家のNASサーバーはFreeBSDの入ったHP microserverである。
HP microserverにはHDDを4つ入れることができる。
たいへん便利なのだが、HDDが4つとも24時間動きっぱなしというのは精神衛生上、よろしくない。

実は、HDD4つのうちメインで使っているのはOSの入っているものと、Samba共有しているものの2つだけで、残りの2つはバックアップ用である。
少なくとも、残りの2本はバックアップを取得するときだけ動いてくれればよいので、それ以外の間は、HDD内円盤の回転を止めておきたい(スピンダウン)。

しかしSamba共有しているもの、バックアップ用のHDD(要するにOSの入っているHDD)以外はすべてzfsのzpoolを構成しているものである。
気軽にスピンダウンしてしまってよいものだろうか。

というのが調査を始めたきっかけである。

ああ、それと、頻繁に止めたり動かしたりすることがHDDに悪い、というのは重々承知の上。

結論(camcontrol standbyしろ)

結論から言うと、camcontrolでディスクを止めろ。
ディスク停止には、”standby”で。”idle”はやめておけ。

ATAデバイスのモード

ATAデバイスには4つのPower Modeがあり、条件によりそれぞれを行き来する。

  1. Active
  2. Idle
  3. Standby
  4. Sleep

Activeモードは、通常のデータのやり取りができる状態のこと。
それ以外は、Idle > Standby > Sleep の順に消費電力が下がり、反応速度も遅くなる。
詳細は以下書類(PDF注意)の4.18.3 Power modesを参照されたし。
http://www.t13.org/Documents/UploadedDocuments/docs2007/e07163r2-Comments_on_ATA8-ACS_revision_4a.pdf

これを踏まえて、任意のタイミング、あるいは、一定時間アクセスがないタイミングでIdle/Standby/Sleepに遷移させられれば目的が達成できる。
FreeBSDにおいて、Power modeの遷移にはcamcontrolコマンドを使う。
しかしその前に、zfs/zpoolで使えるPower Modeを調べねばならない。

zfsにはStandby

FreeBSD Forumにあるcamcontrol standby weirdnessというスレッドを見ると、以下のような記述がある。要するにStandbyを使えと。Idleだとzfsは当該ディスクをlost/defect/detachedと判断し、zpoolはdegradedになるか、unavailableになるという。

First of all: ZFS is fine with disks that go into STANDBY (accessing a zpool with disks in STANDBY will wake them up and ZFS will wait for it). ZFS cannot handle disks that are in IDLE mode (it considers the disks lost/defect/detached and the zpool will go degraded or even unavailable).

https://forums.freebsd.org/threads/camcontrol-standby-weirdness.59296/#post-340121

自分で試す気にはならないので、そのまま受け取る。

camcontrolによるstabdby操作

再びFreeBSD Forum。[AHCI] Spinning down ada(4) disksというスレッドの以下のポストを参照
https://forums.freebsd.org/threads/ahci-spinning-down-ada-4-disks.8841/page-2#post-98640

camcontrol standby adaXとすればよい。
またcamcontrol standby adaX -T sssとすれば、ただちにstandbyモードに移行し、その後もsss秒、アクセスがなければstandbyモードに移行することができる。
以下なら/dev/ada3をすぐにstandbyモードに移行させるとともに、20分の間アクセスがなければやはりstandbyモードに遷移するようタイマー設定している。今すぐはstandbyモードにしなくてもいいけど、タイマーだけ設定したい、という方法はないみたいだ。

# camcontrol standby ada3 -T 12000

しかし上記のコマンドを実行したとしても、応答はない。なしのつぶてである。
standbyモードに移ったのか。かくなる上はHDDの回転数はいかほどか、耳を澄ますほかはない。
そんなご無体な、とgoogle先生に訴えたところ、FreeNASのフォーラムに以下のポストを発見。

Spinning Down your Drives and Checking Power States. (New Script)

上記にあるスクリプトを使えば、power modeを知ることができる。
本記事の末尾に転載しておく。
get_drive_status.shとして保存しておいた。
実行してみると;

$ sudo drivestatus.sh
ada0:  FF
ada0: Running
ada1:  FF
ada1: Running
ada2:  FF
ada2: Running
ada3:  FF
ada3: Running

camcontrolでstandbyにしておいて再実行。

$ sudo drivestatus.sh
ada0:  FF
ada0: Running
ada1:  00
ada1: Standby
ada2:  00
ada2: Standby
ada3:  00
ada3: Standby

/dev/ada0はOSのあるHDDだからActiveですな。

運用方法(なにかが変)

よしこれで解決。
と思ったのだが、タイマー満了してもpower modeがstandbyに移らないのである。
その割に、そのディスクのディレクトリにアクセスすると、ファイル一覧の表示に待たされたりするのである。

先に引用した彼も同じことに悩んでいる。

But, then, when the disk is idle for > 1800sec (monitor with “zpool iostat 60”), it will not spin down. Huh?

https://forums.freebsd.org/threads/camcontrol-standby-weirdness.59296/#post-339820

この彼は、zpool iostat でディスクへの読み書きをモニターできるので、何分かアクセスがなければidleモードに移すスクリプトを書いた、と言っている。
常駐スクリプトを運用するのが面倒なので、cronジョブでstandbyさせるようにした。

結果

ワットチェッカーなんてものは持っていないので、単純に温度で確認した。
以下がそのグラフ。
ある日を境に、(OSのある/dev/ada0を除いて)温度が劇的に下がっていて、現時点ではまあ満足。

power mode確認スクリプト

#!/bin/bash
#
# Created by: Motorahead
# Date: 02/19/2016
# Checks For Running Status of Connected ADA Devices

# Look for Connected Devices
DEVICELIST=($( camcontrol devlist | grep -o 'ada[0-9]' ))

# Checks Drive Status, but only outputs relative field $10
STATUS(){
camcontrol cmd ${LIST} -a "E5 00 00 00 00 00 00 00 00 00 00 00" -r - | awk '{print $10}'
}

# Loop through each device found in ${DEVICELIST}
for LIST in ${DEVICELIST[@]}; do
        echo -n "${LIST}:  "
        STATUS
# If the Output is 00, then the drive is in Standby. If it's FF, then it's active.
        if [[ "$(STATUS)" == "FF" ]]; then
                echo "${LIST}: Running"
        elif [[ "$(STATUS)" -eq "00" ]]; then
                echo "${LIST}: Standby"
        else
                echo "${LIST} is in a unrecognized state."
    fi
done

[zfs][zpool] zfsの別ディスクへの移行

Pocket

zpoolを容量の多い別HDDに移したのでメモ。
一度、同じようなことはやっているが、時間も経っているので。
最初に書いておくが移行元でまずscrubしておくこと。

流れとしては以下の通り。

  1. 移行元HDD
    1. scrubしておく
    2. snapshot
  2. 移行先HDD
    1. GPTでzfsのパーティションを作成
    2. zpool作成
  3. zfs send, recvで丸々コピー

以下、実作業に触れる前に補足。

方針についての補足

なぜmirrorにしないのか

上記の方法のほかには、追加のディスクをmirrorとしてzpoolに追加し、resilveringが終わったら旧ディスクを外してexpandという手がある。
が、その手は採らない。
実は、zpool statusをする都度、以下のメッセージが表示されていた。
旧ディスクは512Bセクタになっていると文句を言っているのである。
ディスクを交換するか、新Poolに移せ、と。

  pool: vault
 state: ONLINE
status: One or more devices are configured to use a non-native block size.
        Expect reduced performance.
action: Replace affected devices with devices that support the
        configured block size, or migrate data to a properly configured
        pool.
  scan: scrub repaired 0 in 8h3m with 0 errors on Sun Nov  4 04:16:39 2018
config:

        NAME        STATE     READ WRITE CKSUM
        vault       ONLINE       0     0     0
          ada1      ONLINE       0     0     0  block size: 512B configured, 4096B native

 

512Bセクタのpoolにmirrorを追加したら、やっぱり512Bになるんではと心配になったので、mirrorではなく新規ディスクの新規Poolに移す。

なぜディスクをまるっと使わずgptでパーティションを切るのか

zpoolは、わざわざgptパーティションにしなくても、ディスクをまるっと使ってzpoolに指定できる。
できるのだが、/dev/ada2なんて名前よりも、gptラベルでpoolを作成したいのである。
これの有利な点は、例えば当該ディスクの物理的な位置で名前を付けることができる点である。
具体的には、slot_1とか名前を付けておくと、ディスク交換の時に楽。
幸いにもFreeBSDにおいては、gptパーティションを切ってもディスクをそのまま使っても、いずれもパフォーマンスに違いはない。
それならgptにしましょう。

https://www.freebsd.org/doc/handbook/zfs-zpool.html
There is no performance penalty on FreeBSD when using a partition rather than a whole disk.
(2018/11/09)

ではさっそく作業を。

実作業(移行元ディスクの準備)

scrubをしておく。

zpool scrub で。
かなり時間がかかるので覚悟しておくように。
なおscrubは最低3か月に一回が推奨
https://www.freebsd.org/doc/handbook/zfs-term.html#zfs-term-scrub
recommended at least once every three months

作業直前にsnapshot。

pool内に複数のディレクトリがある場合、最上階層でsnapshot -r(recursive)すればよい。
たとえばvaultというpoolにchamber, itunesがある場合に;

vault
vault/chamber
vault/chamber@20170503
vault/itunes
vault/itunes@20170503

※zfs list -t allの出力を一部削除したもの

zfs snapshot vault@20181109とすれば;

vault
vault@20181109
vault/chamber
vault/chamber@20180503
vault/chamber@20181109
vault/itunes
vault/itunes@20180503
vault/itunes@20181109

※zfs list -t allの出力を一部削除したもの

となる。いちいち各ディレクトリ配下でコマンドを叩かなくてよい。

 

移行先作業

GPTパーティションの作成

以下のようなディスク

ada3 at ahcich3 bus 0 scbus3 target 0 lun 0
ada3: ACS-3 ATA SATA 3.x device
ada3: Serial Number WD-WCC7K3PU64NE
ada3: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada3: Command Queueing enabled
ada3: 3815447MB (7814037168 512 byte sectors)

GPTスキームをcreateし、全領域をfreebsd-zfsに割り当てる。
このとき、-lオプションでラベルを付ける。
同じくgpart showに-lオプションを付ければ名前を確認できる。

# gpart create -s GPT ada3
ada3 created
# gpart add -l slot_4 -t freebsd-zfs /dev/ada3
ada3p1 added
$ gpart show ada3
          40  7814037088  ada3  GPT  (3.6T)
          40  7814037088     1  freebsd-zfs  (3.6T)

$ gpart show -l /dev/ada3
          40  7814037088  ada3  GPT  (3.6T)
          40  7814037088     1  slot_4  (3.6T)

zpoolの作成

/dev/ada3ではなくGPTラベルで指定する。
GPTラベルで指定するときは、gpt/<GPTラベル>というように指定する。

# zpool create warehouse gpt/slot_4
# zpool status warehouse
  pool: warehouse
 state: ONLINE
  scan: none requested
config:
        NAME               STATE     READ WRITE CKSUM
        warehouse          ONLINE       0     0     0
          gpt/slot_4  ONLINE       0     0     0

プロパティの変更

zfsを作成する前に。
圧縮モードをlz4にする。lz4はCPU負荷の割には非常に効率が良いので積極的に有効にしたい。
また、atime(アクセスタイムの記録)もoffに。これがonだと差分snapshotが失敗するから、というのが一つと、これをoffにするとパフォーマンスが上がる(can result in significant performance gains)から。
zfs get <プロパティ名> で現在の値を取得。
zfs set <プロパティ名>=<値> で値のセット。
圧縮モードのプロパティ名はcompression、atimeはatime。

$ zfs get compression warehouse
NAME       PROPERTY     VALUE     SOURCE
warehouse  compression  off       default
$ zfs get atime warehouse
NAME       PROPERTY   VALUE     SOURCE
warehouse  atime      on        default

# zfs set compression=lz4 warehouse
# zfs set atime=off warehouse
$ zfs get compression warehouse
NAME       PROPERTY     VALUE     SOURCE
warehouse  compression  lz4       local
$ zfs get atime warehouse
NAME       PROPERTY   VALUE     SOURCE
warehouse  atime      off       local

ディレクトリの用意とsend/recv

# zfs create warehouse/itunes
# zfs create warehouse/chamber

このとき、勝手にマウントされないようにすべきだった。-uを付ければよかったかな。
いずれにせよzfs set mountpointで後から変えられる。

sendに-Rを付けると、子孫やスナップショットもまとめてsendされる。

# zfs send -R vault/chamber@20181109 | zfs receive warehouse/chamber
# zfs send -R vault/itunes@20181109 | zfs receive warehouse/itunes

かかった時間、容量は以下の通り。うーむ。ちょっとかかったかな。

 991GiB 3:09:00 [89.5MiB/s]
1.10TiB 3:58:24 [80.3MiB/s] 

このとき適当にhtopを叩いた結果。CPU負荷はそんなんでもないので、ボトルネックは別のところにあるように思われる。

  1  [|||||||||||||||||||||                47.6%]   Tasks: 43, 0 thr; 2 running
  2  [|||||||||||||||||                    37.7%]   Load average: 0.91 1.77 1.86 
  Mem[||||||||||||||||||||||||||||||||642M/1.84G]   Uptime: 12:03:30
  Swp[|||||||||                        176M/907M]

なおCPUはAMDのTurionである。

compression=lz4の結果は.
プロパティused(HDD上の容量)とlogicalused(圧縮前容量)で調べられる。

warehouse  used                  2.00T                    -
warehouse  logicalused           2.02T                    -

本来なら2.02Tのところ、2.00Tで済んでる。

これで引っ越し完了。

以上

zfs snapshotの差分send/recvについて

Pocket

 

zfs snapshotの差分send/recvについて

zfsのバックアップは、snapshotを撮っておいて、自ホストの別zpool、あるいは他ホストの別zpoolに移すことで行われる。
バックアップは定期的に行われるものであるが、ではそのsnapshotを移す際、毎回毎回まるまる送っていたんでは帯域も時間もディスク寿命も無駄である。
zfsはそこも考慮していて、差分だけを送ればいいようにincrementalオプションがきちんと用意されている。

書式は以下の通りsendに-iオプションを与えるだけ。
(recv側にはsnapshotAがすでに転送済みの前提)

zfs send -i <snapshotA> <snapshotB> | zfs recv <target pool>

 

よろしい。では次回からは…?

ふむ。
では二回目以降はどうするのだろう?
上記の書式例でsnapshotCが出来たらどうするのだろう?
まさかsnapshotA, B, Cを全部並べるのか?と思ったけどそれは間違いで、snapshotB, Cだけでよい。

recv側にはsnapshotAがすでにあるとき。
zfs send -i snapshotA snapshotBでAとBの差分のみが送られる。
つぎにzfs send -i snapshotB snapshotCでBとCの差分のみが送られる、というわけ。

では早速試してみる。が。

「転送先が更新されているため差分を転送できません」

こんなエラーがでる。

cannot receive incremental stream: destination warehouse/dir has been modified
since most recent snapshot

まあ文字通りなんですが。
バックアップ用の転送先が更新されるのはなぜか分からないが(atimeだろうか?)。

こういう場合には、recv側で-Fオプションを与えればよい。
-Fオプションによりrecv側は最新snapshotに強制rollbackして、それからsnapshotを受け取る。

下記の例だと、recv側は@20131226にいったんrollbackしてから受け取る。

$ sudo sh -c "zfs send -i vault/chamber@20131226 vault/chamber@2014010
2 | zfs recv -F warehouse/chamber"

 

atimeのoff

recv側がなぜ更新されてるのか、atimeが怪しいのでoffにしておく。
recv側のzpoolに対してzfs set atime=offするだけ。
(zpoolから切り出されたzfsすべてに適用される)

$ zfs get atime warehouse
NAME       PROPERTY  VALUE  SOURCE
warehouse  atime     on     default
$ sudo zfs set atime=off warehouse
$ zfs get atime warehouse
NAME       PROPERTY  VALUE  SOURCE
warehouse  atime     off    local
$ zfs get atime warehouse/chamber
NAME               PROPERTY  VALUE  SOURCE
warehouse/chamber  atime     off    inherited from warehouse

 

[メモ]zpoolのVersionについて(Versionナンバはもう使われない)

Pocket

 

過日、zpool v28のアップグレードをして、いくつかのfeature flagsを有効にした。
したのだが、よく分からないことがいくつかあった。

すなわち、最新のはずのv28なのにアップグレードを促されたこと、アップグレードしたら zpool get allの結果からバージョンが消えてしまったこと、である。

WikipediaのZFSやOpenZFSを眺めてみて分かったのは、zpool((Open)ZFS)はv28以降、バージョンナンバの使用を止めてしまったせいとの由。
http://en.wikipedia.org/wiki/OpenZFS
http://en.wikipedia.org/wiki/ZFS#RELEASEHISTORY

以下に調べた結果を示す。
なお、ご覧の通り情報の出所はwikipediaである。
問題ないとは思うが、各位においてはご留意されたい。

ZFSの歴史

もともと、zpoolやZFS filesytemに機能が追加されるたび、バージョンナンバがインクリメントされてきた。
しかし2010年、OpenSoralisの開発が停止され、ZFSはオープンソースではなくなった。
本家(Oracle)のZFSはプロプライエタリとなって、2013/12/24現在、ZFS filesystemはv6, ZFS Poolはv34まで進んでいる。

それはそれとして、illumos(OpenSolaris後継)やBSD/Linux/OSX関連の方々は、オープンであったzfs v5, zpool v28をベースに本家とは別の開発が進める。
これが2013年にOpenZFSとなる。

バージョンナンバとフィーチャーフラグ

OpenZFSはいろんな所でいろんな人々が開発を続けている。
こういった状態で、単一のバージョンナンバを付与することは不可能である。
そこでフィーチャーフラグ(feature flags)という考え方を導入する。
機能ごとに個別の名前を与える、というもの。

個別の名前は、feature@<org-name>:<feature-name>という書式で表される。
org-nameは当該機能を開発した組織名。一意の名前。もちろん、勝手につけることは許されない。
org-nameが明らかな場合には、feature@<feature-name>と短縮してもよい。
feature@async_destroyというように。

フィーチャーの状態

フィーチャーの状態には三つある。
disabled, enabled, activeである。

  • disabled: 無効。機能を使えない状態。
  • enabled: 機能を使える状態。有効にはなっていない。
  • active: 機能が有効。旧バージョンとの互換性がなくなっている。

フィーチャーの種類

  • features for write : 書き込みには必須の機能。読み込みのみであれば不要。
  • features for read : 読み込み、あるいはpoolを開くために必須の機能。

たとえばasync_destroyはデータ書き込みの時だけ必要な機能なのでfeatures for write。

バージョンについて

一つでもフィーチャーを有効にするとpoolのバージョンは1000になる。
1000とはめちゃくちゃな数に見えるかもしれないが、本家のバージョンと被らないようにするため。

おわりに

ここで改めてzpoolの出力を見てみると、poolのバージョンがハイフンになっていることや、フィーチャーの記載など、なるほどと理解できることがありますな。

$ zpool get all|grep vault
vault size 2.27T -
vault capacity 64% -
vault health ONLINE -
vault version - default
(略)
vault feature@async_destroy enabled local
vault feature@empty_bpobj enabled local
vault feature@lz4_compress enabled local

 

[メモ]zpoolのupgrade

Pocket

 

zpoolのupgradeをしたのでメモ。
結論としては、zpoolのupgradeとは、単にversionを上げるだけ以外にもあるようだ。

legacy on-disk formatでformat??

気がつくと、zpool statusで文句を言われていた。

$ zpool status
  pool: vault
 state: ONLINE
status: The pool is formatted using a legacy on-disk format.  The pool can
        still be used, but some features are unavailable.
action: Upgrade the pool using 'zpool upgrade'.  Once this is done, the
        pool will no longer be accessible on software that does not support feature
        flags.
(略)

曰く、「このpoolはlegacy on-disk formatでフォーマットされている。
もちろんpoolは引き続き使えるけれども、いくかの機能が使えない。」とのこと。

zpoolを調べてみたが、最新のv28である。

$ zpool get all|grep vault
vault      size                   2.27T                  -
vault      capacity               64%                    -
vault      health                 ONLINE                 -
vault      version                28                     local
(略)

 

zpool upgradeで調べて分かってきた。
zpoolバージョンではなくfeature flagsのことを言っているわけだ。

$ zpool upgrade
This system supports ZFS pool feature flags.

The following pools are formatted with legacy version numbers and can
be upgraded to use feature flags.  After being upgraded, these pools
will no longer be accessible by software that does not support feature
flags.

VER  POOL
---  ------------
28   vault

Use 'zpool upgrade -v' for a list of available legacy versions.
Every feature flags pool has all supported features enabled.

 

で、もういちど調べてみると。

$ zpool get all|grep vault
vault      size                   2.27T                  -
vault      capacity               64%                    -
vault      health                 ONLINE                 -
vault      version                28                     local
(略)
vault      feature@async_destroy  disabled               local
vault      feature@empty_bpobj    disabled               local
vault      feature@lz4_compress   disabled               local

featureがいくつかdiabledになっている。
そうと分かれば素直にupgradeである。

zpoolのupgrade

zpool upgradeとするだけ。
ただ、バージョンが変わらないとはいえ、ファイルシステムの基盤をアップグレードするわけだからバックアップは取っといた。

$ sudo zpool upgrade vault
This system supports ZFS pool feature flags.

Successfully upgraded 'vault' from version 28 to feature flags.
Enabled the following features on 'vault':
  async_destroy
  empty_bpobj
  lz4_compress

あっけなく終了。

調べてみるとversionが消えて(なぜ….でもpropertiesがdefaultだからよしとしよう)、その代りfeatureはすべてenabledに変化したことが分かる。
なお、enabledは「その機能が使えますよ」という表示。
実際に有効にするとenabledはactiveに変化する。

$ zpool get all|grep vault
vault      size                   2.27T                  -
vault      capacity               64%                    -
vault      health                 ONLINE                 -
vault      version                -                      default
(略)
vault      feature@async_destroy  enabled                local
vault      feature@empty_bpobj    enabled                local
vault      feature@lz4_compress   enabled                local

 

zpool upgrade、zpool statusの表示いずれも問題なし。

$ zpool upgrade
This system supports ZFS pool feature flags.

All pools are formatted using feature flags.

Every feature flags pool has all supported features enabled.

$ zpool status
  pool: vault
 state: ONLINE
  scan: scrub repaired 0 in 4h53m with 0 errors on Sat Jul 27 14:35:23 2013
config:

        NAME        STATE     READ WRITE CKSUM
        vault       ONLINE       0     0     0
          ada1      ONLINE       0     0     0

errors: No known data errors

 

[メモ] ディスクを追加してZFSを作り、他zpoolのsnapshotを送り込む

Pocket

 

HDDを増設してZFSを作ったのでメモ。
一本のHDDにpool、zfsを作成し、圧縮、重複排除機能の有効化まで。
環境は(残念ながら10.0-Rではなく)FreeBSD 9.2-RELEASE-p1。

lz4でzfsの圧縮機能を気軽に試せるように

ファイルシステムで圧縮機能を有効にすると、読み書きのいずれにもCPUパワーが必要で、要するに遅くなる。
非力なCPUを使っているとなかなか使いにくい機能なのだが、圧縮方法にlz4が選べるようになってハードルは下がったように思う。
lz4はここでも触れたが、めっぽう速い圧縮アルゴリズムである。
これはぜひとも使ってみなければ。

 

 

ディスクの確認とzfs機能の確認

物理ディスクを追加し、ブートしたらdmesgを確認する。

$ uname -r
9.2-RELEASE
$ dmesg|grep ada
ada2 at ahcich2 bus 0 scbus2 target 0 lun 0
ada2: <WDC WD30EZRX-00D8PB0 80.00A80> ATA-9 SATA 3.x device
ada2: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada2: Command Queueing enabled
ada2: 2861588MB (5860533168 512 byte sectors: 16H 63S/T 16383C)
ada2: quirks=0x1<4K>
ada2: Previously was known as ad8

ada2とのこと。

作業前にzfs, zpoolのバージョンを確認しておいてもいいかも。
zfs, zpoolそれぞれにupgradeオプションを与えればよい。
upgradeという名前の通り、upgradeのためのコマンドだが、バージョン確認にも使える。

$ zfs upgrade
This system is currently running ZFS filesystem version 5.

All filesystems are formatted with the current version.
$
$ zpool upgrade
This system supports ZFS pool feature flags.

The following pools are formatted with legacy version numbers and can
be upgraded to use feature flags.  After being upgraded, these pools
will no longer be accessible by software that does not support feature
flags.

VER  POOL
---  ------------
28   vault

Use 'zpool upgrade -v' for a list of available legacy versions.
Every feature flags pool has all supported features enabled.

zfsはバージョン5、zpoolはバージョン28。
このバージョンであれば、lz4による圧縮機能(LZ4 Compression algorithm support)と、重複排除機能(Deduplication)を使える。

pool、zfsの作成

warehouseというzpoolを作り、そこからbackupというボリュームを切り出す。

まずzpoolを作る。
ほんと簡単で速くて助かる。

$ sudo zpool create backup /dev/ada2
$

で確認。

$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault/itunes on /itunes (zfs, local, noatime, nfsv4acls)
vault/chamber on /chamber (zfs, local, noatime, nfsv4acls)
backup on /backup (zfs, local, nfsv4acls)

$ zpool status
pool: backup
state: ONLINE
scan: none requested
config:

NAME        STATE     READ WRITE CKSUM
backup      ONLINE       0     0     0
ada2      ONLINE       0     0     0

errors: No known data errors

pool: vault
state: ONLINE
(略)

$ df
 Filesystem     1K-blocks      Used      Avail Capacity  Mounted on
 /dev/ada0p2    239436440  20822200  199459328     9%    /
 devfs                  1         1          0   100%    /dev
 vault/itunes  1436646199 598670122  837976077    42%    /itunes
 vault/chamber 1796007595 958031518  837976077    53%    /chamber
 warehouse     2873622450        31 2873622419     0%    /warehouse

ではzpoolからzfsの切り出し。
先ほど作成したwarehouseからbackupという名前で。

$ sudo zfs create warehouse/backup
$
$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault/itunes on /itunes (zfs, local, noatime, nfsv4acls)
vault/chamber on /chamber (zfs, local, noatime, nfsv4acls)
warehouse on /warehouse (zfs, local, nfsv4acls)
warehouse/backup on /warehouse/backup (zfs, local, nfsv4acls)
$ df
Filesystem        1K-blocks      Used      Avail Capacity  Mounted on
/dev/ada0p2       239436440  20823572  199457956     9%    /
devfs                     1         1          0   100%    /dev
vault/itunes     1436646199 598670122  837976077    42%    /itunes
vault/chamber    1796007595 958031518  837976077    53%    /chamber
warehouse        2873622404        32 2873622372     0%    /warehouse
warehouse/backup 2873622403        31 2873622372     0%    /warehouse/backup

あとは/etc/fstabに書くだけ。
warehouse/backupを/backupにマウントするとして以下のように書いておき。

warehouse/backup        /backup zfs     rw      0       0

/warehouse/backupをいったんunmountしてそれからmount。

$ sudo umount /warehouse/backup
$
$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault/itunes on /itunes (zfs, local, noatime, nfsv4acls)
vault/chamber on /chamber (zfs, local, noatime, nfsv4acls)
warehouse on /warehouse (zfs, local, nfsv4acls)
$
$ sudo mount /backup
$
$ mount
/dev/ada0p2 on / (ufs, local, journaled soft-updates)
devfs on /dev (devfs, local, multilabel)
vault/itunes on /itunes (zfs, local, noatime, nfsv4acls)
vault/chamber on /chamber (zfs, local, noatime, nfsv4acls)
warehouse on /warehouse (zfs, local, nfsv4acls)
warehouse/backup on /backup (zfs, local, nfsv4acls)

 

圧縮機能と重複排除機能を有効に

ではさっそく圧縮機能と重複排除機能を有効にする。
といっても、すっごく簡単なんだけどね。

$ sudo zfs set dedup=on warehouse/backup
$
$ sudo zfs set compression=lz4 warehouse/backup
$

確認。
zfs getで対象zfsの属性を確認できる。

$ zfs get dedup warehouse/backup
NAME              PROPERTY  VALUE          SOURCE
warehouse/backup  dedup     on             local
$
$ zfs get compression warehouse/backup
NAME              PROPERTY     VALUE     SOURCE
warehouse/backup  compression  lz4       local
$

タイプが面倒ならzfs get allですべての属性を表示させ、grepすればよい。

$ zfs get all warehouse/backup|egrep "compre|ded"
warehouse/backup  compressratio         1.00x                    -
warehouse/backup  compression           lz4                      local
warehouse/backup  dedup                 on                       local
warehouse/backup  refcompressratio      1.00x                    -

 

書き込んでみる

今回追加したHDDはもともとバックアップ用途のつもり。
ここにスナップショットを流しこんでみる。

以下のようにしてスナップショットを作成する。

$ sudo zfs snapshot vault/itunes@`date +%Y%m%d`
$
$ sudo zfs snapshot vault/chamber@`date +%Y%m%d`

スナップショットのサイズは以下のとおりである。

$ zfs list -t snapshot
NAME                     USED  AVAIL  REFER  MOUNTPOINT
vault/chamber@20131121      0      -   914G  -
vault/itunes@20131121       0      -   571G  -

これらスナップショットをバックアップのHDDに流し込む。
zfs sendとzfs recvをパイプで繋ぐ必要がある。
sudoを使う場合にはsh -cで。

$ sudo sh -c "zfs send vault/chamber@20131121 | zfs recv warehouse/backup/chamber"

注意点がある。
以上のようにsnapshotを送ると、受け側では:
①warehouse/backup/chamber ができ、さらに;
②warehouse/backup/chamber@20131121 つまり;
実ディレクトリで言えばwarehouse/backup/chamber/.zfs/snapshot/20131121ができる。

漠然とvault/chamber@20131121の内容がwarehouse/backup/chamberに書き込まれる思っていたので驚いた。

 

また、ロードアベレージを監視するような仕組みは特に入れていなかったので、topの出力を見たところ5を超えてた。ちょっと怖い。

last pid: 10483;  load averages:  5.37,  2.84,  1.36           up 2+23:24:54  22:01:40
45 processes:  3 running, 42 sleeping
CPU:  0.0% user,  0.0% nice, 56.8% system,  0.3% interrupt, 42.9% idle
Mem: 20M Active, 96M Inact, 1592M Wired, 11M Cache, 200M Buf, 120M Free
ARC: 1039M Total, 58M MFU, 826M MRU, 103M Anon, 11M Header, 40M Other
Swap: 907M Total, 10M Used, 897M Free, 1% Inuse

そしてたかだか913GBのsnapshotの転送にかかった時間であるが。

real    3756m59.109s
user    0m0.048s
sys     192m3.897s

まる二日半て…。
これは圧縮か重複排除か、どちらか止めた方がいいかもわからんね。

差分snapshotの転送

オリジナルディスクで複数回snapshotを作成した場合、バックアップディスクにはその差分を送ることができる。
zfs sendに-iを与え、二つのsnapshotを指定すればよいだけ。

$ sudo sh -c "zfs send -i vault/chamber@20131121 vault/chamber@20131125 | zfs recv warehouse/backup/chamber"

以上