Раздел на диске - вещь жёсткая: его край прибит гвоздями к геометрии устройства, и расширить раздел в середине диска, не тронув соседей, почти невозможно. LVM решает ровно эту боль администратора: он вставляет между физическими дисками и файловой системой слой абстракции, в котором место становится текучим. Том можно нарастить на лету, перенести данные с умирающего диска на новый без остановки сервиса, снять мгновенный снимок для бэкапа и раздать тонким клиентам больше места, чем есть физически. В этом уроке разбираем все три этажа LVM, операции resize и pvmove, снапшоты, thin-пулы и связку LVM с RAID.

Как это работает
LVM состоит из трёх уровней, и держать их в голове - половина успеха. Внизу физические тома (PV) - это диски или разделы, которые вы отдали под LVM командой pvcreate. Она пишет в начало устройства метку и область метаданных, после чего диск перестаёт быть обычным разделом и становится сырьём для пула.
Несколько PV объединяются в группу томов (VG) - это общий котёл свободного места. Внутри VG всё пространство нарезано на одинаковые кусочки - физические экстенты (PE), по умолчанию 4 мегабайта. Именно экстент - атом, которым LVM ворочает место. Когда вы создаёте логический том (LV), вы просто говорите группе: дай мне столько-то экстентов, а LVM сам решает, с каких физических дисков их взять. Поэтому один LV может лежать кусками на трёх дисках сразу, и вам это безразлично.
Логический том - это и есть блочное устройство, на котором живёт файловая система. Оно появляется как /dev/имяVG/имяLV (и дублем как /dev/mapper/имяVG-имяLV), потому что под капотом LVM использует device-mapper - подсистему ядра, которая строит виртуальные блочные устройства поверх реальных. Гибкость растёт отсюда: добавили в VG новый диск - в котле прибавилось экстентов, и любой том можно ими накормить, не перетряхивая таблицу разделов.
Снапшот - это особый LV, который ловит образ другого тома на момент создания. Работает он по принципу copy-on-write: пока в исходном томе ничего не меняется, снимок занимает почти ноль места и просто ссылается на оригинал. Как только в оригинал пишут блок, старое его содержимое сначала копируется в область снапшота. Поэтому снимок надо делать с запасом места под изменения и жить ему отведено недолго - под бэкап, а не навсегда.
Тонкое выделение (thin) переворачивает логику: thin-пул выделяет блоки не при создании тома, а только когда в него реально пишут. Можно создать десять томов по 100 ГБ поверх пула в 200 ГБ - это оверкоммит, и он удобен, пока вы следите за заполнением пула. Переполнится физический пул - и все тонкие тома встанут.
Команды и примеры
Пакет называется по-разному, но команды одни и те же:
Код: Выделить всё
# Debian/Ubuntu
sudo apt install lvm2
# RHEL/Fedora
sudo dnf install lvm2Код: Выделить всё
sudo pvcreate /dev/sdb /dev/sdc # пометить диски как PV
sudo vgcreate data /dev/sdb /dev/sdc # группа data из двух PV
sudo lvcreate -L 20G -n web data # том web на 20 ГБ
sudo mkfs.ext4 /dev/data/web # ФС поверх тома
sudo mount /dev/data/web /srv/webКод: Выделить всё
sudo pvs # PV, их VG и свободное место
sudo vgs # группы, размер, свободно
sudo lvs -a -o +devices # тома и на каких PV они лежатКод: Выделить всё
sudo lvextend -L +10G -r /dev/data/web # +10 ГБ и resize ФС
# вручную, если без -r:
sudo lvextend -L +10G /dev/data/web
sudo resize2fs /dev/data/web # ext4
sudo xfs_growfs /srv/web # XFS (по точке монтирования)Код: Выделить всё
sudo umount /srv/web
sudo e2fsck -f /dev/data/web
sudo resize2fs /dev/data/web 12G
sudo lvreduce -L 12G /dev/data/webКод: Выделить всё
sudo pvmove /dev/sdb # увести всё с sdb на свободные PV
sudo vgreduce data /dev/sdb # выкинуть пустой PV из группы
sudo pvremove /dev/sdbКод: Выделить всё
sudo lvcreate -s -L 5G -n web_snap /dev/data/web # снимок
sudo mount -o ro /dev/data/web_snap /mnt # читаем согласованно
# ... сняли tar/rsync, дальше либо удалить, либо откатить:
sudo lvconvert --merge /dev/data/web_snap # вернуть том в момент снимкаКод: Выделить всё
sudo lvcreate -L 50G -T data/pool # thin-пул 50 ГБ
sudo lvcreate -V 100G -T data/pool -n vm1 # тонкий том 100 ГБ
sudo lvs -o +data_percent data # следить за заполнением пулаКод: Выделить всё
sudo lvcreate --type raid1 -m1 -L 10G -n mirror data # зеркало на 2 PV
sudo lvcreate --type raid5 -L 20G -n parity data # нужно 3+ PV- Расширили том, а места в ФС не прибавилось: lvextend растит блочное устройство, но не файловую систему. Без ключа -r или ручного resize2fs/xfs_growfs вы расширили пустоту.
- Сжатие в неверном порядке = потеря данных. Том нельзя ужимать раньше ФС: lvreduce обрежет блоки, которые ФС ещё считает своими. Всегда сначала resize2fs, потом lvreduce, и лучше через -r у lvreduce.
- XFS не сжимается вообще. Если на томе XFS, единственный путь уменьшить - бэкап, пересоздание тома, восстановление.
- Снапшот переполнился и умер. Если изменений в оригинале больше, чем размер снимка, снапшот помечается invalid и становится мусором. Под нагрузкой давайте ему достаточный объём.
- Забыли про мониторинг thin-пула. Оверкоммит молчит до момента, когда физический пул заполнен на 100 процентов - тогда все тонкие тома разом получают ошибки записи. Включайте автоматическое расширение (thin_pool_autoextend в lvm.conf).
- pvremove до pvmove. Если выдернуть диск, на котором ещё лежат экстенты живого тома, том разваливается. Сначала pvmove, проверка lvs, и только потом vgreduce/pvremove.
- Снапшот забыли удалить. Старый снимок продолжает копировать в себя каждое изменение оригинала и тормозит запись, пока не лопнет или не отъест всё место в VG.
- Добавьте на стенд два чистых диска (или два loop-устройства через truncate -s 2G и losetup). Сделайте из них PV командой pvcreate и проверьте pvs.
- Создайте группу lab из обоих PV (vgcreate) и в ней том app на 1 ГБ, отформатируйте в ext4 и смонтируйте.
- Расширьте том на 500 МБ командой lvextend с ключом -r и подтвердите df -h, что место реально прибавилось в ФС.
- Снимите снапшот тома app, измените файл в оригинале, затем откатите том на снимок через lvconvert --merge и убедитесь, что изменение исчезло.
- Командой pvmove уведите все данные с первого PV на второй, проверьте lvs -o +devices, затем выкиньте опустевший PV из группы (vgreduce).
- Создайте thin-пул на 1 ГБ и поверх него тонкий том на 5 ГБ. Через lvs -o +data_percent посмотрите, сколько пула занято на самом деле.
- Назовите три уровня LVM снизу вверх и команду создания на каждом. Что такое физический экстент и зачем он нужен?
- В каком порядке выполняются операции при расширении и при сжатии тома и почему порядок противоположный? Что делает ключ -r?
- Как перенести данные с умирающего диска на новый, не размонтируя файловую систему? Какие команды и в каком порядке?
- Объясните принцип copy-on-write у снапшота LVM. Почему снимок может стать invalid и от чего зависит, сколько места ему дать?
- Что такое оверкоммит в thin-пуле и какая опасность с ним связана? Как от неё защититься?
- Чем XFS отличается от ext4 в контексте изменения размера тома?