当没有错误时,坏块是否会上升?

当没有错误时,坏块是否会上升?

在向阵列添加替换驱动器之前,我执行了此脚本以确保不需要将替换驱动器送回制造商:

date
badblocks -b 4096 -c 4096 /dev/sdd
date
hdparm -Tt /dev/sdd
date

大约 8 小时后,它的执行产生了这个输出,让我知道我可以保留该驱动器:

Thu Jan 28 20:07:54 CST 2021
Fri Jan 29 04:37:40 CST 2021
/dev/sdd:
 Timing cached reads:   34840 MB in  1.99 seconds = 17546.64 MB/sec
 Timing buffered disk reads: 728 MB in  3.01 seconds = 242.16 MB/sec
Fri Jan 29 04:37:40 CST 2021

尽管坏块正在运行,大约每小时一次我执行斯特拉斯看看它是如何运行的。每次执行它时,我都注意到系统调用的频率在下降。每次执行它时,我都会看到这种模式,这让我确信它正在取得进展(即查找值增加了 16M,即读取调用的大小):

lseek(3, 5929403678720, SEEK_SET)  = 5929403678720
read(3, "\0\0\0"..., 16777216)     = 16777216
lseek(3, 5929420455936, SEEK_SET)  = 5929420455936
read(3, "\0\0\0"..., 16777216)     = 16777216

我查看了top。最上面的是badblocks,占用了大约 3% 的核心,并且这台私有机器上没有其他进程在执行任何操作。阅读后,我决定阅读源代码(特别是test_ro函数)。没有发现任何问题,我问的是:

  1. 斜坡的来源可能是什么?坡道每次循环的迭代都比前一次迭代慢。
  2. badblocks我是否可以仅通过从最后已知的偏移量重新启动来解决这个问题?
  3. 坏块是只在执行结束时显示还是一遇到就会显示?手册页没有说清楚。

我正在使用 e2fsprogs Version: 1.42.13-1ubuntu1.2,它是包含的包badblocks

更新 1

因为我不得不更换两个驱动器,所以我决定收集更多信息。我首先想确保strace会报告睡眠调用,因此我跟踪了以下执行:

#include <stdio.h>
#include <unistd.h>
#include <time.h>
int main (int argc, char *argv[]) {
   sleep(3);
   usleep(5123456);
   struct timespec req = {7,123456789};
   struct timespec rem = {0,0};
   nanosleep(&req, &rem);
}

我看到了这一点,这向我证明了坡度不是由test_ro执行睡眠调用引起的(因为一些坏块的执行包括睡眠调用,但我从未看到任何证据表明坏块执行了它们):

nanosleep({3, 0}, 0x7ffff1cbaa60)       = 0
nanosleep({5, 123456000}, NULL)         = 0
nanosleep({7, 123456789}, 0x7ffff1cbaab0) = 0

以下是自动定期收集系统调用计数的修改后的脚本:

date
badblocks -b 4096 -c 4096 $dev -o bad.out &
bp=$!

while [ -e /proc/$bp ]; do
    date
    strace -c -p $bp &
    sp=$!
    sleep 5
    kill $sp
    sleep 300
done
date
echo waiting
wait
date
hdparm -Tt $dev
date

然后我用 执行了脚本nohup sh check >check.out 2>&1 &

以下是 1-11 行check.out

nohup: ignoring input
Fri Jan 29 17:57:35 CST 2021
Fri Jan 29 17:57:35 CST 2021
strace: Process 3404 attached
strace: Process 3404 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 99.84    0.156000        2137        73           read
  0.16    0.000248           3        74           lseek
------ ----------- ----------- --------- --------- ----------------
100.00    0.156248                   147           total

以下是来自同一文件的第 903 至 919 行:

Sat Jan 30 02:25:55 CST 2021
strace: Process 3404 attached
strace: Process 3404 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.072000        2118        34           read
  0.00    0.000000           0        35           lseek
------ ----------- ----------- --------- --------- ----------------
100.00    0.072000                    69           total
Sat Jan 30 02:31:00 CST 2021
waiting
Sat Jan 30 02:31:00 CST 2021

/dev/sdd:
 Timing cached reads:   34034 MB in  1.99 seconds = 17137.69 MB/sec
 Timing buffered disk reads: 730 MB in  3.00 seconds = 242.94 MB/sec
Sat Jan 30 02:31:13 CST 2021

当然,bad.out是空的。

我用 过滤了 101 个read计数grep read\$ check.out| awk '{print $4}'

然后我将读取计数粘贴到 Excel 中以生成以下散点图:

在此处输入图片描述

更新 2

然后我使用以下命令绘制了 usecs/call 的 strace 输出grep read\$ check.out| awk '{print $3}'

在此处输入图片描述

但是,strace 不会打印最大和最小持续时间(尽管它可以)。计数较低但平均持续时间不较低这一事实一定意味着持续时间确实在增加。这听起来像是一个线索。

然后我显示了不同的 lseek 持续时间:

# grep lseek\$ check.out| awk '{print $3}' | sort | uniq -c
     44 0
      3 1
     24 2
     13 3
     10 4
      4 5
      2 6
      1 8

我预计这些 lseek 持续时间是因为搜索没有移动头部,因为代码正在寻找读取留下的相同位置。

出于完整性考虑,这里是它们的散点图(整个图均为零),创建自grep lseek\$ check.out| awk '{print $3}'

在此处输入图片描述

答案1

大多数 HDD 在开始处提供的吞吐量比结束处更高。这是因为 HDD 的开始处(扇区编号较低)通常靠近盘片的边缘。

如果您曾经玩过旋转木马,您就会理解这个概念。与站在中心相比,站在外边缘的速度要快得多。您会发现大多数硬盘,无论大小,都表现出类似的性能特征(靠近外端的速度较快,靠近内端的速度较慢)。

更快的线速度意味着单位时间内有更多的数据通过读/写头。[…]

(来源:多分区驱动器的优点

手册hdparm证实了这一点并提供了一种测试方法:

--offset
执行设备读取计时时,偏移量为给定的 GiB 数 (1024*1024*1024) -t。许多机械驱动器的速度会发生变化(大约两次)。通常最大值在开始时,但并非总是如此。无论偏移量如何,固态驱动器 (SSD) 都应显示类似的计时。

重新启动badblocks不会改变此行为。


坏块是否只在执行结束时显示,还是一遇到坏块就会显示?

一旦遇到它们(至少在你使用的模式下;我有已测试)。我的建议是使用badblocks-vs -o output_file感谢 ,-s您将看到没有 的进度strace。您可以tail -f output_fileless +F output_file在另一个控制台中。

相关内容