2013-07-09 01:27:18

Перенос программного RAID в Ubuntu Linux

Linux RAID

Become root. If you're root, you should know what to do.

Когда-то я собрал программный RAID на основе Silicon Image 3132 (тык и крутим до соответствующего заголовка), по прошествии времени появилась необходимость запустить этот же самый RAID-1, но на встроенном SATA-контроллере без поддержки RAID, т.е. перенести массив в новые полностью софтовые условия.

Изначально все выглядело просто: переткнул харды и на новой системе сказал, что они продолжают быть массивом. Но на деле все оказалось не так просто. Диски были подхвачены Device Mapper и появились как /dev/mapper/sil_***. dmraid признал, что они принадлежали к какому-то массиву, но собрать их обратно в массив при помощи mdadm не получалось и по отдельности они были не доступны для чтения информации - fdisk показывал неверную таблицу разделов.


После копания в гугле, было принято решение снести с них информацию о принадлежности к RAID и попробовать все собрать заново. Для этого начинаем с чистки меты. (диски для RAID у меня появились как /dev/sda и /dev/sdb)

 dmraid -r -E /dev/sda
 dmraid -r -E /dev/sdb 

После перезагрузки стало возможным монтировать /dev/sda1 и /dev/sdb1, данные на них оказались целы и с виду идентичны.

Теперь нужно сделать из этих дисков массив, но в текущем состоянии mdadm при создании массива обещал затереть какие-то данные и продолжать было нельзя.

Решить эту ситуацию помогла смена типа раздела через fdisk. Для начала

fdisk -l /dev/sda

и видим тип раздела

83 Linux 

теперь этот раздел нужно сделать raid-пригодным, для это нужно поменять его тип на fd - Автоопределение Linux raid. Для этого запускаем

fdisk /dev/sda

жмем t и вводим fd (попутно можно нажимать m для получения справки о кнопках). Нажимаем w и изменения записаны на диск. Аналогично поступаем с /dev/sdb. Подробности по этой щекотливой операции можно посмотреть в мане и гугле.

Теперь команда

mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sda1 /dev/sdb1

проходит без страшных предупреждений о потере данных, наоборот видит что на дисках есть ext2 (хотя в реальности там ext4). Массив успешно создается и наступает долгий мучительный процесс синхронизации массива. У меня он обещал длиться больше 120 мнут. Посмотреть текущее состояние синхронизации можно командой

watch cat /proc/mdstat

До завершения синхронизации массив не доступен, хоть команда

mdadm --detail /dev/md0

говорит, что все хорошо, mount не может смонтировать /dev/md0 по причине неизвестной файловой системы.

Моей ошибкой было заниматься созданием массива на ночь глядя, на часах 2 ночи, а процесс все идет, выключать страшно т.к. не понятно к чему это может привести. Для того чтоб скоротать время сижу пишу этот пост. Самое обидное будет, если после синхронизации ситуация с доступностью массива не изменится, что-то похожее было на  Silicon Image 3132, тогда назначая в массив размеченные диски с ними невозможно было работать, требовалось создать сначала новую файловую систему. Тогда диски были без данных и создать новую файловую систему на массиве не было проблемой, сейчас ситуация совсем другая.

Итак процесс синхронизации закончен, перезагрузка и... массив стал теперь /dev/md127 но также как и раньше получить доступ к данным не удалось. Придется пойти другим путем и попробовать собрать RAID-1 из одного диска, копировать на него данные со второго и добавить второй к массиву и снова синхронизировать. На этой печальной ноте разбираем массив

mdadm -S /dev/md0

Снова пытаемся монтировать диски /dev/sda1 и /dev/sdb1 и снова не получается, теперь придется заново пробовать вытащить данные, работать будем с каждым диском по очереди тк есть опасность потерять данные от того что нет точного решения как это сделать.

Epic fail

Не повторяйте моих ошибок и не делайте описанное далее. Первый неверный шаг - сменить тип раздела через fdisk с fd (Linux raid autodetect) на 83 (Linux). После этого данные остались не доступны, mount не мог монтировать раздел.

Второй неверный шаг - затереть superblock

mdadm --zero-superblock /dev/sda1 

после этого разел не стал доступнее. И последний неверный шаг - это утилита testdisk в таком состоянии находит раздел, находит и перезаписывает таблицу разделов, но mount до сих пор не хочет монтировать. И под занавес по предложению testdisk запуск fsck который окончательно угробил данные.

А вот теперь так как надо

Запускаем testdisk и на не тронутом втором диске находим разделы перезаписываем файловую таблицу, в итоге получается два раздела и первый содержит данные и нормально монтируется. В моем случае mount не сразу после записи таблицы смог монтировать диск, а спустя некоторое время (или перезагрузку).

Можно вздохнуть с облегчением, хотя бы одна копия данных уцелела и с ней можно работать. Теперь будем собирать raid массив по-другому.

Сборка RAID-1 из одного диска

Идея очень простая, собираем собираем массив из одного диска с отсутствующим вторым. Для этого используем запоротый /dev/sda, на котором сносим все что осталось и создаем новый раздел на весь объем при помощи fdisk. Следующим шагом собираем массив вот такой командой

mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sda1 missing 

Таким образом получается изначально сломанный, но вполне рабочий RAID массив. На нем создаем файловую систему

mkfs.ext4 /dev/md0 

Никаких дополнительных параметров для "улучшения производительности" не нужно, т.к. в RAID-1 они все равно не сыграют роли. Далее монтируем массив и копируем на него, то что удалось спасти со второго диска.

Небольшое отступление

Имея сломанный массив, после перезагрузки по-умолчанию система не захочет загрузиться, а перейдет в консоль восстановления RAID. Если вы работаете с компьютером через ssh и для того чтоб убедится, что все работает после создания сломанного RAID перезагрузитесь, то неприятным сюрпризом станет то, что доступ к машине потерян. Чтоб этого не произошло, нужно вписать параметр bootdegraded в команду загрузки ядра, тогда комп загрузится даже со сломанным массивом. Идем в /etc/default/grub и модифицируем GRUB_CMDLINE_LINUX_DEFAULT

GRUB_CMDLINE_LINUX_DEFAULT="bootdegraded" 

Если изначально там были какие-то другие параметры, а не "", то их затирать не стоит, а просто добавить bootdegraded в конец. Теперь обновляем конфигурацию GRUB:

sudo update-grub

и можно перезагружать, не боясь потерять комп из-за сломанного RAID.

Ну а теперь нужно добавить второй диск (с которого копировали) в массив и снова долго синхронизировать, чтоб данные были идентичны...

Добавляем второй жесткий диск в RAID1 

Начальная ситуация: у меня есть raid-1 массив /dev/md127 (название автоматически тк нет конфига для mdadm) собранный из одного диска /dev/sda1 и диск для добавления /dev/sdb1.

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

sfdisk -d /dev/sda | sfdisk -f /dev/sdb

и после этого добавляем диск

mdadm /dev/md127 --add /dev/sdb1 

Диск добавлен и теперь можно посмотреть состояние массива:

mdadm --detail /dev/md127

который должен вывести что-то вроде этого (жирным выделено интересное)

/dev/md/homeserver:0:
Version : 1.2
Creation Time : Tue Jul 9 22:47:28 2013
Raid Level : raid1
Array Size : 976630336 (931.39 GiB 1000.07 GB)
Used Dev Size : 976630336 (931.39 GiB 1000.07 GB)
Raid Devices : 2
Total Devices : 2

Persistence : Superblock is persistent

Update Time : Wed Jul 10 21:09:59 2013
State : clean, degraded, recovering
Active Devices : 1
Working Devices : 2

Failed Devices : 0
Spare Devices : 1

Rebuild Status : 0% complete

Name : homeserver:0 (local to host homeserver)
UUID : 05f76479:3db01146:f706784b:4a5fb8db
Events : 1660

Number Major Minor RaidDevice State
0 8 1 0 active sync /dev/sda1
2 8 17 1 spare rebuilding /dev/sdb1

Также командой cat /proc/mdstat можно посмотреть что сейчас происходит с массивом, а для наблюдения за процессом синхронизации вводим

watch -n 10 cat /proc/mdstat

И в живую видим прогресс. Вывод будет примерно таким:

Every 10,0s: cat /proc/mdstat

Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md127 : active raid1 sdb1[2] sda1[0]
976630336 blocks super 1.2 [2/1] [U_]
[====>................] recovery = 22.8% (223410880/976630336) finish=114.8min speed=109312K/sec

unused devices: <none>

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

Переносим /home на RAID

Конечно, можно было монтировать raid в любое место и использовать, но для меня самым удобным было использовать его как /home. Процесс не представляет из себя ничего сложного.

Сначала убираем имеющиеся на raid данные в одну папку чтоб потом их растащить куда надо. Далее копируем данные из текущего /home на raid (который смонтирован, например, как /media/raid). В силу того, что я копировал home на свежей системе, то он был почти пустой и копировал я его без выкрутасов, как предлагается во многих рецептах.

Далее вписываем в /etc/fstab новую точку монтирования для /home

UUID=05f76479-3db0-1146-f706-784b4a5fb8db /home ext4 nodev,nosuid 0 2

UUID взят из вывода команды

blkid /dev/md127

не путать с выводом из mdadm --detail --scan, который дает другой UUID.

После изменения fstab перезагружаемся и смотрим на результат, и если в /home есть данные с raid (которые выше были убраны в одну папку), то все хорошо :)

Несколько полезных ссылок, которые использовались в процессе