Рано или поздно на любом сервере заканчивается место. Классика: на srv-db01 раздел с базой разросся, а соседний раздел простаивает наполовину пустым. Если диск размечен обычными разделами, ты получаешь долгую и нервную операцию с остановкой сервисов. С LVM (Logical Volume Manager) та же задача решается парой команд и без простоя. В этой статье мы пройдём весь путь на примере хоста srv-linux01 в домене itpages.lab.local: создадим логический том, расширим его вместе с файловой системой, добавим новый диск и сделаем снимок перед рискованным обновлением.

Сначала немного модели, потому что без неё команды превращаются в заклинания. В LVM три уровня. Физические тома (PV) — это блочные устройства: диски или разделы, которые ты отдаёшь под управление LVM. Группа томов (VG) — общий пул места, собранный из одного или нескольких PV. Логические тома (LV) — то, что ты нарезаешь из пула и форматируешь под файловые системы. Файловая система живёт на LV и ничего не знает о том, на каких физических дисках лежат её блоки. Именно эта прослойка даёт гибкость: LV можно растягивать, переносить между дисками и снимать с них мгновенные копии.

Шаг 1. Подготовка дисков и создание группы томов

Допустим, на srv-linux01 появились два чистых диска, /dev/sdb и /dev/sdc по 20 ГБ. Сначала проверим, что система их видит и что на них нет ничего нужного:

lsblk -f
NAME   FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
sda
├─sda1 ext4   1.0         3f1c...  412M  38% /boot
└─sda2 LVM2_member LVM2 001 Xk2p...
sdb
sdc

Диски пустые. Инициализируем их как физические тома и соберём группу vg_data:

sudo pvcreate /dev/sdb /dev/sdc
  Physical volume /dev/sdb successfully created.
  Physical volume /dev/sdc successfully created.

sudo vgcreate vg_data /dev/sdb /dev/sdc
  Volume group vg_data successfully created

sudo vgs
  VG      #PV #LV #SN Attr   VSize   VFree
  vg_data   2   0   0 wz--n- <39.99g <39.99g

Обрати внимание на колонку VFree: это нераспределённое место в пуле. Именно из него мы будем резать тома и именно за ним нужно следить в мониторинге, а не за свободным местом внутри файловых систем.

Шаг 2. Создание логического тома и файловой системы

Создадим том под данные веб-приложения на srv-web01 размером 15 ГБ. Имя лучше делать говорящим: потом ты сам скажешь себе спасибо.

sudo lvcreate -L 15G -n lv_www vg_data
  Logical volume lv_www created.

sudo mkfs.xfs /dev/vg_data/lv_www
sudo mkdir -p /srv/www
sudo mount /dev/vg_data/lv_www /srv/www

Чтобы том монтировался после перезагрузки, добавляем строку в /etc/fstab. Лучше использовать путь через /dev/mapper или UUID, а не /dev/sdX: имена дисков могут поменяться местами.

echo '/dev/mapper/vg_data-lv_www /srv/www xfs defaults 0 0' | sudo tee -a /etc/fstab
sudo mount -a
df -h /srv/www
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/vg_data-lv_www    15G  140M   15G   1% /srv/www

Команда mount -a после правки fstab — привычка, которая спасает от сюрпризов при следующей загрузке. Если в строке опечатка, ты узнаешь об этом сразу, а не в три часа ночи после перезапуска сервера.

Шаг 3. Расширение тома на лету

Через месяц место на /srv/www подходит к концу. В группе остались свободные 25 ГБ, поэтому расширяем том ещё на 10 ГБ. Ключ -r (resize fs) говорит lvextend сразу увеличить и файловую систему, так что отдельный вызов xfs_growfs или resize2fs не нужен:

sudo lvextend -r -L +10G /dev/vg_data/lv_www
  Size of logical volume vg_data/lv_www changed from 15.00 GiB to 25.00 GiB.
  Logical volume vg_data/lv_www successfully resized.
  xfs_growfs /srv/www ...

df -h /srv/www
/dev/mapper/vg_data-lv_www    25G  141M   25G   1% /srv/www

Всё это время том остаётся смонтированным, а приложение продолжает работать. Если нужно отдать тому всё оставшееся место, используй -l +100%FREE вместо -L. Запомни асимметрию: расширять можно онлайн для ext4 и XFS, а вот уменьшать XFS нельзя вообще, а ext4 можно только размонтированной. Поэтому в LVM принято выделять места чуть меньше, чем кажется нужным, и добавлять по мере роста.

Шаг 4. Добавление нового диска в группу

Свободное место в VG рано или поздно закончится. Допустим, виртуализация подарила srv-db01 ещё один диск /dev/sdd на 50 ГБ. Добавляем его в существующую группу:

sudo pvcreate /dev/sdd
sudo vgextend vg_data /dev/sdd
  Volume group vg_data successfully extended

sudo pvs
  PV         VG      Fmt  Attr PSize   PFree
  /dev/sdb   vg_data lvm2 a--  <20.00g     0
  /dev/sdc   vg_data lvm2 a--  <20.00g <15.00g
  /dev/sdd   vg_data lvm2 a--  <50.00g <50.00g

Теперь пул вырос, и любой LV можно растянуть дальше. Если диск виртуальный и ты увеличил его на стороне гипервизора, не создавая нового, достаточно сказать LVM пересчитать размер: сначала пересканировать устройство (echo 1 | sudo tee /sys/class/block/sdb/device/rescan), затем выполнить pvresize /dev/sdb. Так делается расширение без добавления дисков.

Бывает и обратная задача: старый диск нужно вывести из эксплуатации. LVM умеет переносить данные между физическими томами прямо на работающей системе:

sudo pvmove /dev/sdb
  /dev/sdb: Moved: 100.00%
sudo vgreduce vg_data /dev/sdb
sudo pvremove /dev/sdb

Команда pvmove копирует экстенты с /dev/sdb на другие диски группы, не останавливая файловые системы. Это одна из тех возможностей, ради которых LVM и стоит использовать. Перед запуском убедись, что в группе достаточно свободного места, иначе pvmove честно сообщит, что переносить некуда.

Шаг 5. Снимки перед рискованными изменениями

Снимок (snapshot) — это моментальная копия тома по принципу copy-on-write: LVM не копирует данные сразу, а сохраняет исходные версии блоков только тогда, когда они меняются. Для снимка нужно выделить место под эти изменения. Представь, что на srv-web01 ты собираешься обновлять приложение и хочешь иметь путь назад:

sudo lvcreate -s -L 5G -n lv_www_snap /dev/vg_data/lv_www
  Logical volume lv_www_snap created.

sudo lvs
  LV          VG      Attr       LSize  Pool Origin Data%
  lv_www      vg_data owi-aos--- 25.00g
  lv_www_snap vg_data swi-a-s---  5.00g      lv_www 0.01

Колонка Data% показывает, насколько заполнено место под изменения. Если оно дойдёт до 100%, снимок станет недействительным, поэтому для активных томов закладывай запас и поглядывай на этот показатель. После обновления есть два сценария. Если всё хорошо, снимок просто удаляем:

sudo lvremove /dev/vg_data/lv_www_snap

Если обновление сломало приложение, откатываемся. Слияние снимка с оригиналом выполняется при следующей активации тома, поэтому для смонтированного тома нужно размонтировать его и перезапустить активацию:

sudo umount /srv/www
sudo lvconvert --merge /dev/vg_data/lv_www_snap
sudo lvchange -an /dev/vg_data/lv_www
sudo lvchange -ay /dev/vg_data/lv_www
sudo mount /dev/vg_data/lv_www /srv/www

Снимок не заменяет резервную копию: он лежит в той же группе томов на тех же дисках. Он нужен для короткого окна риска, а не для хранения истории. Хорошая практика: снимок на время работ, потом либо удаление, либо откат. Ещё один сценарий — согласованная резервная копия базы: смонтируй снимок только для чтения и снимай с него бэкап, пока сама база продолжает работать на оригинале.

Шаг 6. Контроль и повседневная гигиена

Для ежедневной работы достаточно трёх команд: pvs, vgs и lvs. Они показывают краткую сводку по каждому уровню. Подробности по конкретному объекту даёт lvdisplay, vgdisplay и pvdisplay. Настрой простую проверку, которая предупреждает, когда в группе остаётся меньше 10 процентов свободного места:

sudo vgs --noheadings -o vg_name,vg_free_count,vg_extent_count
  vg_data 6400 12798

Если считаешь свободное место скриптом в cron или в системе мониторинга, сравнивай vg_free_count и vg_extent_count. Кроме того, делай копию метаданных: LVM сам хранит резервные копии в /etc/lvm/backup, и они пригодятся при восстановлении после сбоя. Можно сохранить копию вручную командой vgcfgbackup vg_data и положить её на другой хост, например на srv-linux01 из сети 192.168.10.0/24, через scp.

Отдельно упомяну тонкие тома (thin provisioning). Они позволяют создавать тома, суммарный размер которых больше реального места, и выделять блоки по мере записи. Это удобно для тестовых стендов и контейнеров, но требует жёсткого мониторинга заполненности пула, потому что при переполнении тонкого пула страдают все тома сразу. На продуктивных серверах с критичными данными начинай с обычных (толстых) томов, а тонкие подключай осознанно.

Шаг 7. Восстановление и аварийные ситуации

Что делать, если после перезагрузки тома не появились? Первым делом проверь, видит ли система физические диски, а затем выполни vgscan и vgchange -ay: первая команда ищет группы томов, вторая активирует их логические тома. Часто причина банальна: в виртуальной среде диск не подключился к машине или его порядок изменился. Если группа не находится совсем, посмотри архив метаданных в /etc/lvm/archive и восстанови конфигурацию командой vgcfgrestore, но делай это внимательно и только после чтения справки, потому что неправильное восстановление способно усугубить ситуацию.

Отдельная история — удаление и переименование. Переименовать том можно на лету командой lvrename, но не забудь поправить fstab и ссылки в конфигурации приложений, иначе после перезагрузки монтирование не состоится. Удаляя том, дважды проверь имя: lvremove спросит подтверждение, и это тот случай, когда лучше прочитать вопрос, а не нажимать y по привычке. Хорошая привычка — перед любой операцией разрушающего типа сохранить метаданные командой vgcfgbackup и записать вывод lvs -a -o +devices в рабочий журнал. В таком журнале через полгода легко найти, какой том на каком диске жил.

Наконец, производительность. LVM добавляет крошечные накладные расходы на преобразование адресов, на практике незаметные. Заметнее влияет выравнивание и размер экстента: по умолчанию он равен 4 МБ и подходит почти всегда. Если же ты планируешь группу на десятки терабайт, задай размер экстента заранее ключом -s при создании группы, ведь потом его не изменить. Для вторичных нагрузок (архивы, бэкапы) удобны полосатые тома: lvcreate -i 2 -I 64 распределяет данные между двумя дисками и ускоряет последовательное чтение и запись, хотя надёжность при этом не растёт, а падает, ведь отказ любого диска уничтожает том.

Частые ошибки и как их избежать

  • Отдать всё место сразу. Если ты нарезал тома под завязку, у тебя нет резерва ни на снимок, ни на расширение. Оставляй в группе 10–20 процентов свободного места и растягивай тома по мере необходимости: расширение онлайн дёшево, а уменьшение дорого или невозможно.
  • Забыть про файловую систему. Команда lvextend без ключа -r увеличит том, но файловая система сохранит старый размер, и df ничего не покажет. Либо всегда используй -r, либо следом запускай xfs_growfs или resize2fs. Сверяй результат с df -h.
  • Оставить снимок навсегда. Старый снимок замедляет запись на оригинале (каждый изменённый блок копируется), а при заполнении превращается в мусор. Удаляй снимок сразу после завершения работ и следи за Data% командой lvs.

Что дальше

Администрирование Linux — это набор связанных навыков, вот соседние темы серии: