Сбой устройства в MD RAID, когда ATA перестает отвечать
Я создал пять разделов жесткого диска 1TB (/dev/sda1
, /dev/sdb1
, /dev/sdc1
, /dev/sde1
, а также /dev/sdf1
) в массиве RAID 6 называется /dev/md0
с помощью mdadm
на Ubuntu 14.04 LTS Trusty Tahr.
Команда sudo mdadm --detail /dev/md0
используется для отображения всех дисков в активной синхронизации.
Затем для тестирования я смоделировал длинную блокировку ввода-вывода на /dev/sdb
запустив эти команды в то время как /dev/sdb1
был все еще активен в массиве:
hdparm --user-master u --security-set-pass deltik /dev/sdb
hdparm --user-master u --security-erase-enhanced deltik /dev/sdb
ПРЕДУПРЕЖДЕНИЕ
НЕ ПОПРОБУЙТЕ ЭТО НА ДАННЫХ, КОТОРЫЕ ВЫ ЗАБЫВАЕТЕ
В результате этой операции 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>
Я старался 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]
ОБНОВЛЕНИЕ (21 июля 2015 г.): После того, как я ждал полных 188 минут, пока блок ввода-вывода будет очищен, удивление переросло в ужас, когда я увидел это md
лечили полностью заглушенным /dev/sdb
как будто это было полностью в такте.
я думал так md
по крайней мере, видел бы, что соотношение не соответствует, а затем упал бы /dev/sdb1
,
Запаниковав, я побежал mdadm /dev/md0 -f /dev/sdb1
снова, и поскольку блок ввода-вывода был снят, команда выполнена быстро.
Повреждение файловой системы уже происходило из-за ошибок ввода / вывода. Все еще паникуя, я сделал ленивый размонтирование раздела данных в массиве 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
Это все еще довольно шокирует меня, что md
не имеет двух линий защиты, которые я ожидал:
- Сбой устройства, когда оно блокируется
- Сбой устройства, когда данные, которые оно возвращает, являются мусором
Вопросы
- Почему не
md
сбой не отвечает диск / раздел? - Можно ли удалить диск / раздел из массива, пока диск заблокирован?
- Можно ли настроить тайм-аут так, чтобы
md
автоматически отказывает диск, который не отвечает на команды ATA? - Почему
md
продолжать использовать устройство с недействительными данными?
1 ответ
Deltik , you've misunderstood how Linux Software RAID ( md
) works.
md
makes a virtual block device out of multiple devices or partitions and has no awareness of what data you are transferring to and from the virtual device.
You hoped that it could do things that it wasn't designed to do.
ответы
1. Why doesn't md
сбой не отвечает диск / раздел?
Это потому что md
has no idea whether
- the drive is busy with I/O from something that
md
itself requested or - the drive was blocked due to some external circumstance like the drive's own error recovery or in your case an ATA Secure Erase,
так md
will wait to see what the drive returns. The drive eventually didn't return any read or write errors. If there was a read error, md
would have automatically fixed it from parity, and if there was a write error, md
would have failed the device (see the "Recovery" section of the md
справочная страница ).
Since there was neither a read error nor a write error, md
continued using the device after the kernel waited for it to respond.
2. Can I drop the drive/partition from the array while the drive is blocked?
№ /dev/md0
RAID device is blocked and can't be modified until the block is cleared.
You passed the -f
или же --fail
флаг к mdadm
"Manage" mode.
Here's a walkthrough of what that actually does:
This is the source code of how that flag works :
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;
Notice the call write(sysfd, "faulty", 6)
, sysfd
is a variable set earlier in the file: sysfd = sysfs_open(fd2devnm(fd), dname, "block/dev");
sysfs_open()
is a function from this file :
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;
}
If you follow the functions, you'll find that mdadm /dev/md0 -f /dev/sdb1
essentially does this:
echo "faulty" > /sys/block/md0/md/dev-sdb1/block/dev
This request will be waiting and won't go through immediately because /dev/md0
is blocked.
3. Can a timeout be configured so that md
автоматически отказывает диск, который не отвечает на команды ATA?
Да. In fact, by default, the timeout is 30 seconds :
root@node51 [~]# cat /sys/block/sdb/device/timeout
30
The problem with your assumption was that your drive was actually busy running an ATA command (for 188 minutes), so it wasn't timing out.
For details about this, see the Linux kernel SCSI error handling documentation .
4. Why does md
продолжать использовать устройство с недействительными данными?
When the ATA Secure Erase finished, the drive did not report any issues, like an aborted command, so md
had no reason to suspect that there was an issue.
Furthermore, in your case of using partitions as the RAID devices instead of whole disks, the kernel's in-memory partition table wasn't informed that the partition on the wiped drive was gone, so md
would continue to access your /dev/sdb1
like nothing was wrong.
Это из md
справочная страница :
Scrubbing and Mismatches
As storage devices can develop bad blocks at any time it is valuable to regularly read all blocks on all devices in an array so as to catch such bad blocks early. This process is called scrubbing .
md arrays can be scrubbed by writing either check or repair to the file md/sync_action in the sysfs directory for the device.
Запрос на очистку приведет к тому, что md прочитает каждый блок на каждом устройстве в массиве и проверит соответствие данных. Для RAID1 и RAID10 это означает, что копии идентичны. Для RAID4, RAID5, RAID6 это означает проверку правильности блока четности (или блоков).
We can infer from this that parity is not normally checked on every disk read. (Besides, checking parity on every read would be very taxing on performance by increasing the transactions necessary just to complete a read and running the comparison of the parity to the data read.)
Under normal operation, md
just assumes that the data it is reading are valid, leaving it vulnerable to silent data corruption . In your case, you had an entire drive of silently corrupted data because you wiped the drive.
Your filesystem wasn't aware of the corruption. You saw input/output errors at the filesystem level because the filesystem couldn't understand why it had bad data.
To avoid silent data corruption, first, don't ever do what you did again . Second, consider using ZFS , a filesystem that focuses on data integrity and detects and corrects silent data corruption.