Я хочу создать NAS, используя mdadm для RAID и btrfs для обнаружения битров. У меня довольно простая настройка, объединяющая 3 диска по 1 ТБ с mdadm в RAID5, чем btrfs.

Я знаю, что mdadm не может восстановить bitrot. Он может только сказать мне, когда есть несоответствия, но не знает, какие данные верны, а какие нет. Когда я говорю mdadm восстановить мой md0 после того, как я симулирую bitrot, он всегда восстанавливает четность. Btrfs использует контрольные суммы, поэтому он знает, какие данные являются ошибочными, но он не может восстановить данные, так как он не может видеть четность.

Однако я могу запустить скраб btrfs и прочитать системный журнал, чтобы получить смещение данных, не соответствующих его контрольной сумме. Затем я могу перевести это смещение на диск и смещение на этом диске, потому что я знаю, что начальное смещение данных равно md0 (2048 * 512), размеру куска (512K) и макету (симметрично слева). Расположение означает, что в моем первом слое четность находится на третьем диске, во втором слое на втором диске и в третьем слое на первом диске.

Объединяя все эти данные и еще несколько btrfs на основе знаний о формате диска, я могу точно рассчитать, какой кусок какого диска является неисправным. Однако я не могу найти способ заставить mdadm исправить этот конкретный кусок.

Я уже написал сценарий, который меняет четность и дефектный чанк с помощью команды dd, затем запускает восстановление с помощью mdadm и затем меняет их обратно, но это не очень хорошее решение, и я бы очень хотел, чтобы mdadm пометил этот сектор как плохой и не используйте это снова. Так как это начало гнить, шансы высоки, он сделает это снова.

Мой вопрос: есть ли способ сказать mdadm, чтобы он восстановил один чанк (который не является четным) и, возможно, даже пометил сектор диска как плохой? Может быть, создание ошибки чтения IO?

(И я знаю, что ZFS может делать все это самостоятельно, но я не хочу использовать память ECC)

Изменить: этот вопрос / ответ о том, как btrfs RAID6 нестабилен и как ZFS намного более стабильна / полезна. Это не относится к моему вопросу о том, как восстановить один известный дефектный кусок с помощью mdadm.

2 ответа2

1

Я не могу найти способ сказать mdadm исправить этот конкретный кусок.

Это происходит потому, что когда происходит молчаливое повреждение данных, у md недостаточно информации, чтобы узнать, какой блок молча поврежден.

Я предлагаю вам прочитать мой ответ на вопрос № 4 («Почему md продолжает использовать устройство с недействительными данными?") здесь, что объясняет это более подробно.

Что еще хуже для предложенного макета, если блок контроля четности страдает от повреждения данных без вывода сообщений, слой Btrfs выше не может его увидеть! Если диск с соответствующим блоком данных выходит из строя и вы пытаетесь заменить его, md будет использовать поврежденную четность и необратимо испортить ваши данные. Только когда этот диск выйдет из строя, Btrfs распознает повреждение, но вы уже потеряли данные.

Это потому, что md не читает из блоков четности, если массив не ухудшен.


Так есть ли способ заставить mdadm восстановить один чанк (который не является четным) и, возможно, даже пометить сектор диска как плохой? Может быть, создание ошибки чтения IO?

Для плохих секторов, которые сам жесткий диск определил, 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 over 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 inode.
-1

Я нашел способ создать ошибку чтения для mdadm.

С помощью dmsetup вы можете создавать логические устройства из таблиц.

Устройства создаются путем загрузки таблицы, в которой указана цель для каждого сектора (512 байт).

От: manpage

В этих таблицах вы можете указать смещения, которые должны возвращать ошибку ввода-вывода, например:

0 4096 linear /dev/sdb 0
4096 1 error
4097 2093055 linear /dev/sdb 4097

Это создает устройство (1 ГБ) с ошибкой по смещению 4096 * 512.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .