btrfs の透過圧縮を有効にしてみる

btrfs は透過圧縮が使える。

圧縮を有効にすると Disk I/O の負荷が減るので 素の btrfs よりも速くなる ようです。 (リンク先はカーネルが古すぎるので参考にならんかもですが・・・)

というわけで すでに btrfs で構築済みの / の圧縮を有効にしてみます。

マウントオプションを変える

/etc/fstab を編集して、 / のマウントオプションに compress=lzo を追加します。

UUID=b2ea3bb7-9a9d-4487-93e6-279934821f06 / btrfs defaults,compress=lzo 0 0

追加したら再起動。

既存のファイルを圧縮する

マウントオプション変えただけでは既存のファイルは未圧縮状態なので、 btrfs filesystem defragment -clzo で圧縮をかけます。

$ sudo btrfs filesystem defragment -clzo -v

スナップショットがある場合

この時ファイルシステムのスナップショットがあると、ファイルシステムの空き領域がもりもりと減っていきます。CoW の鼓動を感じます。 空き領域が厳しい場合(具体的には空き50%未満)は事前にスナップショットを消すなどして、空き領域を増やしたほうが良さそうです。

また圧縮終了後は、コマンド実行前のスナップショットに未圧縮のデータが残ったままになるので、新しくスナップショット作って未圧縮データが残っているスナップショットは消さないと容量が無駄になります。

透過圧縮を試す

透過圧縮が動作していれば、例えば中身がすべて 0x00 の数GBのファイルを作っても、空き容量はほとんど変化しないはずです。 dd if=/dev/zero で中身0の大容量ファイルを作って試してみます。

まず作成前。

$ sudo btrfs filesystem df /
Data, single: total=11.24GiB, used=4.20GiB
System, single: total=11.00MiB, used=16.00KiB
Metadata, single: total=768.00MiB, used=296.81MiB
GlobalReserve, single: total=21.05MiB, used=0.00B

空き容量は 4.20GiB。ここで4GBぐらいのファイルを作ってみる。

$ sudo dd if=/dev/zero of=/dummy.bin bs=1M count=4K
4096+0 レコード入力
4096+0 レコード出力
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 9.93683 s, 432 MB/s

ls で見るとちゃんと4GBあります。

$ ls -lh /dummy.bin
-rw-r--r-- 1 root root 4.0G  3月 25 22:16 dummy.bin

しかしファイルシステムの空き容量は 4.32GiB で、0.1GiB しか増えていません。ちゃんと透過圧縮が効いているみたいです。

$ sudo btrfs filesystem df /
Data, single: total=11.24GiB, used=4.32GiB
System, single: total=11.00MiB, used=16.00KiB
Metadata, single: total=768.00MiB, used=301.94MiB
GlobalReserve, single: total=23.62MiB, used=0.00B

ちなみに圧縮後のファイルサイズが小さければ、実ファイルサイズがファイルシステムの総容量を超えていてもファイルが作れるようです。 なので11GiBちょっとのファイルシステム上に 20GB のファイルが作れてしまったりする。

$ sudo dd if=/dev/zero of=/dummy.bin bs=1M count=20K
20480+0 レコード入力
20480+0 レコード出力
21474836480 bytes (21 GB, 20 GiB) copied, 79.485 s, 270 MB/s
$ ls -lh /dummy.bin
-rw-r--r-- 1 root root 20G  3月 25 22:49 /dummy.bin
$ sudo btrfs filesystem df /
Data, single: total=11.24GiB, used=4.82GiB
System, single: total=11.00MiB, used=16.00KiB
Metadata, single: total=768.00MiB, used=323.72MiB
GlobalReserve, single: total=33.75MiB, used=0.00B

social