btrfs 運用日記#

基本的なことはbtrfs wikiとおよびbtrfs arch wikiが参考になる.ドキュメントにある. 情報は古いが昔Qiitaにも記事を書いている.

ディスクの交換#

(2026.1.9)

手順は概ねReplacing failed devicesに従う.

HDDが故障したわけじゃないが,/dev/sddのDiskUtilityが他の3台より以上に高いため念の為に交換する. 下記のように4台のHDDでRAID10の構成である.

# btrfs filesystem show /hddpool/
Label: 'hddpool'  uuid: 46a60800-98c7-49bb-b380-9f9753fae539
	Total devices 4 FS bytes used 3.05TiB
	devid    1 size 14.55TiB used 1.55TiB path /dev/sdc
	devid    2 size 14.55TiB used 1.55TiB path /dev/sdb
	devid    3 size 14.55TiB used 1.55TiB path /dev/sda
	devid    4 size 14.55TiB used 1.55TiB path /dev/sdd

SMART情報は以下の通り,運用期間は概ね3.6年程度経過しているがエラー等はない.

# smartctl -a /dev/sdd
smartctl 7.3 2022-02-28 r5338 [x86_64-linux-6.1.0-41-amd64] (local build)
Copyright (C) 2002-22, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family:     Toshiba MG08ACA... Enterprise Capacity HDD
Device Model:     TOSHIBA MG08ACA16TE
Serial Number:    91Q0A0Z0FVGG
LU WWN Device Id: 5 000039 b28d98de4
Firmware Version: 0102
User Capacity:    16,000,900,661,248 bytes [16.0 TB]
Sector Sizes:     512 bytes logical, 4096 bytes physical
Rotation Rate:    7200 rpm
Form Factor:      3.5 inches
Device is:        In smartctl database 7.3/5319
ATA Version is:   ACS-3 T13/2161-D revision 5
SATA Version is:  SATA 3.3, 6.0 Gb/s (current: 6.0 Gb/s)
Local Time is:    Fri Jan  9 12:31:28 2026 JST
SMART support is: Available - device has SMART capability.
SMART support is: Enabled
...
SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x000b   100   100   050    Pre-fail  Always       -       0
  2 Throughput_Performance  0x0005   100   100   050    Pre-fail  Offline      -       0
  3 Spin_Up_Time            0x0027   100   100   001    Pre-fail  Always       -       7882
  4 Start_Stop_Count        0x0032   100   100   000    Old_age   Always       -       31
  5 Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       0
  7 Seek_Error_Rate         0x000b   100   100   050    Pre-fail  Always       -       0
  8 Seek_Time_Performance   0x0005   100   100   050    Pre-fail  Offline      -       0
  9 Power_On_Hours          0x0032   019   019   000    Old_age   Always       -       32417
 10 Spin_Retry_Count        0x0033   100   100   030    Pre-fail  Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       31
 23 Helium_Condition_Lower  0x0023   100   100   075    Pre-fail  Always       -       0
 24 Helium_Condition_Upper  0x0023   100   100   075    Pre-fail  Always       -       0
191 G-Sense_Error_Rate      0x0032   100   100   000    Old_age   Always       -       1
192 Power-Off_Retract_Count 0x0032   100   100   000    Old_age   Always       -       30
193 Load_Cycle_Count        0x0032   100   100   000    Old_age   Always       -       43
194 Temperature_Celsius     0x0022   100   100   000    Old_age   Always       -       22 (Min/Max 5/41)
196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       0
197 Current_Pending_Sector  0x0032   100   100   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0030   100   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x0032   200   200   000    Old_age   Always       -       0
220 Disk_Shift              0x0002   100   100   000    Old_age   Always       -       85196801
222 Loaded_Hours            0x0032   020   020   000    Old_age   Always       -       32149
223 Load_Retry_Count        0x0032   100   100   000    Old_age   Always       -       0
224 Load_Friction           0x0022   100   100   000    Old_age   Always       -       0
226 Load-in_Time            0x0026   100   100   000    Old_age   Always       -       597
240 Head_Flying_Hours       0x0001   100   100   001    Pre-fail  Offline      -       0

サーバーのHDDのトレーに余裕があればreplaceコマンドで交換できるが,トレーが4つしかないので一度/dev/sddをraid10の構成から外す. まずは物理的に/dev/sddを特定するためにHDDのステータスランプをledmonで操作を試みる.Debian系はaptでインストールできる(sudo apt install ledmon).

# sudo ledctl locate=/dev/sdd # 特定する場合
# sudo ledctl normal=/dev/sdd # 通常に戻す場合

うちの環境だと非対応っぽくて特定できず(😭).仕方ないのでddコマンドで/dev/sddを読み出してディスクアクセスのステータスランプを確認し特定(HDDエンクロージャーの重要性がわかる瞬間,研究用のNASは裸運用なんだよな・・・).

# sudo ionice -c 1 -n 0 dd if=/dev/sdd of=/dev/null bs=1M

物理diskを確認して,ホットスワップでそのまま抜いても良いかもしれないがここでは/hddpoo/に書き込みしているサービスを確認して停止する.

# sudo lsof +D /hddpool

サービスを停止

# systemctl stop zabbix-server.service syslog.socket rsyslog.service elasticsearch.service logstash.service kibana.service btrbk.timer mariadb.service
# sudo umount /hddpool

HDDを交換する.アンマウントしてもdiskは回転しているので,抜いたら回転が停止するまで少し待つと良いだろう.

# lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda      8:0    0  14.6T  0 disk
sdb      8:16   0  14.6T  0 disk
sdc      8:32   0  14.6T  0 disk
sdd      8:48   0  14.6T  0 disk
sde      8:64   0 931.5G  0 disk
├─sde1   8:65   0   512M  0 part /boot/efi
├─sde2   8:66   0 838.2G  0 part /mnt/btr_pool
│                                /
└─sde3   8:67   0  92.8G  0 part [SWAP]
# btrfs filesystem show /hddpool/
Label: 'hddpool'  uuid: 46a60800-98c7-49bb-b380-9f9753fae539
	Total devices 4 FS bytes used 3.05TiB
	devid    1 size 14.55TiB used 1.55TiB path /dev/sdc
	devid    2 size 14.55TiB used 1.55TiB path /dev/sdb
	devid    3 size 14.55TiB used 1.55TiB path /dev/sda
	devid    4 size 0 used 0 path  MISSING

欠損(degrated)モードで/hddpoolをマウント

# mount -o degraded /dev/sda /hddpool

devid 4/dev/sddでreplaceする

# btrfs replace start 4 /dev/sdd /hddpool
# btrfs filesystem show
Label: 'root'  uuid: d313cd52-7511-4311-81fb-a5aa43c42bf6
	Total devices 1 FS bytes used 229.25GiB
	devid    1 size 838.19GiB used 714.08GiB path /dev/sde2

Label: 'hddpool'  uuid: 46a60800-98c7-49bb-b380-9f9753fae539
	Total devices 5 FS bytes used 3.05TiB
	devid    0 size 14.55TiB used 1.55TiB path /dev/sdd
	devid    1 size 14.55TiB used 1.55TiB path /dev/sdc
	devid    2 size 14.55TiB used 1.55TiB path /dev/sdb
	devid    3 size 14.55TiB used 1.55TiB path /dev/sda
	devid    4 size 0 used 0 path  MISSING

なんかdevid 0に追加されてるんだけど...replace statusは下記コマンドで確認可能なのでreplaceが終わったら再度確認してみるか.

# btrfs replace status /hddpool
0.0% done, 0 write errs, 0 uncorr. read errs

RAID10なのでとりあえずはdegradedの状態でもサービスは動くの,サービスを再開する.

systemctl start zabbix-server.service syslog.socket rsyslog.service elasticsearch.service logstash.service kibana.service btrbk.timer mariadb.service

~翌日~

# btrfs replace status /hddpool
Started on  9.Jan 13:32:07, finished on  9.Jan 19:42:24, 0 write errs, 0 uncorr. read errs

6時間くらいで終了していた.devidも正しく修正されmissingも消えた.

# btrfs filesystem show /hddpool

Label: 'hddpool'  uuid: 46a60800-98c7-49bb-b380-9f9753fae539
	Total devices 4 FS bytes used 3.05TiB
	devid    1 size 14.55TiB used 1.55TiB path /dev/sdc
	devid    2 size 14.55TiB used 1.55TiB path /dev/sdb
	devid    3 size 14.55TiB used 1.55TiB path /dev/sda
	devid    4 size 14.55TiB used 1.55TiB path /dev/sdd

思ったより早い.degradedでmountしているので,通常マウントするためサービスを停止

# systemctl stop zabbix-server.service syslog.socket rsyslog.service elasticsearch.service logstash.service kibana.service btrbk.timer mariadb.service
# sudo umount /hddpool
# mount -av
/                        : ignored
/boot/efi                : already mounted
none                     : ignored
/hddpool                 : successfully mounted
/mnt/btr_pool            : already mounted

サービスの再開.

# systemctl start zabbix-server.service syslog.socket rsyslog.service elasticsearch.service logstash.service kibana.service btrbk.timer mariadb.service

replace終了後も異様にDiskUtilityが高い(特に,交換したHDDへのw_await),しばらくは様子見かな.

もし長時間続くようであればbalanceしてみるか.

Disk書き込み過負荷#

4~5日待っても交換後のdiskのutilizationがかなり高く80%台を推移している.まずはmetaデータのみblanceしてみる.時間がかかるのでtmux環境で

# btrfs balance start -m /hddpool

とbalanceを実行する.branceのstatusは下記コマンドで確認できる.

# btrfs balance status /hddpool/
Balance on '/hddpool/' is running
11 out of about 24 chunks balanced (984 considered),  54% lef

balanceは終了したが状況変わらず.ディスクスケジューラーを参考デフォルトの

[mq-deadline] bfq none

から

# cat /sys/block/sd*/queue/scheduler
mq-deadline [bfq] none
mq-deadline [bfq] none
mq-deadline [bfq] none
mq-deadline [bfq] none

に変更してみるも変化なし...1%だけバランスしてみるこれはすぐに終わる.

# btrfs balance start -dusage=1 /hddpool

w_awaitが4倍くらい時間かかってんだよね・・・初期不良か,配線か?

# iostat -xz 1
Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz     f/s f_await  aqu-sz  %util
sda              0.00      0.00     0.00   0.00    0.00     0.00  270.00   2584.00    17.00   5.92    0.25     9.57    0.00      0.00     0.00   0.00    0.00     0.00   78.00    0.19    0.08   5.60
sdc              0.00      0.00     0.00   0.00    0.00     0.00  270.00   2584.00    17.00   5.92    0.28     9.57    0.00      0.00     0.00   0.00    0.00     0.00   78.00    0.27    0.10   6.40
sdd              1.00      8.00     0.00   0.00   11.00     8.00  278.00   2960.00    24.00   7.95    0.25    10.65    0.00      0.00     0.00   0.00    0.00     0.00   78.00    0.29    0.10   6.00
sde              0.00      0.00     0.00   0.00    0.00     0.00  278.00   3004.00    24.00   7.95    3.25    10.81    0.00      0.00     0.00   0.00    0.00     0.00   78.00    0.36    0.93  84.80

iotop -oPaでIOの最も高いものはelasticsearchだと判明しているので,一度elasticsearchを止めてみるとDiskUtilityはほぼ0におちつくので原因ははっきりとelasticsearch.elasticsearchへの最適化はここでに続く

圧縮#

(2026.1.10)

圧縮の一般的なことはCompressionが参考になる.

hddpool/est/fstab

UUID=........ /hddpool btrfs defaults,compress-force=zstd,noatime,commit=60 0 0

としてmountしており,elasticsearchrsyslogで受信した生log,mariadbbtrbkによるbackupが保管されている./hddpool/elasticsearch/のディレクトリは全体で4.2T2.7Tで圧縮率64%(=データ削減率36%).

# compsize /hddpool/elasticsearch/ 
Processed 13110 files, 33867706 regular extents (33867706 refs), 6486 inline.
Type       Perc     Disk Usage   Uncompressed Referenced
TOTAL       64%      2.7T         4.2T         4.2T
none       100%      340G         340G         340G
zstd        61%      2.4T         3.9T         3.9T

上記コマンドはめちゃ時間がかかるのとディスクアクセスに負担をかけるので注意.

他も調べてみよう.生ログは月に1度xzで圧縮してtarに保管しており, xzの圧縮で約30GB/日のデータが0.5GB/日程度になるために,98%のデータが削減される. そのため,btrfsによるzstdの圧縮はおこなわれていない.

# compsize syslog_0910.log
Processed 1 file, 245460 regular extents (245460 refs), 0 inline.
Type       Perc     Disk Usage   Uncompressed Referenced
TOTAL        6%      1.9G          29G          29G
none       100%      4.0K         4.0K         4.0K
zstd         6%      1.9G          29G          29G
# compsize syslog_0910.tar.xz
Processed 1 file, 1984 regular extents (1984 refs), 0 inline.
Type       Perc     Disk Usage   Uncompressed Referenced
TOTAL      100%      758M         758M         758M
none       100%      758M         758M         758M

mysql(mariadb)はデータ自体そんなに大きくないが,比較的高効率に圧縮が効いている.

# compsize /hddpool/mysql/
Processed 697 files, 679412 regular extents (755414 refs), 339 inline.
Type       Perc     Disk Usage   Uncompressed Referenced
TOTAL       25%      8.8G          35G          29G
none       100%      1.3G         1.3G         1.2G
zstd        22%      7.5G          33G          28G
prealloc   100%       16K          16K         9.9M

btrfsのシステム全体はbtrbkで定期的にbackupを/hddpool/backupに格納している.

# ls /hddpool/backup/rootfs/
@rootfs.20250105T0000  @rootfs.20251102T0025  @rootfs.20251214T0025  @rootfs.20251228T0025  @rootfs.20260101T0025  @rootfs.20260103T0025  @rootfs.20260105T0025  @rootfs.20260107T0025	@rootfs.20260109T0025
@rootfs.20251005T0000  @rootfs.20251207T0025  @rootfs.20251221T0025  @rootfs.20251231T0025  @rootfs.20260102T0025  @rootfs.20260104T0025  @rootfs.20260106T0025  @rootfs.20260108T0025	@rootfs.20260110T0025
# compsize /hddpool/backup/
Processed 5348212 files, 3438361 regular extents (19051810 refs), 3112411 inline.
Type       Perc     Disk Usage   Uncompressed Referenced
TOTAL       36%       63G         174G         1.0T
none       100%       18G          18G         280G
zstd        28%       45G         155G         845G