Del*_*tik 6 linux raid io mdadm raid6
我已经创造5个1TB HDD分区(/dev/sda1,/dev/sdb1,/dev/sdc1,/dev/sde1,和/dev/sdf1在a)中RAID 6阵列称为/dev/md0使用mdadm在Ubuntu 14.04 LTS可信赖的塔尔羊。
命令 sudomdadm --detail /dev/md0用于显示处于活动同步状态的所有驱动器。
然后,为了测试,我/dev/sdb通过/dev/sdb1在阵列中仍处于活动状态时运行这些命令来模拟长 I/O 阻塞:
hdparm --user-master u --security-set-pass deltik /dev/sdb
hdparm --user-master u --security-erase-enhanced deltik /dev/sdb
Run Code Online (Sandbox Code Playgroud)
警告
不要在你关心的数据上尝试这个!
由于此 ATA 操作,我最终损坏了 455681 个 inode。我承认我的疏忽。
用于安全擦除的 ATA 命令预计将运行 188 分钟,阻止所有其他命令至少那么长时间。
我md原本希望像一个合适的 RAID 控制器一样丢弃没有响应的驱动器,但令我惊讶的是,它/dev/md0也被阻塞了。
mdadm --detail /dev/md0 查询被阻止的设备,因此它会冻结并且不会输出。
这是/proc/mdstat我无法使用时的布局mdadm --detail /dev/md0:
root@node51 [~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4] [linear] [multipath] [raid0] [raid1] [raid10]
md0 : active raid6 sdf1[5] sda1[0] sdb1[4] sdc1[2] sde1[1]
2929887744 blocks super 1.2 level 6, 512k chunk, algorithm 2 [5/5] [UUUUU]
unused devices: <none>
Run Code Online (Sandbox Code Playgroud)
我试图mdadm /dev/md0 -f /dev/sdb1强行失败/dev/sdb1,但这也被阻止了:
root@node51 [~]# ps aux | awk '{if($8~"D"||$8=="STAT"){print $0}}'
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 3334 1.2 0.0 42564 1800 ? D 03:21 3:37 parted -l
root 4957 0.0 0.0 13272 900 ? D 06:19 0:00 mdadm /dev/md0 -f /dev/sdb1
root 5706 0.0 0.0 13388 1028 ? D 06:19 0:00 mdadm --detail /dev/md0
root 7541 0.5 0.0 0 0 ? D Jul19 6:12 [kworker/u16:2]
root 22420 0.0 0.0 11480 808 ? D 07:48 0:00 lsblk
root 22796 0.0 0.0 4424 360 pts/13 D+ 05:51 0:00 hdparm --user-master u --security-erase-enhanced deltik /dev/sdb
root 23312 0.0 0.0 4292 360 ? D 05:51 0:00 hdparm -I /dev/sdb
root 23594 0.1 0.0 0 0 ? D 06:11 0:07 [kworker/u16:1]
root 25205 0.0 0.0 17980 556 ? D 05:52 0:00 ls --color=auto
root 26008 0.0 0.0 13388 1032 pts/23 D+ 06:32 0:00 mdadm --detail /dev/md0
dtkms 29271 0.0 0.2 58336 10412 ? DN 05:55 0:00 python /usr/share/backintime/common/backintime.py --backup-job
root 32303 0.0 0.0 0 0 ? D 06:16 0:00 [kworker/u16:0]
Run Code Online (Sandbox Code Playgroud)
更新(2015 年 7 月 21 日):在我等待了整整 188 分钟以清除 I/O 块后,当我看到md将完全空白的部分视为完全完好时,我的惊讶变成了恐惧/dev/sdb。
我认为这md至少会看到奇偶校验不匹配,然后会下降/dev/sdb1。
惊慌失措,我又跑mdadm /dev/md0 -f /dev/sdb1了,因为 I/O 块已经解除,命令很快完成。
随着输入/输出错误的出现,文件系统损坏已经发生。仍然惊慌失措,我懒惰地卸载了 RAID 阵列中的数据分区,reboot -nf因为我认为它不会变得更糟。
在e2fsck分区上咬指甲后,455681 个 inode 使其成为lost+found.
我已经重新组装了数组,现在数组本身看起来很好:
root@node51 [~]# mdadm --detail /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Mon Feb 16 14:34:26 2015
Raid Level : raid6
Array Size : 2929887744 (2794.16 GiB 3000.21 GB)
Used Dev Size : 976629248 (931.39 GiB 1000.07 GB)
Raid Devices : 5
Total Devices : 5
Persistence : Superblock is persistent
Update Time : Tue Jul 21 00:00:30 2015
State : active
Active Devices : 5
Working Devices : 5
Failed Devices : 0
Spare Devices : 0
Layout : left-symmetric
Chunk Size : 512K
Name : box51:0
UUID : 6b8a654d:59deede9:c66bd472:0ceffc61
Events : 643541
Number Major Minor RaidDevice State
0 8 1 0 active sync /dev/sda1
1 8 97 1 active sync /dev/sdg1
2 8 33 2 active sync /dev/sdc1
6 8 17 3 active sync /dev/sdb1
5 8 113 4 active sync /dev/sdh1
Run Code Online (Sandbox Code Playgroud)
md没有我预期的两条保护线,这对我来说仍然很震惊:
md响应的驱动器/分区不会失败?md未响应 ATA 命令的驱动器自动发生故障?md继续使用数据无效的设备?Deltik,您误解了 Linux Software RAID ( md) 的工作原理。
md从多个设备或分区中创建虚拟块设备,并且不知道您正在向虚拟设备传输什么数据或从虚拟设备传输什么数据。
你希望它可以做一些它没有设计做的事情。
md响应的驱动器/分区不会出现故障?这是因为md不知道是否
md自身请求的 I/O 或因此md将等待查看驱动器返回的内容。驱动器最终没有返回任何读取或写入错误。如果存在读取错误,md则会自动从奇偶校验中修复它,如果存在写入错误,md则会导致设备故障(请参阅md手册页的“恢复”部分)。
由于既没有读取错误也没有写入错误,因此md在内核等待设备响应后继续使用该设备。
不可以/dev/md0。RAID 设备已被阻止,并且在该块被清除之前无法进行修改。
您将-f或--fail标志传递给mdadm“管理”模式。
以下是其实际作用的演练:
case 'f': /* set faulty */
/* FIXME check current member */
if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) ||
(sysfd < 0 && ioctl(fd, SET_DISK_FAULTY,
rdev))) {
if (errno == EBUSY)
busy = 1;
pr_err("set device faulty failed for %s: %s\n",
dv->devname, strerror(errno));
if (sysfd >= 0)
close(sysfd);
goto abort;
}
if (sysfd >= 0)
close(sysfd);
sysfd = -1;
count++;
if (verbose >= 0)
pr_err("set %s faulty in %s\n",
dv->devname, devname);
break;
Run Code Online (Sandbox Code Playgroud)
注意来电write(sysfd, "faulty", 6)。 sysfd是文件前面设置的变量:
sysfd = sysfs_open(fd2devnm(fd), dname, "block/dev");
sysfs_open()是该文件中的一个函数:
int sysfs_open(char *devnm, char *devname, char *attr)
{
char fname[50];
int fd;
sprintf(fname, "/sys/block/%s/md/", devnm);
if (devname) {
strcat(fname, devname);
strcat(fname, "/");
}
strcat(fname, attr);
fd = open(fname, O_RDWR);
if (fd < 0 && errno == EACCES)
fd = open(fname, O_RDONLY);
return fd;
}
Run Code Online (Sandbox Code Playgroud)
如果您遵循这些函数,您会发现它mdadm /dev/md0 -f /dev/sdb1基本上是这样做的:
echo "faulty" > /sys/block/md0/md/dev-sdb1/block/dev
Run Code Online (Sandbox Code Playgroud)
该请求将等待,并且不会立即通过,因为/dev/md0被阻止。
md自动使不响应 ATA 命令的驱动器出现故障?是的。事实上,默认情况下,超时时间是 30 秒:
root@node51 [~]# cat /sys/block/sdb/device/timeout
30
Run Code Online (Sandbox Code Playgroud)
您的假设的问题在于您的驱动器实际上正忙于运行 ATA 命令(持续 188 分钟),因此它没有超时。
有关详细信息,请参阅Linux 内核 SCSI 错误处理文档。
md继续使用数据无效的设备?当 ATA 安全擦除完成时,驱动器没有报告任何问题,例如中止的命令,因此md没有理由怀疑存在问题。
此外,在您使用分区作为 RAID 设备而不是整个磁盘的情况下,内核的内存分区表不会被告知已擦除驱动器上的分区已消失,因此将继续md访问您的分区,/dev/sdb1就像没有任何问题一样。
这是来自md手册页:
擦洗和不匹配
由于存储设备随时可能产生坏块,因此定期读取阵列中所有设备上的所有块以便及早捕获此类坏块非常有价值。这个过程称为擦洗。
可以通过将检查或修复写入设备sysfs目录中的文件md/sync_action来清理 md 数组。
请求清理将导致 md 读取阵列中每个设备上的每个块,并检查数据是否一致。对于 RAID1 和 RAID10,这意味着检查副本是否相同。对于 RAID4、RAID5、RAID6,这意味着检查奇偶校验块(或多个块)是否正确。
我们可以由此推断,奇偶校验通常不会在每次磁盘读取时进行检查。(此外,每次读取时检查奇偶校验都会增加完成读取所需的事务并运行奇偶校验与数据读取的比较,从而对性能造成很大的负担。)
在正常操作下,md只是假设它正在读取的数据是有效的,从而使其容易受到静默数据损坏的影响。就您而言,由于您擦除了驱动器,整个驱动器中的数据都已悄然损坏。
您的文件系统不知道损坏。您在文件系统级别看到输入/输出错误,因为文件系统无法理解为什么它有错误的数据。
为了避免静默数据损坏,首先,不要再做以前做过的事情。其次,考虑使用ZFS,这是一种专注于数据完整性并检测和纠正静默数据损坏的文件系统。
| 归档时间: |
|
| 查看次数: |
2049 次 |
| 最近记录: |