Я хочу построить NAS, используя mdadm для RAID и btrfs для обнаружения bitrot. У меня довольно простая установка, объединяющая 3 диска по 1 ТБ с mdadm в RAID5, а затем btrfs поверх этого.
Я знаю, что mdadm не может исправить bitrot. Он может только сказать мне, когда есть несоответствия, но он не знает, какие данные верны, а какие неисправны. Когда я говорю mdadm исправить мой md0 после того, как я симулирую bitrot, он всегда восстанавливает четность. Btrfs использует контрольные суммы, поэтому он знает, какие данные неисправны, но он не может исправить данные, так как не видит четность.
Однако я могу запустить btrfs scrap и прочитать syslog, чтобы получить смещение данных, которые не соответствуют своей контрольной сумме. Затем я могу перевести это смещение на диск и смещение на этом диске, поскольку я знаю начальное смещение данных md0 (2048 * 512), размер фрагмента (512 КБ) и макет (левосимметричный). Макет означает, что в моем первом слое четность находится на третьем диске, во втором слое на втором диске и в третьем слое на первом диске.
Объединив все эти данные и некоторые дополнительные знания btrfs о формате диска, я могу точно вычислить, какой именно фрагмент какого диска является неисправным. Однако я не могу найти способ указать mdadm исправить этот конкретный фрагмент.
Я уже написал скрипт, который меняет местами четность и неисправный кусок с помощью команды dd, затем запускает исправление с помощью mdadm, а затем меняет их обратно, но это не очень хорошее решение, и я бы очень хотел, чтобы mdadm пометил этот сектор как плохой и больше его не использовал. Поскольку он начал гнить, велики шансы, что он сделает это снова.
Мой вопрос:есть ли способ заставить mdadm восстановить один кусок (который не является четностью) и, возможно, даже пометить сектор диска как плохой? Может быть, создать ошибку чтения ввода-вывода?
(И я знаю, что ZFS может делать все это сама по себе, но я не хочу использовать память ECC)
Редактировать:этотвопрос / ответ о том, как btrfs RAID6 нестабилен и как ZFS гораздо более стабилен / удобен в использовании. Это не отвечает на мой вопрос о том, как восстановить один известный неисправный кусок с помощью mdadm.
решение1
Я не могу найти способ заставить mdadm исправить этот конкретный фрагмент.
Это происходит потому, что при скрытом повреждении данных у md недостаточно информации, чтобы определить, какой блок скрытно поврежден.
Я приглашаю вас прочитать моюответ на вопрос №4 («Почему md
продолжают использовать устройство с недействительными данными?») здесь, который объясняет это более подробно.
Чтобы усугубить ситуацию с предлагаемой вами компоновкой,Если блок четности страдает от скрытого повреждения данных, то расположенный выше уровень Btrfs не может этого увидеть! Когда диск с соответствующим блоком данных выходит из строя и вы пытаетесь заменить его, md будет использовать поврежденную четность и необратимо испортит ваши данные. Только когда этот диск выйдет из строя, Btrfs распознает повреждение, но вы уже потеряете данные.
Это связано с тем, что md не считывает данные из блоков четности, если только массив не деградировал.
Так есть ли способ сказать mdadm восстановить один кусок (который не является четностью) и, возможно, даже пометить сектор диска как плохой? Может быть, создать ошибку чтения ввода-вывода?
С поврежденными секторами, которые жесткий диск обнаружил самостоятельно, md может справиться легко, поскольку поврежденный сектор идентифицируется md.
Технически вы можете создать плохой сектор с помощью hdparm --make-bad-sector
, но как узнать, на каком диске блок затронут скрытым повреждением данных?
Рассмотрим этот упрощенный пример:
Формула четности:PARITY = DATA_1 + DATA_2
+--------+--------+--------+
| DATA_1 | DATA_2 | PARITY |
+--------+--------+--------+
| 1 | 1 | 2 | # OK
+--------+--------+--------+
Теперь давайте молча испортим каждый из блоков значением 3
:
+--------+--------+--------+
| DATA_1 | DATA_2 | PARITY |
+--------+--------+--------+
| 3 | 1 | 2 | # Integrity failed – Expected: PARITY = 4
| 1 | 3 | 2 | # Integrity failed – Expected: PARITY = 4
| 1 | 1 | 3 | # Integrity failed – Expected: PARITY = 2
+--------+--------+--------+
Если бы у вас не было первой таблицы, на которую можно было бы посмотреть, как бы вы узнали, какой блок был поврежден?
Вы не можете знать наверняка.
Вот почему Btrfs и ZFS оба используют блоки контрольной суммы. Это занимает немного больше места на диске, но эта дополнительная информация позволяет системе хранения данных выяснить, какой блок лежит.
ОтСтатья в блоге Джеффа Бонвика "RAID-Z":
Всякий раз, когда вы читаете блок RAID-Z, ZFS сравнивает его с контрольной суммой. Если диски данных не вернули правильный ответ, ZFS считывает четность, а затем выполняет комбинаторную реконструкцию, чтобы выяснить, какой диск вернул неверные данные.
Чтобы сделать это с Btrfs на md, вам придется пересчитывать каждый блок до тех пор, пока контрольная сумма в Btrfs не совпадет, что является трудоемким процессом, не имеющим простого интерфейса, доступного пользователю/скрипту.
Я знаю, что ZFS может делать все это сама по себе, но я не хочу использовать память ECC.
Ни ZFS, ни Btrfs через md не зависят от памяти ECC и даже не знают о ней. Память ECC обнаруживает только скрытые повреждения данных в памяти, поэтому она не зависит от системы хранения.
Я рекомендовал ZFS вместо Btrfs для RAID-5 и RAID-6 (аналогично ZFS RAID-Z и RAID-Z2 соответственно) ранее вBtrfs через mdadm raid6?иСбой устройства в md RAID, когда ATA перестает отвечать, но я хотел бы воспользоваться этой возможностью, чтобы описать еще несколько преимуществ ZFS:
- Когда ZFS обнаруживает скрытое повреждение данных, оно автоматически и немедленно исправляется на месте без какого-либо вмешательства человека.
- Если вам необходимо перестроить весь диск, ZFS выполнит «перезапись» только реальных данных, вместо того чтобы без необходимости выполнять ее по всему блочному устройству.
- ZFS — это комплексное решение для логических томов и файловых систем, что упрощает управление им по сравнению с Btrfs поверх md.
- RAID-Z и RAID-Z2 надежны и стабильны, в отличие от
- Btrfs на md RAID-5/RAID-6, которая обеспечивает обнаружение ошибок только в скрытых поврежденных блоках данных (плюс скрытые поврежденные блоки четности могут оставаться необнаруженными, пока не станет слишком поздно) и не имеет простого способа исправления ошибок, и
- Btrfs RAID-5/RAID-6, который "имеет несколько серьезных ошибок, приводящих к потере данных".
- Если бы я незаметно испортил весь диск с ZFS RAID-Z2, я бы вообще не потерял никаких данных, тогда как на md RAID-6,На самом деле я потерял 455 681 инодов.
решение2
Я нашел способ создать ошибку чтения для mdadm.
С помощью dmsetup вы можете создавать логические устройства из таблиц.
Устройства создаются путем загрузки таблицы, которая определяет цель для каждого сектора (512 байт)
В этих таблицах вы можете указать смещения, которые должны возвращать ошибку ввода-вывода, например:
0 4096 linear /dev/sdb 0
4096 1 error
4097 2093055 linear /dev/sdb 4097
Это создает устройство (1 ГБ) с ошибкой по смещению 4096*512.