Восстановление данных с RAID5: когда два диска вышли из строя одновременно

Ситуация: RAID5 с двумя отказавшими дисками

Юридическая фирма «ПравоДок» обратилась к нам в пятницу вечером — классика жанра. Их файловый сервер на Ubuntu 20.04 с программным RAID5 из 4 дисков по 4 ТБ (mdadm) перестал отвечать. Первый диск начал сыпать ошибками неделю назад, но администратор не заметил предупреждений в логах. Второй диск отказал сегодня утром.

RAID5 выдерживает отказ одного диска. Два отказа — это катастрофа, при которой массив не может быть собран штатными средствами. На массиве хранились документы клиентов за 8 лет — договоры, судебные акты, переписка. Бэкапы делались... на тот же сервер, на отдельный раздел того же RAID.

Первичная диагностика:

# Состояние RAID-массива
sudo mdadm --detail /dev/md0

# Вывод (сокращённо):
# /dev/md0:
#         Version : 1.2
#   Creation Time : Wed Mar 15 2019
#      Raid Level : raid5
#      Array Size : 11720540160 (11.18 TiB)
#     Raid Devices : 4
#    Total Devices : 2
#          State : inactive
# Failed Devices : 2
#
#    Number   Major   Minor   RaidDevice State
#       -       0        0        0      removed
#       1       8       17        1      active sync   /dev/sdb1
#       -       0        0        2      removed
#       3       8       49        3      active sync   /dev/sdd1

Два диска (/dev/sda1 и /dev/sdc1) отсутствовали. Массив в состоянии inactive — данные недоступны.

Шаг 1: оценка состояния дисков

Прежде чем что-то делать, нужно понять, насколько повреждены отказавшие диски. Возможно, один из них ещё читаем.

# Проверяем SMART-статус всех дисков
for dev in sda sdb sdc sdd; do
  echo "=== /dev/$dev ==="
  sudo smartctl -H /dev/$dev
  sudo smartctl -A /dev/$dev | grep -E 'Reallocated|Current_Pending|Offline_Uncorrectable'
  echo
done

Результаты:

ДискSMART StatusReallocated SectorsPending SectorsОценка
/dev/sdaFAILED48211203Критический износ, частично читаем
/dev/sdbPASSED00Здоров
/dev/sdcFAILED124808901Тяжёлый случай, много bad blocks
/dev/sddPASSED30Здоров

Диск /dev/sda был повреждён, но большая часть секторов читалась. Диск /dev/sdc — значительно хуже, 8901 секторов в очереди на ремаппинг. Но для RAID5 нам достаточно восстановить данные хотя бы с одного из двух отказавших дисков.

Шаг 2: создание образов дисков с ddrescue

Критическое правило: никогда не работайте с оригинальными дисками. Каждая попытка чтения с повреждённого диска может ухудшить его состояние. Мы используем ddrescue — инструмент, который умеет обходить повреждённые сектора и возвращаться к ним позже.

Подключили внешний массив на 20 ТБ для хранения образов и начали копирование:

# Создаём образ первого повреждённого диска
# --no-scrape: не пытаться вычитывать побитые области при первом проходе
# -d: прямой доступ к диску (минуя кэш ядра)
# -r3: до 3 попыток чтения повреждённых секторов
sudo ddrescue -d --no-scrape /dev/sda1 /mnt/rescue/sda1.img /mnt/rescue/sda1.log

# Первый проход занял 6 часов для 4 ТБ
# Результат:
# rescued: 3998.71 GB, errsize: 1.29 GB, current rate: 0 B/s
# ipos: 2847.26 GB, errors: 4821, average rate: 184.8 MB/s
# opos: 2847.26 GB, run time: 6h 01m 12s
# successful read: 0s ago,  bad sector: 23m 45s ago

# Второй проход — попытка вычитать ошибочные области
sudo ddrescue -d -r3 /dev/sda1 /mnt/rescue/sda1.img /mnt/rescue/sda1.log

# Итого удалось спасти 99.97% данных с /dev/sda1

# Аналогично для /dev/sdc1
sudo ddrescue -d --no-scrape /dev/sdc1 /mnt/rescue/sdc1.img /mnt/rescue/sdc1.log
# Этот диск был хуже: 98.2% данных

# Здоровые диски тоже копируем — на всякий случай
sudo ddrescue -d /dev/sdb1 /mnt/rescue/sdb1.img /mnt/rescue/sdb1.log
sudo ddrescue -d /dev/sdd1 /mnt/rescue/sdd1.img /mnt/rescue/sdd1.log

Суммарно процесс копирования занял 18 часов. С этого момента оригинальные диски мы больше не трогали.

Шаг 3: анализ метаданных RAID и сборка массива

Имея образы, мы можем экспериментировать без риска. Подключаем образы как loop-устройства и пробуем собрать массив:

# Подключаем образы дисков как loop-устройства
sudo losetup /dev/loop0 /mnt/rescue/sda1.img
sudo losetup /dev/loop1 /mnt/rescue/sdb1.img
sudo losetup /dev/loop2 /mnt/rescue/sdc1.img
sudo losetup /dev/loop3 /mnt/rescue/sdd1.img

# Проверяем метаданные RAID на каждом образе
for i in 0 1 2 3; do
  echo "=== loop$i ==="
  sudo mdadm --examine /dev/loop$i
done

Метаданные mdadm показали порядок дисков, chunk size (512K), layout (left-symmetric) и UUID массива. Ключевой момент — Events counter: диски /dev/sdb1 и /dev/sdd1 имели одинаковый Events (145832), /dev/sda1 — 145830 (на 2 меньше), /dev/sdc1 — 145801 (на 31 меньше).

Это значит: /dev/sda1 отключился недавно и его данные почти актуальны. /dev/sdc1 выпал раньше и его данные устарели. Для сборки массива мы используем /dev/sda1 — лучший из двух повреждённых.

# Собираем массив из 3 дисков (один — повреждённый образ, один missing)
# ВАЖНО: --assume-clean — не пересчитывать parity, иначе потеряем данные
sudo mdadm --assemble /dev/md127 /dev/loop0 /dev/loop1 --force

# Если assemble отказывает, пробуем create с --assume-clean
sudo mdadm --create /dev/md127 --level=5 --raid-devices=4 \
  --chunk=512 \
  /dev/loop0 /dev/loop1 missing /dev/loop3 \
  --assume-clean

# Проверяем состояние
sudo mdadm --detail /dev/md127
# State : clean, degraded
# Это ожидаемо — один диск missing, но массив работает!

Шаг 4: восстановление файловой системы

Массив собран в degraded-режиме. Теперь проверяем файловую систему. На массиве был ext4.

# Сначала — только проверка, без исправлений
sudo e2fsck -n /dev/md127

# Результат:
# /dev/md127: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
# (i.e., without -a or -p options)
# 18 inodes/blocks would be fixed
# 3 orphaned inodes

# Запускаем полную проверку с исправлением
# -y: автоматически отвечать "yes" на все вопросы
sudo e2fsck -y -f /dev/md127

# Если бы была XFS:
# sudo xfs_repair /dev/md127
# При ошибке "dirty log":
# sudo xfs_repair -L /dev/md127  # ОПАСНО: теряем журнал

e2fsck исправил 18 повреждённых блоков и 3 осиротевших inode. Потеря — несколько файлов, последние по времени модификации. Файлы попали в lost+found.

Монтируем и проверяем данные:

# Монтируем в read-only для безопасности
sudo mount -o ro /dev/md127 /mnt/restored

# Проверяем структуру
ls -la /mnt/restored/
# drwxr-xr-x 12 root root 4096 Apr  3 14:22 .
# drwxr-xr-x  8 root root 4096 Apr  5 09:15 ..
# drwxr-xr-x 45 root root 4096 Mar 28 11:30 contracts/
# drwxr-xr-x 38 root root 4096 Apr  2 16:45 court_cases/
# drwxr-xr-x 22 root root 4096 Apr  1 09:12 correspondence/
# ...

# Считаем файлы
find /mnt/restored -type f | wc -l
# 847293

# Проверяем целостность случайной выборки файлов
for f in $(find /mnt/restored/contracts -name '*.pdf' | shuf | head -50); do
  if pdfinfo "$f" &>/dev/null; then
    echo "OK: $f"
  else
    echo "DAMAGED: $f"
  fi
done
# Результат: 49 из 50 OK, 1 повреждён

Шаг 5: спасение данных с нечитаемых областей

1.29 ГБ данных с /dev/sda не удалось прочитать через ddrescue. Эти области могут содержать важные файлы. Для восстановления используем carving — поиск файлов по сигнатурам, минуя файловую систему.

# photorec — восстановление файлов по сигнатурам
# Ищем PDF, DOCX, XLSX в повреждённых областях
sudo photorec /dev/loop0 /mnt/rescue/carved/

# testdisk — для восстановления структуры разделов и удалённых файлов
sudo testdisk /dev/loop0
# Интерактивный режим:
# 1. Analyse → Quick Search → список найденных разделов
# 2. Advanced → List (показывает файлы, включая удалённые)
# 3. Copy — копирование найденных файлов

# Альтернатива: foremost для целевого поиска конкретных типов
sudo foremost -t pdf,docx,xlsx -i /mnt/rescue/sda1.img -o /mnt/rescue/foremost_output/

photorec нашёл дополнительно 2 340 файлов, из которых 1 890 оказались уникальными (не дубликаты уже восстановленных). Основная проблема carving — файлы теряют имена и структуру каталогов. Юристы потратили два дня на сортировку, но все критичные документы были восстановлены.

Предотвращение: RAID6, мониторинг и правильные бэкапы

После восстановления мы полностью перестроили систему хранения «ПравоДок»:

1. RAID6 вместо RAID5:

# RAID6 выдерживает отказ ДВУХ дисков
sudo mdadm --create /dev/md0 --level=6 --raid-devices=6 \
  /dev/sda1 /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1 /dev/sdf1 \
  --chunk=256

# Добавляем hot spare — диск, который автоматически заменит отказавший
sudo mdadm --add-spare /dev/md0 /dev/sdg1

2. Мониторинг SMART и RAID через Prometheus + node_exporter:

# /etc/prometheus/alerts/raid.yml
groups:
  - name: raid_alerts
    rules:
      - alert: RAIDDegraded
        expr: node_md_disks_active < node_md_disks_required
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "RAID массив {{ $labels.device }} деградирован"

      - alert: DiskSMARTFailing
        expr: smartmon_device_smart_healthy == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Диск {{ $labels.disk }} SMART FAILED — замените немедленно"

      - alert: DiskReallocatedSectors
        expr: smartmon_reallocated_sector_ct_raw_value > 100
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Диск {{ $labels.disk }}: {{ $value }} reallocated секторов"

3. Правильные бэкапы — на отдельный сервер:

# Ежедневный бэкап через restic на S3-совместимое хранилище
#!/bin/bash
export RESTIC_REPOSITORY="s3:https://s3.storage.ru/pravodok-backup"
export RESTIC_PASSWORD_FILE="/etc/restic/password"
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..."

# Инкрементальный бэкап
restic backup /srv/documents \
  --exclude='*.tmp' \
  --exclude='.Trash*' \
  --tag daily

# Удаляем старые снэпшоты: 7 ежедневных, 4 еженедельных, 12 ежемесячных
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

# Проверяем целостность
restic check

Правило 3-2-1: три копии данных, на двух разных типах носителей, одна копия — off-site. Подробнее о стратегиях резервного копирования — на itfresh.ru.

Когда вызывать профессионалов

Наш кейс закончился успешно, но бывают ситуации, когда самостоятельное восстановление невозможно или рискованно:

  • Физическое повреждение дисков — головки чтения повреждены, диск издаёт щелчки или не раскручивается. Здесь нужна clean room (чистая комната) и замена механики. Стоимость: 15 000 — 80 000 ₽ за диск.
  • Аппаратный RAID-контроллер — при отказе контроллера нужен идентичный контроллер (той же модели, ревизии, прошивки) для импорта конфигурации. Некоторые контроллеры шифруют метаданные.
  • SSD с аппаратным шифрованием — если контроллер SSD вышел из строя, данные зашифрованы ключом, который хранился в этом контроллере. Восстановление возможно только в лаборатории.
  • Данные стоят дороже, чем услуги лаборатории — если на дисках финансовая отчётность, медицинские данные или уникальные документы, не экспериментируйте. Каждая неудачная попытка усложняет работу профессионалам.

Рекомендуемый порядок действий: (1) не паниковать, (2) не запускать rebuild без понимания ситуации, (3) сделать посекторные образы всех дисков, (4) работать только с образами, (5) если не уверены — остановитесь и обратитесь к специалистам.

Часто задаваемые вопросы

Можно, если хотя бы один из отказавших дисков частично читаем. С помощью ddrescue создаётся образ повреждённого диска (даже с пропущенными секторами), после чего массив собирается в degraded-режиме из трёх дисков. Если оба диска полностью мертвы — восстановление невозможно.
RAID6 использует две контрольные суммы вместо одной, выдерживая отказ двух дисков одновременно. При rebuild RAID5 массив работает без избыточности 12-24 часа, и если в это время откажет ещё один диск — данные потеряны. RAID6 защищает от этого сценария, что критично для массивов из больших дисков (4+ ТБ).
dd останавливается при первой ошибке чтения или пытается бесконечно читать повреждённый сектор. ddrescue обходит проблемные области, сначала копирует все читаемые данные, затем возвращается к повреждённым секторам с многократными попытками. Ведёт log-файл, позволяя прерывать и возобновлять копирование.
Настройте мониторинг: mdadm --monitor отправляет email при любом изменении состояния массива. Prometheus с node_exporter экспортирует метрику node_md_disks_active. Настройте алерт, если значение меньше node_md_disks_required. Также мониторьте SMART-атрибуты: Reallocated_Sector_Ct > 100 — повод для замены диска.
Data carving (photorec, foremost, testdisk) — восстановление файлов по их сигнатурам (magic bytes), минуя файловую систему. Применяйте, когда файловая система повреждена и fsck не помог, или для восстановления данных с нечитаемых областей RAID. Минус — файлы теряют имена и структуру каталогов.

Нужна помощь с проектом?

Специалисты АйТи Фреш помогут с архитектурой, DevOps, безопасностью и разработкой — 15+ лет опыта

📞 Связаться с нами
#RAID5#восстановление данных#mdadm#ddrescue#fsck#testdisk#photorec#RAID6
Комментарии 0

Оставить комментарий

загрузка...