На сервере кончается свободное место на дисках, а купить новый в этом месяце в бюджет не заложено? Ищем не самые полезные с точки зрения отказоустойчивости методы решения вопроса и вспоминаем, что все сервера у нас собраны на программных зеркалах mdadm raid1. Пришло время избавиться от дублирования данных в угоду увеличению объема тех самых данных. Это увеличит риски потерять все в случае выхода из строя любого из дисков, но иногда можно этим пренебречь (как говорил классик, все люди делятся на три категории: 1) те кто еще не делают бэкапы, 2) те кто уже делает, 3) кто проверяет что он там набэкапил).
Итак, суть: возьмем RAID1 из двух дисков, выбросим из него один диск, накатим туда пустой LVM, переложим данные, загрузимся с этого диска, грохнем raid и расширим LVM за счет освободившегося второго диска.
Идея не претендует на новаторство, однако пошагового how-to при беглом гуглении найти не удалось. Были найдены варианты с переделкой в RAID5 в статусе degraded без одного диска, что явно не является решением нашей проблемы. А также вполне логичный вопрос (на мой взгляд) как переделать зеркало в страйп (raid1 в raid0) от Пумы несколько лет назад. Так вот, Ромка, нельзя. Из-за структуры хранения данных в страйпе, которая напоминает сцепленные в замок руки. Данные поочередно кладутся на оба диска.
Перед началом всех операций имеем следующую картину: 2 диска по 3 раздела в каждом (swap, /boot и /) объединены в md-зеркала:
# fdisk -l Disk /dev/sda: 477 GiB, 512110190592 bytes, 1000215216 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 Disklabel type: dos Disk identifier: 0x865165a5 Device Boot Start End Sectors Size Id Type /dev/sda1 2048 33556479 33554432 16G fd Linux raid autodetect /dev/sda2 33556480 34605055 1048576 512M fd Linux raid autodetect /dev/sda3 34605056 1000213167 965608112 460.4G fd Linux raid autodetect Disk /dev/sdb: 477 GiB, 512110190592 bytes, 1000215216 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 Disklabel type: dos Disk identifier: 0x96457804 Device Boot Start End Sectors Size Id Type /dev/sdb1 2048 33556479 33554432 16G fd Linux raid autodetect /dev/sdb2 33556480 34605055 1048576 512M fd Linux raid autodetect /dev/sdb3 34605056 1000213167 965608112 460.4G fd Linux raid autodetect Disk /dev/md1: 511.4 MiB, 536281088 bytes, 1047424 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 /dev/md0: 16 GiB, 17163091968 bytes, 33521664 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 /dev/md2: 460.3 GiB, 494257111040 bytes, 965345920 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 # cat /proc/mdstat Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10] md2 : active raid1 sdb3[1] sda3[0] 482672960 blocks super 1.2 [2/2] [UU] bitmap: 1/4 pages [4KB], 65536KB chunk md0 : active raid1 sda1[0] sdb1[1] 16760832 blocks super 1.2 [2/2] [UU] md1 : active raid1 sdb2[1] sda2[0] 523712 blocks super 1.2 [2/2] [UU] unused devices:
Выбрасываем первый диск
# mdadm --fail /dev/md2 /dev/sda3 mdadm: set /dev/sda3 faulty in /dev/md2 # mdadm -fr /dev/md2 /dev/sda3 mdadm: hot removed /dev/sda3 from /dev/md2 # mdadm --fail /dev/md1 /dev/sda2 mdadm: set /dev/sda2 faulty in /dev/md1 # mdadm -fr /dev/md1 /dev/sda2 mdadm: hot removed /dev/sda2 from /dev/md1 # mdadm --fail /dev/md0 /dev/sda1 mdadm: set /dev/sda1 faulty in /dev/md0 # mdadm -fr /dev/md0 /dev/sda1 mdadm: hot removed /dev/sda1 from /dev/md0 # cat /proc/mdstat Personalities : [raid1] [linear] [multipath] [raid0] [raid6] [raid5] [raid4] [raid10] md2 : active raid1 sdb3[1] 482672960 blocks super 1.2 [2/1] [_U] bitmap: 2/4 pages [8KB], 65536KB chunk md0 : active raid1 sdb1[1] 16760832 blocks super 1.2 [2/1] [_U] md1 : active raid1 sdb2[1] 523712 blocks super 1.2 [2/1] [_U] unused devices:
Стираем с этого диска информацию о принадлежности к RAID-массиву, чтобы он в будущем не решил вернуться в эти ряды.
# mdadm --zero-superblock /dev/sda1 # mdadm --zero-superblock /dev/sda2 # mdadm --zero-superblock /dev/sda3
Поменяем информацию по типу разделов на этом диске
# fdisk /dev/sda Command (m for help): t Partition number (1-3, default 3): 3 Partition type (type L to list all types): 82 Changed type of partition 'Linux raid autodetect' to 'Linux swap / Solaris'. Command (m for help): t Partition number (1-3, default 3): 2 Partition type (type L to list all types): 83 Changed type of partition 'Linux raid autodetect' to 'Linux'. Command (m for help): t Partition number (1-3, default 3): Partition type (type L to list all types): 83 Changed type of partition 'Linux raid autodetect' to 'Linux'. Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Re-reading the partition table failed.: Device or resource busy The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8).
Если выдало в конце ошибку как у меня — делаем (после установки kpartx при отсутствии):
# kpartx -f -v /dev/sda sda1 : 0 33554432 /dev/sda 2048 sda2 : 0 1048576 /dev/sda 33556480 sda3 : 0 965608112 /dev/sda 34605056
Раздел /boot класть на LVM не будем (с LVM уверенно грузится GRUB2+, а в случае отсутствия KVM-доступа к серверу вернуть в работоспособное состояние его будет весьма проблематично). Поэтому создаем в маленьком разделе файловую систему и перекладываем туда данные с еще живого куска зеркала
# mkfs.ext3 /dev/sda2 mke2fs 1.42.13 (17-May-2015) Discarding device blocks: done Creating filesystem with 131072 4k blocks and 32768 inodes Filesystem UUID: f4215b7b-1793-49f0-96ed-f3fb8fc50786 Superblock backups stored on blocks: 32768, 98304 Allocating group tables: done Writing inode tables: done Creating journal (4096 blocks): done Writing superblocks and filesystem accounting information: done # mount /dev/sda2 /mnt/ # rsync -av /boot/ /mnt/
Делаем раздел подкачки активным:
# mkswap /dev/sda1 Setting up swapspace version 1, size = 16 GiB (17179865088 bytes) no label, UUID=0b90f5ac-810e-40e2-a026-18823dedbd50 # swapon /dev/sda1
Выключаем прежний раздел
# swapoff /dev/md0
На оставшемся разделе под систему и данные создаем lvm том, группу и непосредственно логическое устройство необходимых размеров (я задействую всё пространство, кому требуются другие варианты — есть неплохие мануалы тут и там, переносить их сюда слово в слово не вижу надобности)
# pvcreate /dev/sda3 Physical volume "/dev/sda3" successfully created # vgcreate vg0 /dev/sda3 Volume group "vg0" successfully created # lvcreate -n bigroot vg0 Please specify either size or extents. Run `lvcreate --help' for more information. # lvcreate -n bigroot -l100%FREE vg0 Logical volume "bigroot" created. # mkfs.ext4 /dev/vg0/bigroot mke2fs 1.42.13 (17-May-2015) Discarding device blocks: done Creating filesystem with 120699904 4k blocks and 30179328 inodes Filesystem UUID: 38c8869a-516b-4149-8db8-ce74831f8a6f Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968, 102400000 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done
Помимо всего прочего, можно тут сразу потюнить файловую систему, например я отключаю журналирование, поскольку на диске будет много операций чтения/записи.
Теперь самое рутинное — переносим своим любимым способом ПОЧТИ всю информацию со старого диска на новый раздел (то, что не требуется — пропускаем)
# mount /dev/vg0/bigroot /mnt/ # rsync -av / /mnt/ --exclude sys --exclude proc --exclude dev --exclude tmp --exclude media --exclude mnt --exclude run --exclude boot # cd /mnt && mkdir sys proc dev tmp media mnt run boot
Заходим в окружение новой системы и правим конфиги для успешной загрузки в дальнейшем
# mount -t proc none /mnt/proc/ # mount -t sysfs sysfs /mnt/sys # mount -o bind /dev/ /mnt/dev # mount -o bind /run /mnt/run # mount /dev/sda2 /mnt/boot # chroot /mnt/ # mcedit /etc/fstab proc /proc proc defaults 0 0 /dev/sda1 none swap sw 0 0 /dev/sda2 /boot ext3 defaults 0 0 /dev/vg0/bigroot / ext4 defaults 0 0 # update-grub # grub-install /dev/sda # exit # umount /mnt/proc /mnt/sys /mnt/dev /mnt/run /mnt/boot # umount /mnt
Ну и, скрестив пальцы, пробуем загрузиться с этого диска
# reboot
В случае успешной загрузки проверяем с помощью df, что мы добились желаемого (у / будет не /dev/md0 а наш /dev/vg0/bigroot), останавливаем RAID и форматируем диск.
# mdadm --zero-superblock /dev/sdb1 # mdadm --zero-superblock /dev/sdb2 # mdadm --zero-superblock /dev/sdb3 # fdisk /dev/sdb Command (m for help): d Partition number (1-3, default 3): Partition 3 has been deleted. Command (m for help): d Partition number (1,2, default 2): Partition 2 has been deleted. Command (m for help): d Selected partition 1 Partition 1 has been deleted. Command (m for help): p Disk /dev/sdb: 477 GiB, 512110190592 bytes, 1000215216 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 Disklabel type: dos Disk identifier: 0x96457804 Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks.
Теперь добавляем диск к нашим lvm-партициям и увеличиваем место
# vgextend vg0 /dev/sdb WARNING: dos signature detected on /dev/sdb at offset 510. Wipe it? [y/n]: y Wiping dos signature on /dev/sdb. Physical volume "/dev/sdb" successfully created Volume group "vg0" successfully extended # lvextend -l +100%FREE /dev/vg0/bigroot Size of logical volume vg0/bigroot changed from 460.43 GiB (117871 extents) to 937.37 GiB (239967 extents). Logical volume bigroot successfully resized. # resize2fs /dev/vg0/bigroot resize2fs 1.42.13 (17-May-2015) Filesystem at /dev/vg0/bigroot is mounted on /; on-line resizing required old_desc_blocks = 29, new_desc_blocks = 59 The filesystem on /dev/vg0/bigroot is now 245726208 (4k) blocks long.
Радуемся, что всё получилось!
# df -h|grep bigroot /dev/mapper/vg0-bigroot 923G 174G 707G 20% /