avatar FAQ Изменение размера раздела Software RAID в Linux (mdadm resize)

В этот раз я вам расскажу о том, как увеличить размер раздела который находится на software raid массиве. В качестве примера мы расширим раздел находящийся на RAID 1 массиве.

Ситуация:
Сервер с двумя дисками на которых собран программный RAID 1, было создано 3 логических диска.
md0 с точкой минирования / -10 Gb -Находится операционная система
Раздел подкачки- по 512Mb на каждом диске, итого 1Gb
md1 /home- под него выделено все оставшееся место на диске там и находятся данные файлового сервера.

Переставим задачу, у нас есть файловый сервер, на котором установлено 2 жестких диска, размером 160Gb каждый, объединенных в программный RAID 1, место в разделе перестало хватать и нам требуется установить более емкие жесткие диски, например- 2х1TB. Конечно можно засунуть новые диски и переустановить операционную систему, но это не «тру» т.к. придется многое перенести: информацию, перенастроить SAMBA, права доступа к директориям, снова настраивать резервное копирование и прочие малоинтересные, но крайне необходимые вещи, которые до этого момента отлично работали.
В общем все это нужно тихонько перенести, ничего не потеряв по дороге, иначе «капут»…
Пару лет назад я уже писал статью по установке системы на программный RAID, с которой можно ознакомиться в статье Как установить Ubuntu 10.04 на RAID 5, статья до сих пор не потеряла актуальности, рекомендую к ознакомлению, многие действия перекочевали оттуда.

Сам метод применим не только к RAID1, но и к другим массивам имеющим отказоустойчивость и выдерживающим потерю как минимум одного диска, а именно RAID5, RAID6, RAID10. Пример с RAID 1 рассматриваться как наиболее простой и доступный для понимания, алгоритм был протестирован на массивах 5,6 и 10го уровней и отлично показал себя.

Есть вариант более правильный и простой, при кажущейся «геморройности» процедуры, а именно, следите за мыслью:
1) Убрать 1 старый жесткий диск
2) Установить 1 новый жесткий диск,
3) Перенести таблицу разделов на новый жесткий диск,
4) Расширить размер раздела на новом жестком диске, за счет оставшегося свободного места.
5) Синхронизировать содержимое старого диска с новым
6) Убрать старый диск
7) Установить второй- новый жесткий диск
8) Перенести таблицу разделов на второй новый жесткий диск
9) Синхронизировать содержимое дисков.
10) Расширить раздел RAID массива, за счет присоединения свободного места
Пользоваться!
В результате такого «переезда» информация останется на одном из дисков, который будет выключен, благодаря чему можно, с довольно высокой долей вероятности, говорить что инфа не пропадет, но наличие резервных копий никто не отменял!!!

В качестве тестового стенда, у меня будет система, которая состоит из 2х дисков по 20Gb.
В системе создано 2 устройства md
md0-Корневая файловая система
md1-Раздел /home (его мы и будем расширять)
В систему мы установим 2 диска по 160Gb.

Итого, нам требуется выполнить 10 действий.
Заходим в систему и поднимаем права до root
sudo su


Для начала определимся что у нас все в порядке с RAID массивом
cat /proc/mdstat

Нам вывалит «портянку» о стоянии массива в целом и дисков которые включены в него:
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4][raid10]
md0 : active raid1 sda1[0] sdb1[1]
      9756544 blocks super 1.2 [2/2] [UU]

md1 : active raid1 sda6[0] sdb6[1]
      10218368 blocks super 1.2 [2/2] [UU]

Из которой понятно что у нас все хорошо, но это мы скоро исправим.
После этого посмотрим что у нас со сводным местом:
root@ubuntu:~# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/md0        6.5G 1017M  5.1G  17% /
udev            494M  4.0K  494M   1% /dev
tmpfs           201M  316K  201M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            502M     0  502M   0% /run/shm
/dev/md1         13G   12G  4.0K 100% /home


Из написанного видно что раздел /home, на устройстве md1 забит на 100%, я специально это сделал чтобы сделать более наглядно.

Убедимся что возможность загрузки системы, в случае сбоя массива, включена, для этого:
nano /etc/initramfs-tools/conf.d/mdadm


находим строку:
BOOT_DEGRADED и если в ней установлено:
BOOT_DEGRADED=false

Меняем значение на:
BOOT_DEGRADED=true

ну если совсем лень залезать в конфиги, то можно все сделать через dpkg:
dpkg-reconfigure mdadm

ну и дальше следуем указаниям системы:
mdadm

mdadm

mdadm

ну и сосбвенно то ради чего все затевалось, активируем возможность загрузки системы при сбое массива
mdadm

На этом с подготовкой все, переходим к практике.

1-Делай раз. Извлекаем старый жесткий диск.
Выключаем систему и извлекаем жесткий диск, он нам понадобится в качестве плана Б — если что-то пойдет не так, мы всегда сможем с него откатиться к прежней системе, но если все сделать правильно и заранее потренироваться, то все проходит гладко.
Не важно какой диск вы выдерните, система запустится со второго, и он у нас будет виден в системе в качестве устройства sda

2-Делай два. Добавляем новый диск и запускаем систему
Тут все ясно из названия пункта. Устанавливаем новый жесткий диск и включаем систему.

Проверяем состояние массива:
cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md1 : active raid1 sda6[0]
      13148032 blocks super 1.2 [2/1] [U_]

md0 : active raid1 sda1[0]
      6831040 blocks super 1.2 [2/1] [U_]


Тут мы можем понять что мы извлекли диск sdb -какая «неожиданность»…

Проверяем наличие дисков:
fdisk -l

Если диск не определился, то перезагружаем систему и проверяем снова. Система остается работоспособной, ведь все данные имеются на втором диске.
Нам должно выдать следующее:
Disk /dev/sda: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders, total 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00088388

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1            2048    13672447     6835200   fd  Linux raid autodetect
/dev/sda2        13674494    41940991    14133249    5  Extended
/dev/sda5        13674496    15626239      975872   82  Linux swap / Solaris
/dev/sda6        15628288    41940991    13156352   fd  Linux raid autodetect

Disk /dev/sdb: 171.8 GB, 171798691840 bytes
255 heads, 63 sectors/track, 20886 cylinders, total 335544320 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/sdb doesn't contain a valid partition table

Disk /dev/md0: 6994 MB, 6994984960 bytes
2 heads, 4 sectors/track, 1707760 cylinders, total 13662080 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/md0 doesn't contain a valid partition table

Disk /dev/md1: 13.5 GB, 13463584768 bytes
2 heads, 4 sectors/track, 3287008 cylinders, total 26296064 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/md1 doesn't contain a valid partition table


Нас интересует пункт:
Disk /dev/sdb: 171.8 GB, 171798691840 bytes
255 heads, 63 sectors/track, 20886 cylinders, total 335544320 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/sdb doesn't contain a valid partition table

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

3-Делай три. Переносим таблицу разделов на новый жесткий диск.
Новый диск sdb определился, но он пуст, нам требуется создать дубликат таблицы разделов старого диска sda, давайте сделаем это:
sfdisk -d /dev/sda | sfdisk /dev/sdb

Нам выдаст кучу всего, но нам нужно проверить что разделы создались:
fdisk -l

Получаем:
Disk /dev/sda: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders, total 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0003ab93

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1            2048    19531775     9764864   fd  Linux raid autodetect
/dev/sda2        19533822    41940991    11203585    5  Extended
/dev/sda5        19533824    21485567      975872   82  Linux swap / Solaris
/dev/sda6        21487616    41940991    10226688   fd  Linux raid autodetect

Disk /dev/sdb: 171.8 GB, 171798691840 bytes
255 heads, 63 sectors/track, 20886 cylinders, total 335544320 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    19531775     9764864   fd  Linux raid autodetect
/dev/sdb2        19533822    41940991    11203585    5  Extended
/dev/sdb5        19533824    21485567      975872   82  Linux swap / Solaris
/dev/sdb6        21487616    41940991    10226688   fd  Linux raid autodetect

Disk /dev/md0: 9990 MB, 9990701056 bytes
2 heads, 4 sectors/track, 2439136 cylinders, total 19513088 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/md0 doesn't contain a valid partition table

Disk /dev/md1: 10.5 GB, 10463608832 bytes
2 heads, 4 sectors/track, 2554592 cylinders, total 20436736 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/md1 doesn't contain a valid partition table


Из написанного видно что на диске sdb создались разделы.

4- Делай четыре. Расширяем размер раздела на новом жестком диске, за счет оставшегося свободного места.
Вот тут мы сделаем небольшой «финт ушами» и удалим один раздел и создадим его по новой:
cfdisk /dev/sdb

Выглядеть это будет следующим образом:
cfdisk

Удаляем раздел sdb6 и создаем его по новой:
cfdisk

В качестве типа раздела, выбираем logical:
cfdisk

В размер раздела укажем все доступное место на диске:
cfdisk

Указываем тип раздела:
cfdisk

Собственно тип раздела: Linux raid autodedect т.е. FD, нас скриншоте подчеркнуто красным:
cfdisk

Ну и самое главное, записываем изменения на диск, т.к. сами они не сохраняются, и выходим из cfdisk:
1 -запись изменений
2 -выход
cfdisk

5- Делай пять. Синхронизируем содержимое старого диска, с новым.
Тут тоже все просто, нам необходимо добавить разделы нового диска в md.
Для начала восстановим раздел md0-там где у нас живет операционная система.
устройстро md0 состоит у нас из разделов sdb1 и sda1 т.к. с sda1 у нас все хорошо, ведь с ним ПОКА ничего не происходило, то нам требуется добавить раздел со свежеустановленного диска, а он у нас sdb1
mdadm --add /dev/md0 /dev/sdb1

проверим состояние массива
cat /proc/mdstat

Получаем:
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md1 : active raid1 sda6[0]
      13148032 blocks super 1.2 [2/1] [U_]

md0 : active raid1 sdb1[2] sda1[0]
      6831040 blocks super 1.2 [2/1] [U_]
      [===>.................]  recovery = 15.6% (1069184/6831040) finish=1.2min speed=76370K/sec

Видно что на устройстве md0 началось восстановление, периодически повторяем ввод пока не обнаружим что восстановление завершилось:

Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md1 : active raid1 sda6[0]
      13148032 blocks super 1.2 [2/1] [U_]

md0 : active raid1 sdb1[2] sda1[0]
      6831040 blocks super 1.2 [2/2] [UU]

Видно что на устройстве md0 присутствует 2 диска, значит восстановление завершилось успешно.

Туже операцию проводим с устройством md1:
mdadm --add /dev/md1 /dev/sdb6

Проверяем ход восстановления:
cat /proc/mdstat


Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md1 : active raid1 sdb6[2] sda6[0]
      13148032 blocks super 1.2 [2/1] [U_]
      [=====>...............]  recovery = 28.4% (3734848/13148032) finish=1.8min speed=83940K/sec

md0 : active raid1 sdb1[2] sda1[0]
      6831040 blocks super 1.2 [2/2] [UU]


Дожидаемся окончания восстановления, в результате у нас должно получиться:
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md1 : active raid1 sdb6[2] sda6[0]
      13148032 blocks super 1.2 [2/2] [UU]

md0 : active raid1 sdb1[2] sda1[0]
      6831040 blocks super 1.2 [2/2] [UU]

Это говорит о том что массив восстановлен, а информация на дисках синхронизирована.
Все ничего, но наш новый жесткий диск не является загрузочным т.к. на нем не установлен загрузчик, и с него система стартовать не сможет.
Устанавливаем загрузчик в нашем случае grub, наш новый диск sdb
grub-install /dev/sdb

Получаем.
Installation finished. No error reported.
Значит загрузчик установился нормально.
Выключаем систему!
Делай -6. Удаляем второй старый жесткий диск
Делай -7. Устанавливаем второй НОВЫЙ жесткий диск
Все как и в прошлый раз система «почешет репу» и обнаружит что её ОПЯТЬ немного ополовинили, бывает же такое…
Т.к. мы загрузились уже с нового жесткого диска, он у нас единственный в системе, который содержит данные, то он у нас определился как устройство sda, чувствуете к чему я клоню?! Правильно, выполняем все действия повторно, начиная с пункта 4.

Делай 8. Переносим разделы с одного диска, на тот, который мы только что установили
Копируем таблицу разделов с диска который содержит информацию, на новый, но с небольшими изменениями:
sfdisk -d /dev/sda | sfdisk /dev/sdb --force

Кому требуется проверить успешность копирования разделов, можно воспользоваться командой:
fdisk -l

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

Делай 9. Синхронизируем содержимое обоих дисков
Тут тоже все просто, снова добавляем диск sdb в массив:
mdadm --add /dev/md0 /dev/sdb1

Дождемся перестроения массива md0 и добавим раздел в md1
mdadm --add /dev/md1 /dev/sdb6

Устанавливаем загрузчик на новый жесткий диск:
grub-install /dev/sdb


Делай 10. Расширяем место в устройстве md1
Вот мы и добрались до самой «мякотки», собственно нам требуется расширить место, правда система его пока не видит но мы это сейчас исправим.
расширяем место на устройстве md1 до максимального размера:
mdadm --grow /dev/md1 --size=max

В ответ на это система выдаст нам:
mdadm: component size of /dev/md1 has been set to 159950816K

Это говорит о том что система увидела появившееся свободное пространство и начала перестроение массива. Запускаем, неоднократно, ранее использованную команду:
cat /proc/mdstat

И периодически проверяем ход перестроения массива md1
Должно выдавать нечто похожее:
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md1 : active raid1 sdb6[3] sda6[2]
      159950816 blocks super 1.2 [2/2] [UU]
      [=====>...............]  resync = 25.8% (41408000/159950816) finish=9.5min speed=205884K/sec

md0 : active raid1 sdb1[3] sda1[2]
      6831040 blocks super 1.2 [2/2] [UU]

Где:
159950816-объем раздела, сравните это с тем что нам выдавало ранее…
Из этого видно что массив md1 находится в исправном состоянии, но выполняет синхронизацию.
В общем, нам нужно дождаться окончания перестроения массива и перезагрузить систему.
В меню grub выбираем recovery mode (на скриншоте подчекрнуто красным)
grub recovery mode

Немного поясню мои действия, чтобы выполнить проверку файловой системы нам необходимо от монтировать раздел md1, но на работающей системе этого сделать не получается и при запуске, массив остается в использовании и никакие действия с собой производить не позволяет. По этому, мы зайдем через режим восстановления, когда разделы точно не находятся в использовании.
В общем нам нужно гарантированно от монтировать раздел md1 иначе команда e2fsck и resize2fs завершаются ошибкой:

e2fsck: Device or resource busy while trying to open /dev/md


Если у кого-то есть решение данной проблемы, на работающей системе, пожалуйста отпишитесь т.к. я эту проблемы по другому решить не смог.

Тут мы выбираем командную строку root:

Вот тут можно вытворять системой все что вам угодно!

Для начала запускаем проверку файловой системы, на устройстве md1
e2fsck -f /dev/md1

получаем, то что указано на скриншоте:


после этого запустим резайз файловой системы:
resize2fs /dev/md1

Получаем:

Видно что система увидела прибавку на устройстве md1.
еще раз запустим проверку файловой системы:
e2fsck -f /dev/md1

наблюдаем небольшие изменения в файловой системе

После этого, перезагружаем систему и проверяем -чего мы в ней «наворотили»…
Набираем:
df -h

Filesystem      Size  Used Avail Use% Mounted on
/dev/md0        6.5G 1018M  5.1G  17% /
udev            494M   12K  494M   1% /dev
tmpfs           201M  316K  201M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            502M     0  502M   0% /run/shm
/dev/md1        151G   12G  131G   9% /home

Видно что раздел /home на устройстве md1 увеличился теперь он занят всего на 9%, значит все наши действия завершены успешно, с чем я вас и поздравляю.

Если у вас возникнет необходимость в увеличении массива из 3х и более дисков, то тут тоже нет ничего сложного, достаточно разметить один новый диск как вам требуется, а затем копировать таблицу разделов на новые диски.
Например у вас массив состоящий из 4х дисков, тогда схема замены дисков будет иметь следующий вид, перечислю диски в порядке замены:
2
3
4
1
Допустим вы разметили диск №2 так как вам требуется, вы просто копируете разделы с него на все остальные диски, а когда приходит очередь поменять первый диск в системе, то вы просто диск №2 ставите первым, а новый диск на месте первого, ставите последним, копируете таблицу, синхронизируете содержимое разделов/восстанавливаете целостность массивов, ну а дальше-все как обычно по пункту 10.
Едиснственной проблемой данного метода, является необходимость как минимум 3х перезагрузок, а также время на восстановление целостности массивов, но согласитесь, это лучше, чем переносить данные руками…

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

5 комментариев

avatar
Добрый день. Хорошая статья, сменил по ней все диски в raid10, но встала проблемы в расширении ФС, как быть если рейд единственный и на нем стоит все. Вариант с рековери мод не катит поскольку отмонтировать единственный рейд не получится. Я так понимаю остается единственный вариант загрузится с лайв сд и там уже дать комманду resize2fs.
avatar
Думаю что да, LiveСD вас спасет, но такая разметка это дорога в АД, это вам, дружеский совет, от человека который уже наступил в эту «кучу»…
avatar
Все это конечно хорошо. в инете сотни подобных статей.
Но вот хоть бы одну найти «как уменьшить раздел??» а не увеличить… Нигде нет. Вы не подскажите?
avatar
Спасибо за статью! Благодаря ей перенес существующий RAID с двух 500 ГБ дисков на два 2 ТБ диска.
Вопрос для понимания, зачем использовалась команда resize2fs? Я думал, что после команды mdadm --grow /dev/md1 --size=max система произвела увеличение размера md1 (которая длилась около 3 часов), а resize2fs длился около 10 минут всего.
avatar
здравствуйте.
Это утилита предназначена для работы с разделами, писать реально много.
Если с английским все нормально, то рекомендую к прочтению linux.die.net/man/8/resize2fs
Есть что добавить? Регистрируйся и оставляй комментарии!