Доброго времени суток.
Есть сервер с CentOS6 и высоким %iowait. Нужно без простоя, или максимум 10 минут желательно ночью, перенести систему с md raid1 на md raid10. В моём случае реально уложиться в 10 минут, или даже меньше, потому что у сервера есть hot-swap корзины, но инженеры дата центра где арендуется сервер, изначально подключили диски во вторую и третью корзины, а не в первую и вторую. Из-за этого пришлось выключать сервер менять местами старые диски и ставить новые два.
Перед началом упомяну одну деталь, без неё не получиться мигрировать следуя этому топику. Вся система, кроме /boot, должна быть установлена на LVM. Точка монтирования /boot находится на разделе md0, т.к. grub 0,97 не умеет грузиться с LVM.
Итак, сервер загружен и в нём четыре диска. Раздел /dev/md0 — /boot, раздел /dev/md1 — LVM Physical device и на нём стоит система.
# ls -l /dev/vd* brw-rw----. 1 root disk 252, 0 Mar 23 22:34 /dev/vda brw-rw----. 1 root disk 252, 1 Mar 23 22:34 /dev/vda1 brw-rw----. 1 root disk 252, 2 Mar 23 22:34 /dev/vda2 brw-rw----. 1 root disk 252, 16 Mar 23 22:34 /dev/vdb brw-rw----. 1 root disk 252, 17 Mar 23 22:34 /dev/vdb1 brw-rw----. 1 root disk 252, 18 Mar 23 22:34 /dev/vdb2 brw-rw----. 1 root disk 252, 32 Mar 23 22:34 /dev/vdc brw-rw----. 1 root disk 252, 48 Mar 23 22:34 /dev/vdd # df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_vmraid10-root 2.0G 591M 1.3G 32% / tmpfs 376M 0 376M 0% /dev/shm /dev/md0 194M 33M 151M 18% /boot /dev/mapper/vg_vmraid10-part 1008M 34M 924M 4% /mnt/part #cat /proc/mdstat Personalities : [raid1] md0 : active raid1 vda1[0] vdb1[1] 204788 blocks super 1.0 [2/2] [UU] md1 : active raid1 vdb2[1] vda2[0] 5937144 blocks super 1.1 [2/2] [UU] bitmap: 1/1 pages [4KB], 65536KB chunk
В примере диски значатся как /dev/vdX, т.к. для примера использовалась виртуальная машина с использованием паравиртуализированных драйверов диска VirtIO.
Для начала извлечем из /dev/md1 раздел /dev/vdb2
# mdadm /dev/md1 -f /dev/vdb2 mdadm: set /dev/vdb2 faulty in /dev/md1 # mdadm /dev/md1 -r /dev/vdb2 mdadm: hot removed /dev/vdb2 from /dev/md1
Далее нам нужно затереть супер блок раздела и забить нулями небольшую часть раздела, т.к. если этого не сделать, то данные на /dev/md1 и разделе с raid10, как я понял, будут консистенты из-за этого возникнут проблемы с созданием раздела с raid10(mdadm будет ругаться что раздел /dev/vdb2 уже используется в /dev/md1, не смотря на то что мы его извлекли ранее) и после перезагрузки система попытается загрузиться не с /dev/md1, а c /dev/md2 и закончится всё на kernel panic.
# dd if=/dev/zero of=/dev/vdb2 bs=512 count=1 # dd if=/dev/zero of=/dev/vdb2 bs=1M count=100
Я знаю, что можно обойтись только второй командой, но изначально начал делать так, поэтому на реальной машине экспериментировать не решился.
Далее нам нужно скопировать таблицу разделов с /dev/vdb на /dev/vdc и /dev/vdd. Воспользуемся утилитой sfdisk. sfdisk будет ругаться и говорить, что не буду ничего делать т.к. раздел начинается не на границе цилиндра, добавляем ему ключ -f.
# sfdisk -d /dev/vdb | sfdisk -f /dev/vdс # sfdisk -d /dev/vdb | sfdisk -f /dev/vdd
Разделы готовы, самое время для создания нового raid10 в degraded режиме. Указываю свой uuid тоже для страховки, т.к. во время экспериментов были проблемы.
# mdadm --create /dev/md2 --uuid=3846bee5:d9317441:f8fb6391:4c024445 --level=10 --raid-devices=4 --chunk=2048 missing /dev/vd[bcd]2 mdadm: Defaulting to version 1.2 metadata mdadm: array /dev/md2 started.
Добавляем в /etc/mdadm.conf строчку с новым разделом
# cat /etc/mdadm.conf # mdadm.conf written out by anaconda MAILADDR root AUTO +imsm +1.x -all ARRAY /dev/md0 level=raid1 num-devices=2 UUID=7872830a:c480f8c4:ac316f53:c6ea2b52 ARRAY /dev/md1 level=raid1 num-devices=2 UUID=3846bee5:d9317441:f8fb6391:c4024454 ARRAY /dev/md2 level=raid10 num-devices=4 UUID=3846bee5:d9317441:f8fb6391:4c024445
Перезагружаемся, при загрузке видим что раздел /dev/md2 загружается в degraded режиме
md/raid10:md2: active with 3 out of 4 devices
Создаем physical volume из новоиспеченного раздела, так же указываю свой uuid для избежания duplicate uuid.
# pvcreate --uuid I0OAVm-27U4-KFWZ-4lMB-F3r9-X2kx-LnWADB --norestorefile /dev/md2 Writing physical volume data to disk "/dev/md2" Physical volume "/dev/md2" successfully created
Теперь увеличиваем volume group vg_vmraid10
# vgextend vg_vmraid10 /dev/md2 Volume group "vg_vmraid10" successfully extended
В LVM на Physical volume данные хранятся в блоках называемых PhysicalExtent(PE), вот эти PE'шки можно перемещать между Physical volume, что сейчас и требуется нам проделать.
# pvmove /dev/md1 /dev/md2 ... /dev/md1: Moved: 100,0%
Сейчас нужно открыть файл /boot/grub/menu.lst и в строчке команд для ядра поправить параметр rd_MD_UUID на uuid раздела /dev/md2 в моем случае это 3846bee5:d9317441:f8fb6391:4c024445, если этого не сделать, то система будет пытаться найти рутовый раздел на /dev/md1, а том то уже пусто. Так же в эту строку желательно добавить полезный, при удаленной работе, параметр panic=10, что означает при kernel panic делать авторебут через 10 сек. Далее нам нужно перезагрузить сервер.
# reboot
И тут нас ждёт один подарочек, пока что я не разобрался почему такое происходит. После перезагрузки раздел /dev/md2 переименовывается в раздел /dev/md127, но система нормально грузится по uuid. На сколько я знаю это относится к новой версии mdadm — 3.0 и выше, где можно создавать partitionable array, в котором можно именовать md разделы. Если кто нибудь в курсе, почему так происходит, то пожалуйста отпишитесь в комментариях. А пока мне остается только поправить номер раздела в файле /etc/mdadm.conf и удалить строчку отвечающую за /dev/md1.
Удаляем из Physical group /dev/md1 и удаляем его из списка Physical device. Останавливаем /dev/md1, затираем супер блок у /dev/vda2 и добавляем в /dev/md127
# vgreduce vg_vmraid10 /dev/md1 Removed "/dev/md1" from volume group "vg_vmraid10" # pvremove /dev/md1 Labels on physical volume "/dev/md1" successfully wiped # mdadm -S /dev/md1 mdadm: stopped /dev/md1 # dd if=/dev/zero of=/dev/vda2 bs=512 count=1 # mdadm /dev/md127 -a /dev/vda2 mdadm: added /dev/vda2 # cat /proc/mdstat Personalities : [raid10] [raid1] md0 : active raid1 vda1[0] vdb1[1] 204788 blocks super 1.0 [2/2] [UU] md127 : active raid10 vda2[4] vdb2[1] vdc2[2] vdd2[3] 11870208 blocks super 1.2 2048K chunks 2 near-copies [4/3] [_UUU] [>....................] recovery = 1.1% (68352/5935104) finish=2.8min speed=34176K/sec
Всё, система мигрирована на raid10.
Работать это должно и на CentOS5 только там не придется изменять uuid в menu.lst, т.к. там нет такого параметра. В debian squeezy разница будет только в grub, т.к. там grub2.
В заключении, для себя сделал вывод, что лучше всегда пользоваться LVM, т.к. работать с дисками становится легче в разы. Я могу увеличивать разделы, переносить данные с одного физического диска на другой в прозрачном режиме, могу делать снэпшоты и т.д.
Моя первая статья, возможно получилась слишком длинной, хотелось описать всё подробно чтобы было понятно.
Спасибо, если дочитали до конца.
Автор: skul