Btrfsのbtrfs-transactionでioが100%になって困る

デスクトップ検索のRecollを試してみようと recollindex コマンドでindexを作ってみました.すると様々なアプリケーションがフリーズ.indexが出来るまでの辛抱だろうと1日ほど放置してみましたが解消しません.
1つのコマンドを発行して実行されるまで何分も掛かってしまいます.

cpuやmemoryはガラガラです.
iotop を叩いてみると btrfs-transaction がほぼ100%で張り付いています.

マウントオプションはこんな感じ.

$ mount | grep \ /\
/dev/mapper/t430s--vg-root on / type btrfs (rw,noatime,nodiratime,ssd,discard,space_cache,subvolid=5,subvol=/)

discard を `btrfs(5) ` で確認するとちょっと怪しいような?

       discard, nodiscard
           (default: off)

           Enable discarding of freed file blocks. This is useful for SSD devices, thinly provisioned LUNs, or virtual machine images; however, every storage layer must
           support discard for it to work. if the backing device does not support asynchronous queued TRIM, then this operation can severely degrade performance, because a
           synchronous TRIM operation will be attempted instead. Queued TRIM requires newer than SATA revision 3.1 chipsets and devices.

       If it is not necessary to immediately discard freed blocks, then the fstrim tool can be used to discard all free blocks in a batch. Scheduling a TRIM during a period
       of low system activity will prevent latent interference with the performance of other operations. Also, a device may ignore the TRIM command if the range is too
       small, so running a batch discard has a greater probability of actually discarding the blocks.

       If discarding is not necessary to be done at the block freeing time, there’s fstrim(8) tool that lets the filesystem discard all free blocks in a batch, possibly not
       much interfering with other operations. Also, the device may ignore the TRIM command if the range is too small, so running the batch discard can actually discard the
       blocks.

SATAのバージョンを確認すると 3.2 なので問題無さそう?

$ sudo smartctl --info /dev/sda | grep ^SATA
SATA Version is:  SATA 3.2, 6.0 Gb/s (current: 6.0 Gb/s)

でも一旦無効にしてみます.
#ついでに付けた compress=lzo は別でやるべきだった…….

$ time sudo mount -o remount,rw,noatime,nodiratime,ssd,nodiscard,compress=lzo,space_cache /
real    42m32.840s
user    0m0.014s
sys     0m15.209s
$ mount | grep \ /\
/dev/mapper/t430s--vg-root on / type btrfs (rw,noatime,nodiratime,compress=lzo,ssd,space_cache,subvolid=5,subvol=/)

これが当たりだったようでioは一気に空きました!
SATA 3.2 だけど何か別の条件が良くないのでしょうか?

忘れないうちに fstab も修正しておきます.(nodiscard は既定値なので書いていない)

 sudo git -C /etc diff HEAD^ -- /etc/fstab
diff --git a/fstab b/fstab
index b029749..386278f 100644
--- a/fstab
+++ b/fstab
@@ -5,7 +5,7 @@
 # that works even if disks are added and removed. See fstab(5).
 #
 # <file system> <mount point>   <type>  <options>       <dump>  <pass>
-/dev/mapper/t430s--vg-root /               btrfs   noatime,nodiratime,ssd,discard,space_cache 0       0
+/dev/mapper/t430s--vg-root /               btrfs   noatime,nodiratime,ssd,compress=lzo,space_cache 0       0
 # /boot was on /dev/sda2 during installation
 UUID=cba2591a-12da-481e-b239-c002faca22e1 /boot           ext2    defaults        0       2
 # /boot/efi was on /dev/sda1 during installation

これで暫く様子を見てみます.
問題なければ別途TRIMを設定したほうがいいかな?

環境

$ dpkg-query -W btrfs-progs iotop smartmontools
btrfs-progs     5.2.1-1
iotop   0.6-24-g733f3f8-1
smartmontools   7.0-2
$ sudo smartctl -i /dev/sda | grep -E '^Device Model:|Firmware Version:|SATA Version is:'
Device Model:     Seagate BarraCuda SSD ZA1000CM10002
Firmware Version: STAS1024
SATA Version is:  SATA 3.2, 6.0 Gb/s (current: 6.0 Gb/s)
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

Btrfsでdfで空き容量があるように見えるのに容量が無いと言われてreadonlyにされてしまう

最近Btrfsで利用中にroにされてしまうという症状が起きます.
こんな感じで怒られてroになる.
dfは87%とかで未だ空きはあるように見える.
/に使ってるとこでremount,rwも効かず再起動しないと戻せず辛い.

[ 2196.878532] BTRFS: error (device dm-1) in btrfs_truncate_inode_items:4647: errno=-28 No space left
[ 2196.878537] BTRFS info (device dm-1): forced readonly
[ 2196.881248] BTRFS error (device dm-1): pending csums is 1241088

FAQだったようでここを参照しながら

別のsystemで確認してbtrfs fi balance start -dusage=5を叩いてみました.

$ sudo btrfs fi show
Label: none uuid: e54de82f-1fdb-4f9a-b529-0952b0ea3454
        Total devices 1 FS bytes used 465.89GiB
        devid 1 size 542.28GiB used 542.28GiB path /dev/mapper/x220--vg-root

$ sudo mount -o ro /dev/mapper/x220--vg-root /mnt
$ sudo btrfs fi df /mnt
Data, single: total=538.27GiB, used=462.41GiB
System, single: total=4.00MiB, used=80.00KiB
Metadata, single: total=4.01GiB, used=3.48GiB
GlobalReserve, single: total=512.00MiB, used=0.00B
$ sudo btrfs fi balance start -dusage=5 /mnt
ERROR: error during balancing '/mnt': Read-only file system
There may be more info in syslog - try dmesg | tail
$ sudo mount -o remount,rw /mnt
$ sudo btrfs fi balance start -dusage=5 /mnt
Done, had to relocate 0 out of 546 chunks

しかしあまり変わらず暫く利用しているとまたエラーに.しかし今度はdisk fullと怒られるけどroにはならなかったです.以下のページによると,

This means the bigger the -dusage value, the more work balance will have to do (i.e. taking fuller and fuller blocks and trying to free them up by putting their data elsewhere). Also, if your FS is 55% full, using -dusage=55 is ok, but there isn’t a 1 to 1 correlation and you’ll likely be ok with a smaller dusage number, so start small and ramp up as needed.

ということで-dusage=90にしてみると結構空いた感じです.
上の方では別systemで起動して実行しましたが,オンラインでも大丈夫でした.但し処理中はかなり重くなります.そして処理に200分程かかりました.

$ sudo btrfs fi balance start -dusage=90 /
Done, had to relocate 186 out of 530 chunks
$ sudo btrfs fi show
Label: none  uuid: e54de82f-1fdb-4f9a-b529-0952b0ea3454
        Total devices 1 FS bytes used 446.08GiB
        devid    1 size 542.28GiB used 449.27GiB path /dev/mapper/x220--vg-root

この後数GBのデータを書いてみたり溜まっていたapt upgradeとかしてみましたが今のところ大丈夫そうです.
ちなみにこのfsがあるSSD(INTEL SSDSA2CW600G3)も長く使っているのでそっちも心配だったのですが,smartctl-t longしたり-aの以下のあたり見る感じでは未だ行けそう?

9 Power_On_Hours 0x0032 100 100 000 Old_age Always – 36565
228 Workload_Minutes 0x0032 100 100 000 Old_age Always – 2193912
232 Available_Reservd_Space 0x0033 100 100 010 Pre-fail Always – 0
233 Media_Wearout_Indicator 0x0032 095 095 000 Old_age Always – 0

#適当なとこでsecure eraseしておきたい…….

Btrfsでswap fileが作れないことを知らずに嵌まる

ファイルからswapを設定しようとして失敗しました.

$ fallocate -l 500M test
$ /sbin/mkswap test
mkswap: test: insecure permissions 0644, 0600 suggested.
Setting up swapspace version 1, size = 500 MiB (524283904 bytes)
no label, UUID=aaf26c11-4653-40d5-b279-faa7d8c8625d
$ sudo chmod 600 test
$ sudo chown 0.0 test
$ ls -l test
-rw------- 1 root root 524288000 10月  3 07:26 test
$ sudo swapon test
swapon: /home/mk/test: swapon failed: 無効な引数です
$ sudo swapon -v /home/mk/test
swapon: /home/mk/test: found signature [pagesize=4096, signature=swap]
swapon: /home/mk/test: pagesize=4096, swapsize=524288000, devsize=524288000
swapon /home/mk/test
swapon: /home/mk/test: swapon failed: 無効な引数です
$ LANG=C sudo swapon -v /home/mk/test
swapon: /home/mk/test: found signature [pagesize=4096, signature=swap]
swapon: /home/mk/test: pagesize=4096, swapsize=524288000, devsize=524288000
swapon /home/mk/test
swapon: /home/mk/test: swapon failed: Invalid argument

検索するとBtrfsでswap fileがサポートされていないとか.知らなかったorz

性能低下するけどloop deviceを使えばいけるよというワークアラウンドが.

A workaround, albeit with poor performance, is to mount a swap file via a loop device.

試してみます.

$ /sbin/losetup -l
$ sudo /sbin/losetup loop0 ./test
$ /sbin/losetup -l
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO
/dev/loop0 0 0 0 0 /home/mk/test 0
$ sudo swapon -v /dev/loop0
swapon: /dev/loop0: found signature [pagesize=4096, signature=swap]
swapon: /dev/loop0: pagesize=4096, swapsize=536870912, devsize=536870912
swapon /dev/loop0
$ /sbin/swapon -s
Filename Type Size Used Priority
/dev/dm-2 partition 16658428 0 -1
/dev/loop0 partition 524284 0 -2

うまく行きました. もとに戻しておきます.

$ sudo swapoff /dev/loop0
$ sudo /sbin/losetup -d /dev/loop0
$ sudo rm ./test