如何监控 BTRFS 文件系统突袭是否有错误?

Ioa*_*oan 13 linux raid events btrfs

我看到了一些关于可以为各种 BTRFS 事件执行程序/脚本的守护进程的文档,但我找不到了。

如何在 BTRFS raid1 阵列的驱动器故障时执行脚本/程序?我想对任何错误运行一个脚本,作为潜在故障驱动器的早期警告,但实际驱动器故障是最重要的。我想在那时卸载文件系统(如果这不是 BTRFS 所做的)并设置警报。

bas*_*ic6 20

除了常规的日志系统,BTRFS 确实有一个stats命令,它跟踪每个驱动器的错误(包括读、写和损坏/校验和错误):

# btrfs device stats /
[/dev/mapper/luks-123].write_io_errs   0
[/dev/mapper/luks-123].read_io_errs    0
[/dev/mapper/luks-123].flush_io_errs   0
[/dev/mapper/luks-123].corruption_errs 0
[/dev/mapper/luks-123].generation_errs 0
Run Code Online (Sandbox Code Playgroud)

所以你可以创建一个简单的 root cronjob:

MAILTO=admin@myserver.com
@hourly /sbin/btrfs device stats /data | grep -vE ' 0$'
Run Code Online (Sandbox Code Playgroud)

这将每小时检查一次正错误计数并向您发送电子邮件。显然,您将测试此类场景(例如通过导致损坏或删除 grep)以验证电子邮件通知是否有效。

此外,对于像 BTRFS(具有校验和)这样的高级文件系统,通常建议每两周安排一次清理,以检测由坏驱动器引起的静默损坏。

@monthly /sbin/btrfs scrub start -Bq /data
Run Code Online (Sandbox Code Playgroud)

-B选项会将擦除保留在前台,以便您可以在 cron 发送给您的电子邮件中看到结果。否则,它将在后台运行,您必须记住手动检查结果,因为它们不会出现在电子邮件中。

更新:按照 Michael Kjörling 的建议改进了 grep,谢谢。

更新 2:关于清理与常规读取操作的附加说明(这不仅适用于 BTRFS):
正如 Ioan 所指出的,根据阵列的大小和类型(以及其他因素),清理可能需要很多小时,在某些情况下甚至超过一天。而且它是一个主动扫描,它不会检测到未来的错误 - 清理的目标是在那个时间点找到并修复驱动器上的错误。但与其他 RAID 系统一样,建议安排定期清理。确实,典型的 I/O 操作(例如读取文件)确实会检查读取的数据是否确实正确。但是考虑一个简单的镜像——如果文件的第一个副本被损坏,可能是被一个即将死亡的驱动器损坏,但是第二个副本,这是正确的,实际上是由 BTRFS 读取的,那么 BTRFS 不会知道有损坏在其中一个驱动器上。这仅仅是因为已收到请求的数据,这意味着,即使您专门读取了某个驱动器上已知已损坏的文件,也不能保证此读取操作会检测到损坏。
现在,让我们假设 BTRFS 只从好的驱动器读取,没有运行会检测坏驱动器损坏的清理,然后好的驱动器也会变坏 - 结果将是数据丢失(至少 BTRFS 会知道哪些文件仍然正确,并且仍然允许您阅读这些文件)。当然,这是一个简化的例子;实际上,BTRFS 不会总是从一个驱动器读取数据而忽略另一个驱动器。
但关键是定期清理很重要,因为它们会发现(并修复)常规读取操作不一定会检测到的错误。

有故障的驱动器:由于这个问题非常流行,我想指出这个“监控解决方案”用于检测可能有坏驱动器的问题(例如,死驱动器导致错误但仍可访问)。

另一方面,如果一个驱动器突然消失(断开连接或完全死了,而不是死亡并产生错误),它将是一个有故障的驱动器(ZFS 会将这样的驱动器标记为 FAULTED)。不幸的是,正如 09/2015 的邮件列表条目所指出的那样,BTRFS 可能没有意识到在挂载文件系统时驱动器消失了(这可能已被修补):

不同之处在于我们有代码来检测挂载时不存在的设备,我们还没有代码来检测它是否挂在已挂载的文件系统上。为什么对设备消失进行正确检测似乎不是优先事项,我不知道,但这是与挂载行为不同的问题。

https://www.mail-archive.com/linux-btrfs@vger.kernel.org/msg46598.html

到那时 dmesg 中会有大量错误消息,因此 grepping dmesg 可能不可靠。
对于使用 BTRFS 的服务器,如果 RAID 阵列中的至少一个驱动器已消失,即不再可访问,则有一个自定义检查(cron 作业)发送警报可能是一个想法......

  • 像`grep -vE ' 0$'` 这样的东西不是更好吗? (2认同)

小智 8

从 btrfs-progs v4.11.1 开始,stats 具有 --check 选项,如果任何值不为零,该选项将返回非零值,从而不再需要正则表达式。

设备统计信息 -c /


Ioa*_*oan 2

似乎没有守护程序或实用程序正式报告 BTRFS 事件以供用户处理。最接近的替代方案是监视系统日志中是否有来自 BTRFS 的消息并做出相应反应。

http://marc.merlins.org/perso/btrfs/post_2014-03-19_Btrfs-Tips_-Btrfs-Scrub-and-Btrfs-Filesystem-Repair.html

上面的链接提供了配置用于通用日志监控的脚本(secDebian 或SEC上的软件包)的更多详细信息,以对有关 BTRFS 的意外日志消息采取行动。它还依赖于定期对文件系统进行清理,以检查位腐烂并发出日志条目作为先发制人的措施。以下是 SEC 脚本的具体摘录:

如何配置 sec、事件相关器来报告 btrfs 文件系统错误或警告

安装 sec.pl(在 debian 上使用 apt-get install sec 或http://simple-evcorr.sourceforge.net/)后,安装下面的 2 个配置文件。

这并不是万无一失的,它依赖于已知消息的正则表达式,并报告所有未知消息。您可以根据需要扩展前瞻性负正则表达式。

polgara:~\# cat /etc/default/sec  
\#Defaults for sec  
RUN_DAEMON="yes"  
DAEMON_ARGS="-conf=/etc/sec.conf -input=/var/log/syslog -pid=/var/run/sec.pid -detach -log=/var/log/sec.log"

polgara:~# cat /etc/sec.conf  
\# http://simple-evcorr.sourceforge.net/man.html  
\# http://sixshooter.v6.thrupoint.net/SEC-examples/article.html  
\# http://sixshooter.v6.thrupoint.net/SEC-examples/article-part2.html  
type=SingleWithSuppress  
ptype=RegExp  
pattern=(?i)kernel.*btrfs: (?!disk space caching is enabled|use ssd allocation|use .* compression|unlinked .* orphans|turning on discard|device label .* devid .* transid|detected SSD devices, enabling SSD mode|has skinny extents|device label|creating UUID tree|checking UUID tree|setting .* feature flag|bdev.* flush 0, corrupt 0, gen 0)  
window=60  
desc=Btrfs unexpected log  
action=pipe '%t: $0' /usr/bin/mail -s "sec: %s" root
Run Code Online (Sandbox Code Playgroud)