Linux

如何在 btrfs 中線上驗證校驗和?

  • December 12, 2021

TL;DR: raid1 中的兩個磁碟使用 btrfs。校驗和僅針對從中讀取文件數據的磁碟進行驗證。如何偶爾強制驗證所有校驗和,例如在每週的 cron 中?


我在 raid1 ( /dev/sd{b,c}1) 的 2 個磁碟上有一個 btrfs。為了測試糾錯,我將一個文件寫入磁碟,查找它儲存在哪個扇區,並通過直接寫入/dev/sdc1. 自從我 mount 以來/dev/sdb1,我認為寫信/dev/sdc1將是一個很好的測試,看看它是否完全複製,以及它是否會檢測到變化。

讀取文件時,沒有發生錯誤,並且更改的位仍然存在sdc1(它不存在於sdb1)。直到解除安裝sdb1和安裝sdc1,然後讀取文件,才能糾正錯誤。

如何在無需解除安裝的情況下定期驗證兩個磁碟上的校驗和(例如每週,使用 cron)?

如果你想複製這種情況,這就是我所做的:

$ mount /dev/sdb1 /mnt && cd /mnt
$ yes | head -100 > yes
$ filefrag -e yes # Look up in which sector the file is stored
$ echo x | dd of=/dev/sdc seek=$((offset*4096)) bs=1 count=1 # offset*sector_size

$ grep x yes # no results, no errors
$ dmesg | tail # nothing relevant
$ dd if=/dev/sdc skip=$((offset*4096)) bs=1 count=10 # To verify the x is actually there, and it is

$ # Mount sdc1 instead of sdb1
$ cd .. && umount mnt && mount /dev/sdc1 mnt
$ grep x yes # no results, no errors
$ dmesg | tail
[3695509.439534] BTRFS warning (device sdc1): csum failed ino 466 off 469331968 csum 444003100 expected csum 3637724482
[3695509.555018] BTRFS warning (device sdc1): csum failed ino 466 off 469331968 csum 444003100 expected csum 3637724482
[3695509.590762] BTRFS info (device sdc1): read error corrected: ino 466 off 469331968 (dev /dev/sdc1 sector 3692728)
# Finally, it was detected and silently corrected

我在核心版本 4.9 上。

btrfs scrub填補了這個角色:

btrfs scrub 用於清理 btrfs 文件系統,它將從所有設備讀取所有數​​據和元數據塊並驗證校驗和。如果有正確的副本可用,則自動修復損壞的塊。

它僅對諸如您的 btrfs RAID 設置(或DUP可能的設置)有用,因為它需要另一個副本來糾正。通常建議在計時器上將其作為服務執行。手冊頁建議每個月作為預設設置,但可以更頻繁地執行。

引用自:https://unix.stackexchange.com/questions/360120