
Я создалпять разделов жесткого диска по 1 ТБ( /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 инодов. Признаю свою халатность.
Ожидалось, что команда 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
Дельтик, вы неправильно поняли, как md
работает программный RAID Linux ( ).
md
создает виртуальное блочное устройство из нескольких устройств или разделов и не имеет представления о том, какие данные вы передаете на виртуальное устройство и с него.
Вы надеялись, что он сможет делать то, для чего не был предназначен.
Ответы
md
1. Почему неотвечающий диск/раздел не выходит из строя?
Это потому, что md
он понятия не имеет,
- диск занят вводом-выводом от чего-то, что
md
само запросило или - диск был заблокирован из-за каких-то внешних обстоятельств, таких как восстановление после собственной ошибки диска или, в вашем случае, ATA Secure Erase,
поэтому md
подождем, что вернет диск. Диск в конечном итоге не вернул никаких ошибок чтения или записи. Если бы была ошибка чтения, md
она бы автоматически исправилась из четности, а если бы была ошибка записи, md
устройство бы вышло из строя (см. раздел «Восстановление»md
страница руководства).
Поскольку не было ни ошибки чтения, ни ошибки записи, md
продолжил использование устройства после того, как ядро дождалось ответа.
2. Могу ли я удалить диск/раздел из массива, пока диск заблокирован?
Нет. /dev/md0
Устройство RAID заблокировано и не может быть изменено, пока блокировка не будет снята.
Вы передали флаг -f
or --fail
в mdadm
режим "Manage".
Вот пошаговое руководство того, что это на самом деле делает:
Это исходный код того, как работает этот флаг.:
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;
Обратите внимание, что вызов 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;
}
Если вы проследите за функциями, то обнаружите, что mdadm /dev/md0 -f /dev/sdb1
по сути это делает следующее:
echo "faulty" > /sys/block/md0/md/dev-sdb1/block/dev
Этот запрос будет ожидать обработки и не будет выполнен немедленно, поскольку /dev/md0
заблокирован.
3. Можно ли настроить тайм-аут так, чтобы md
автоматически отключать диск, не отвечающий на команды ATA?
Да. На самом деле,по умолчанию тайм-аут составляет 30 секунд:
root@node51 [~]# cat /sys/block/sdb/device/timeout
30
Проблема с вашим предположением заключалась в том, что ваш диск на самом деле был занят выполнением команды ATA (в течение 188 минут), поэтому тайм-аут не истек.
Подробную информацию об этом см.Документация по обработке ошибок SCSI ядра Linux.
4. Почему я md
продолжаю использовать устройство с недействительными данными?
После завершения ATA Secure Erase накопитель не сообщил о каких-либо проблемах, например о прерванной команде, поэтому md
не было причин подозревать наличие какой-либо проблемы.
Более того, в вашем случае использования разделов в качестве устройств RAID вместо целых дисков таблица разделов в памяти ядра не была проинформирована о том, что раздел на очищенном диске исчез, поэтому она md
продолжала бы обращаться к нему /dev/sdb1
, как будто ничего не произошло.
Это изmd
страница руководства:
Очистка и несоответствия
Поскольку устройства хранения данных могут в любой момент вырабатывать плохие блоки, важно регулярно считывать все блоки на всех устройствах в массиве, чтобы обнаружить такие плохие блоки на ранней стадии. Этот процесс называетсячистка.
Массивы md можно очистить, записав либопроверятьилиремонтк файлуmd/sync_actionвsysfsкаталог для устройства.
Запрос очистки заставит md прочитать каждый блок на каждом устройстве в массиве и проверить согласованность данных. Для RAID1 и RAID10 это означает проверку идентичности копий. Для RAID4, RAID5, RAID6 это означает проверку правильности блока четности (или блоков).
Из этого можно сделать вывод, что четность обычно не проверяется при каждом чтении с диска. (Кроме того, проверка четности при каждом чтении сильно повлияла бы на производительность, поскольку увеличилось бы число транзакций, необходимых только для завершения чтения, и выполнялось бы сравнение четности с прочитанными данными.)
При нормальной работе md
просто предполагает, что считываемые данные являются действительными, что делает его уязвимым длямолчаливое повреждение данных. В вашем случае у вас был целый диск с молчаливо поврежденными данными, потому что вы стерли диск.
Ваша файловая система не знала о повреждении. Вы увидели ошибки ввода/вывода на уровне файловой системы, потому что файловая система не могла понять, почему у нее были плохие данные.
Чтобы избежать скрытого повреждения данных, во-первых,никогда больше не делай того, что ты сделалВо-вторых, рассмотрите возможность использованияЗФС, файловая система, которая фокусируется на целостности данных, а также обнаруживает и исправляет скрытые повреждения данных.