当没有错误时,坏块是否有斜坡?

Jef*_*olt 1 performance ubuntu bad-blocks

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

date
badblocks -b 4096 -c 4096 /dev/sdd
date
hdparm -Tt /dev/sdd
date
Run Code Online (Sandbox Code Playgroud)

大约 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
Run Code Online (Sandbox Code Playgroud)

badblocks运行时,我大约每小时执行一次strace来查看它的运行情况。每次执行它时,我都注意到系统调用的频率正在减少。每次我执行它时,我都会看到这种模式,这让我确信它正在取得进展(即,查找值增加了 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
Run Code Online (Sandbox Code Playgroud)

我在看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);
}
Run Code Online (Sandbox Code Playgroud)

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

nanosleep({3, 0}, 0x7ffff1cbaa60)       = 0
nanosleep({5, 123456000}, NULL)         = 0
nanosleep({7, 123456789}, 0x7ffff1cbaab0) = 0
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

我用 执行了脚本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
Run Code Online (Sandbox Code Playgroud)

以下是同一文件中的第 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
Run Code Online (Sandbox Code Playgroud)

当然,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
Run Code Online (Sandbox Code Playgroud)

这些 lseek 持续时间是我预期的,因为查找不会移动头部,因为代码正在查找读取留下的相同位置。

为了完整起见,这是他们的散点图(始终为零),创建自grep lseek\$ check.out| awk '{print $3}'

在此输入图像描述

Kam*_*ski 5

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

\n
\n

如果您曾经玩过旋转木马,您就会明白这个概念。与中心相比,站在外边缘你移动得更快。您会发现大多数硬盘驱动器,无论大小如何,都表现出相似的性能特征(在外端附近速度更快,在内端速度较慢)。

\n

更快的线速度意味着单位时间内更多的数据通过读/写磁头。[\xe2\x80\xa6]

\n
\n

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

\n

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

\n
\n

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

\n
\n

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

\n
\n
\n

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

\n
\n

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

\n