Новости

Как заменить диск в mdadm RAID 1 и не затереть рабочую копию

Дмитрий Потоцкий 3 мин чтения
Как заменить диск в mdadm RAID 1 и не затереть рабочую копию

Ты заменил отказавший /dev/nvme1n1. Linux увидел новый NVMe, но /proc/mdstat по-прежнему показывает [U_]. Ошибки нет: RAID 1 зеркалирует данные внутри разделов, а таблицу разделов не копирует. Новый накопитель нужно разметить по образцу исправного, а затем добавить его разделы в массив.

Самый опасный момент — копирование разметки. Перепутаешь источник и цель, и пустая таблица разделов окажется поверх единственной рабочей копии. Восстанавливать массив будет не из чего. Сначала зафиксируй устройства и серийные номера. Лишь потом меняй состав массива.

Инструкция рассчитана на программный RAID 1 под управлением mdadm. Без остановки сервера диск можно заменить только при поддержке hot-swap. Если сервер её не поддерживает, перед физической заменой накопителя придётся выключить питание (bmcservers.com, blog.beehosting.pro).

Найди отказавший диск и все его разделы

Не начинай с --fail или sgdisk. Сначала установи, из каких физических накопителей собран каждый /dev/mdX:

lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS,MODEL,SERIAL
cat /proc/mdstat
sudo mdadm --detail /dev/md0

lsblk покажет диски, разделы и собранные поверх них md-устройства. /proc/mdstat даст краткий статус массивов. В выводе mdadm --detail будут уровень RAID, количество активных участников и таблица устройств (arturogl.com, mundobytes.com).

У исправного RAID 1 статус [UU]. Значение [U_] или [_U] говорит, что одного участника нет либо mdadm пометил его неисправным.

Один физический накопитель часто входит сразу в несколько массивов:

md125: active raid1 sda2[0] sdb2[1]
md126: active raid1 sda3[0]

Здесь /dev/sdb2 участвует в /dev/md125, а /dev/sdb3 уже отсутствует в /dev/md126. Поэтому проверь каждый /dev/mdX, а не только массив с корневой файловой системой. mdadm собирает виртуальные устройства из отдельных разделов — /dev/sda1, /dev/sdb2 и других.

До первой изменяющей команды запиши соответствие устройств:

исправный диск: /dev/nvme0n1
отказавший диск: /dev/nvme1n1
/dev/md0: nvme0n1p1 + nvme1n1p1
/dev/md1: nvme0n1p2 + nvme1n1p2

Сверь серийные номера с наклейками на накопителях или с интерфейсом управления сервером. Одного имени /dev/sdX мало: после перезагрузки или переподключения прежний путь может достаться другому диску.

Удали отказавшие разделы из каждого массива

Если неисправный участник ещё числится активным, сначала пометь его как faulty. Затем удали:

sudo mdadm /dev/md0 --fail /dev/nvme1n1p1
sudo mdadm /dev/md0 --remove /dev/nvme1n1p1

sudo mdadm /dev/md1 --fail /dev/nvme1n1p2
sudo mdadm /dev/md1 --remove /dev/nvme1n1p2

Активный участник нельзя сразу удалить: mdadm требует сперва перевести его в faulty. Если раздел уже отказал или исчез, --fail может ответить, что устройство не найдено либо уже помечено неисправным. Тогда сразу выполняй --remove.

После каждой пары команд проверяй состояние массивов:

cat /proc/mdstat
sudo mdadm --detail /dev/md0
sudo mdadm --detail /dev/md1

Не вытаскивай накопитель, пока все его разделы не исчезнут из таблиц участников. Иначе можно физически отключить устройство, которое ещё обслуживает ввод-вывод.

Если hot-swap нет, выключи сервер и замени накопитель. После загрузки первым делом запусти lsblk. Новый диск должен появиться в системе до любых операций с массивом.

Скопируй GPT с исправного диска на новый

Перед копированием снова определи источник и цель:

lsblk -o NAME,SIZE,MODEL,SERIAL
sudo mdadm --detail /dev/md0
sudo gdisk -l /dev/nvme0n1

В следующих командах /dev/nvme0n1 — исправный источник с данными. /dev/nvme1n1 — пустой новый диск.

Сохрани резервную копию GPT исправного накопителя:

sudo sgdisk --backup=nvme0n1-gpt.bak /dev/nvme0n1

Теперь скопируй таблицу разделов:

sudo sgdisk -R=/dev/nvme1n1 /dev/nvme0n1
sudo sgdisk -G /dev/nvme1n1
sudo partprobe /dev/nvme1n1

Синтаксис sgdisk -R легко прочитать наоборот. Цель стоит сразу после -R=, источник — последним аргументом.

Команда sgdisk -G создаст новые GUID диска и разделов. Без неё в системе останутся две GPT с одинаковыми идентификаторами.

Перед Enter прочитай направление справа налево:

источник с данными: /dev/nvme0n1
 ↓ копирование
пустая замена: /dev/nvme1n1

После копирования сравни разметку:

lsblk /dev/nvme0n1
lsblk /dev/nvme1n1
sudo gdisk -l /dev/nvme1n1

Номера, размеры и типы разделов должны совпасть. Сам RAID 1 эту разметку не переносит.

Для MBR перенеси таблицу через sfdisk

Если gdisk не обнаружил GPT, сохрани MBR-разметку исправного диска:

sudo sfdisk --dump /dev/sda > parttable_mbr.bak

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

sudo sfdisk /dev/sdb < parttable_mbr.bak
sudo partprobe /dev/sdb

В этих командах /dev/sda — исправный источник, /dev/sdb — новый диск. MBR копируют через sfdisk, предварительно сохранив таблицу командой --dump.

Сравни обе таблицы:

sudo sfdisk --dump /dev/sda
sudo sfdisk --dump /dev/sdb

Идентификаторы дисков могут отличаться. Границы и типы разделов должны совпадать.

Добавь новые разделы и дождись [UU]

Добавь каждый раздел нового накопителя в соответствующий массив:

sudo mdadm --manage /dev/md0 --add /dev/nvme1n1p1
sudo mdadm --manage /dev/md1 --add /dev/nvme1n1p2

Сразу после --add начнётся rebuild. Наблюдай за ним через /proc/mdstat:

watch -n1 cat /proc/mdstat

Состояние каждого участника покажет mdadm --detail:

sudo mdadm --detail /dev/md0
sudo mdadm --detail /dev/md1

На сервере с двумя NVMe по 1 ТБ перестроение занимает примерно 20–60 минут. Время зависит от размера массива, скорости накопителей и текущей нагрузки (bmcservers.com, arturogl.com).

Во время rebuild не запускай бенчмарки, массовое перемещение файлов или тяжёлый VACUUM FULL. Массив непрерывно читает рабочий диск, чтобы собрать зеркало. Дополнительный ввод-вывод отнимет пропускную способность и растянет перестроение.

Работа закончена, когда /proc/mdstat показывает:

[UU]

При этом оба участника должны перейти в active sync в выводе mdadm --detail (blog.beehosting.pro, arturogl.com). Строка прогресса исчезла — ещё не значит, что всё готово. Проверь каждый массив отдельно.

Проверь массив после перестроения

Сначала проверь, что файловые системы смонтированы и читаются:

findmnt
df -hT
sudo mdadm --detail /dev/md0
cat /proc/mdstat

Затем проверь запись в служебном каталоге, где тестовый файл не заденет приложение:

test_dir=/путь/к/служебному/каталогу
test_file="$test_dir/.raid-write-test-$(date +%s)"
printf 'raid-write-test\n' | sudo tee "$test_file" >/dev/null
sudo cat "$test_file"
sudo rm -f "$test_file"

Файл создался, прочитался и удалился без ошибок — массив обслуживает чтение и запись после замены накопителя.

Вся операция помещается в две строки:

identify → fail → remove → replace → clone layout
→ regenerate GUID → add → wait for [UU]

Перед --fail, --remove, sgdisk -R и --add каждый раз сверяй устройство через lsblk и mdadm --detail. Это займёт 20 секунд. Перепутаешь source и target — потеряешь единственную рабочую копию.

После появления [UU] проверь отдельный бэкап. RAID 1 выдержит отказ одного диска, но послушно повторит удаление файла на обоих накопителях и не защитит от повреждения файловой системы. Если давно не проверял восстановление, пройди инструкцию о том, как проверить бэкап до аварии.