LVM (Logical Volume Management) — это способ отвязать файловую систему от конкретного диска.

Вместо «вот есть диск → вот на нём разделы» ты получаешь слой абстракции:

  • можно объединять несколько дисков в один пул
  • можно делить этот пул как угодно
  • можно менять размеры «разделов» на лету

Проще аналогия:
есть куча разных дисков → ты собираешь из них один «виртуальный диск» → режешь его как хочешь.

***

Три сущности, которые нужно понять

  • PV (Physical Volume) — физический носитель

Это либо целый диск (/dev/sdb), либо раздел (/dev/sdb1)

  • VG (Volume Group) — пул дисков

Объединяешь несколько PV → получаешь один большой «диск»

  • LV (Logical Volume) — логический раздел

Это уже аналог обычного раздела, который ты форматируешь и монтируешь

Связка выглядит так:

диски → PV → VG → LV → файловая система → mount

***

Минимальный сценарий: добавили новый диск

Условие:

  • есть система на /dev/sda
  • подключили новый диск /dev/sdb (пустой)

Задача: вынести /home на новый диск через LVM

***

Установка

apt install lvm2

***

Шаг 1. Делаем диск физическим томом

pvcreate /dev/sdb

Проверить:

pvdisplay

***

Шаг 2. Создаём группу томов

vgcreate ws /dev/sdb

Теперь у тебя есть пул ws

***

Шаг 3. Создаём логический том

Например под /home:

lvcreate -n home -L 500G ws

Проверить:

lvdisplay
vgdisplay

***

Шаг 4. Форматируем

mkfs.ext4 /dev/ws/home

(реально это /dev/mapper/ws-home, но /dev/ws/home — удобный алиас)

***

Шаг 5. Перенос данных

mkdir /mnt/newhome
mount /dev/ws/home /mnt/newhome
cp -a /home/* /mnt/newhome/
umount /mnt/newhome

***

Шаг 6. Подключение в систему

Добавляем в /etc/fstab:

/dev/mapper/ws-home /home ext4 defaults 0 2

Монтируем:

mount -a

***

Что ты в итоге получил

  • /home теперь на LVM
  • диск можно расширять
  • можно добавить ещё диски в VG и увеличить том

***

Самое полезное: расширение на лету

Добавил новый диск /dev/sdc:

pvcreate /dev/sdc
vgextend ws /dev/sdc

Увеличил том:

lvextend -L +100G /dev/ws/home
resize2fs /dev/ws/home

Важно:
сначала расширяешь LV, потом файловую систему

***

Магия LVM: перенос без остановки

Если диск умирает — можно «перелить» данные:

pvmove /dev/sdb /dev/sdc

После этого:

vgreduce ws /dev/sdb

И всё — диск можно вытаскивать, система продолжает работать.

***

Что важно помнить

  • /boot лучше держать вне LVM (особенно если BIOS + старый GRUB)
  • всегда проверяй, что именно форматируешь (ошибка = потеря данных)
  • делай бэкапы метаданных:
  vgcfgbackup

***

Когда LVM реально нужен

  • серверы (почти всегда)
  • когда диски добавляются постепенно
  • когда нужно расширять разделы без даунтайма
  • когда не хочешь заранее угадывать размеры

***

Когда не нужен

  • простая домашняя система на одном диске
  • если не планируется изменение разметки

***

Короткий пример «в голове»

Без LVM:

/dev/sda1 = /home (100G) → закончилось место → боль

С LVM:

добавил диск → vgextend → lvextend → готово

***
Тогда поехали во «вторую часть» — про прод и «вкусные» фичи LVM: снапшоты, thin, кеш, Docker/PostgreSQL.

***

Снапшоты: точка отката за секунды

Снапшот — это «фото» тома в момент времени.
Базовая идея: copy‑on‑write — пока данные не меняются, снапшот почти места не занимает. [people.tuebingen.mpg](https://people.tuebingen.mpg.de/maan/aple/LVM.html)

Зачем нужно

  • быстрый rollback перед обновлением
  • «заморозить» состояние под бэкап
  • тест миграций/апдейтов на копии

Классический снапшот (thick)

Создаём снапшот тома ws/home на 10G:

lvcreate -L 10G -s -n home_snap /dev/ws/home
  • home_snap сразу доступен как блочное устройство /dev/ws/home_snap
  • место реально тратится только на изменения, но ограничено 10G

Откат (жёсткий rollback):

lvconvert --merge /dev/ws/home_snap
# перезагрузка или размонтирование/монтирование тома по инструкции lvm

Важно: если снапшот переполнится — он сломается, и точка отката будет потеряна. [docs.redhat](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_logical_volumes/advanced-logical-volume-management_configuring-and-managing-logical-volumes)

***

Thin provisioning: «виртуальные» тома больше физического места

Thin LV — это логический том, где блоки выдаются по мере записи, а не заранее. [man7](https://man7.org/linux/man-pages/man7/lvmthin.7.html)

Что это даёт

  • можно создать, условно, 10 томов по 1T на пуле 2T
  • платить местом только за реально записанные блоки
  • снапшоты тонких томов очень лёгкие (делают быстрые клоны) [man7](https://man7.org/linux/man-pages/man7/lvmthin.7.html)

Базовые сущности thin

  • thin pool LV — специальный LV, из которого раздаются блоки thin‑томам
  • metadata LV — служебные метаданные пула
  • data LV — куда реально пишутся блоки данных [people.tuebingen.mpg](https://people.tuebingen.mpg.de/maan/aple/LVM.html)

Схема: VG → thin pool (data+metadata) → множество thin LV.

***

Пример: создание thin‑пула и thin‑томов

Допустим, есть VG ws с кучей свободного места.

1. Создаём data и metadata LV

lvcreate -L 900G -n thin_data ws
lvcreate -L 10G  -n thin_meta ws

2. Собираем из них thin‑pool

lvconvert --type thin-pool \
  --poolmetadata ws/thin_meta \
  ws/thin_data

Теперь ws/thin_data стал пулам ws/thin_data (thin pool LV). [docs.redhat](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_logical_volumes/advanced-logical-volume-management_configuring-and-managing-logical-volumes)

3. Создаём thin‑том

lvcreate -V 500G -T ws/thin_data -n docker

Форматируем:

mkfs.ext4 /dev/ws/docker

***

Thin‑снапшоты: дешёвые клоны

Thin‑снапшот создаётся от thin‑тома и использует тот же пул:

lvcreate -s -n docker_test /dev/ws/docker

Особенности: [people.tuebingen.mpg](https://people.tuebingen.mpg.de/maan/aple/LVM.html)

  • размер не надо задавать — он живёт внутри того же пула
  • блоки общего прошлого состояния шарятся между origin и снапшотом
  • цепочки снапшотов не деградируют по производительности так жестко, как классические

Это удобно для:

  • теста обновления PostgreSQL или приложения
  • быстрого клонирования окружений (dev/stage)

***

LVM cache: SSD как кеш для HDD

LVM умеет использовать быстрый диск как кеш для медленного. [gaz-dc](https://www.gaz-dc.net/lvm)

Сценарий:

  • HDD том ws/data большой и медленный
  • есть небольшой SSD под кеш /dev/nvme0n1

1. Делаем PV и добавляем в VG

pvcreate /dev/nvme0n1
vgextend ws /dev/nvme0n1

2. Создаём кеш‑LV

lvcreate -n cache_data -L 50G ws /dev/nvme0n1
lvcreate -n cache_meta -L 1G  ws /dev/nvme0n1

3. Подвешиваем кеш к основному LV

lvconvert --type cache \
  --cachepool ws/cache_data \
  --cachemetadata ws/cache_meta \
  ws/data

Теперь ws/data использует SSD как кеш‑слой, ускоряя горячие блоки. [docs.redhat](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/configuring_and_managing_logical_volumes/advanced-logical-volume-management_configuring-and-managing-logical-volumes)

***

Best practices для прод‑серверов

Сводка общих рекомендаций: [cleveruptime](https://cleveruptime.com/docs/applications/lvm)

  • Всегда иметь бэкапы отдельно от LVM (LVM‑снапшоты — не бэкап, а удобный источник для него)
  • Мониторить свободное место в VG и, особенно, в thin‑пуле
  • Не злоупотреблять oversubscription (thin‑томы «больше» физики)
  • Документировать схему LVM (VG/LV назначения, параметры PE, размеры) [cleveruptime](https://cleveruptime.com/docs/applications/lvm)
  • Делать изменения в подходящее окно или с понятным планом отката [linkedin](https://www.linkedin.com/posts/mdarifulcse_work-linux-lvm-activity-7364421796797808640-8j6r)

Для расширения LV в проде:

1. Проверить бэкап/снапшот
2. Убедиться, что есть свободное место в VG / thin‑пуле
3. Для ext4: lvextendresize2fs, для XFS: сначала lvextend, затем xfs_growfs на смонтированном томе [digitalocean](https://www.digitalocean.com/community/tutorials/an-introduction-to-lvm-concepts-terminology-and-operations)

***

LVM + Docker: как жить нормально

Сейчас Docker по умолчанию использует overlay2; старый device‑mapper driver (loop-lvm) помечен как deprecated и не рекомендуется для продакшена. [docs.docker](https://docs.docker.com/engine/storage/drivers/device-mapper-driver/)

Но LVM полезен на уровне хоста:

  • выделяешь отдельный LV под /var/lib/docker
  • делаешь снапшоты/бэкапы всего docker‑хранилища
  • можешь вынести это на отдельный диск/RAID

Пример:

lvcreate -n docker -L 200G ws
mkfs.ext4 /dev/ws/docker
mkdir -p /var/lib/docker
mount /dev/ws/docker /var/lib/docker
# прописать в /etc/fstab

Если хочешь deep‑интеграцию с LVM thin для Docker, у Red Hat был сценарий: LVM thin‑pool как хранилище для device‑mapper driver, настраиваемый через конфиги (docker-storage-setup/container-storage-setup), но эта схема теперь признана устаревшей и больше исторический интерес. [docs.redhat](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux_atomic_host/7/html/managing_containers/managing_storage_with_docker_formatted_containers)

***

LVM + PostgreSQL: разумная схема

Основные моменты: [reddit](https://www.reddit.com/r/docker/comments/4udzcw/can_i_should_i_run_a_big_postgresql_database_in/)

  • данные PostgreSQL хранить на отдельном LV:

lvcreate -n pgdata -L 500G ws

  • использовать XFS или ext4 с правильными опциями монтирования
  • авторасширение: удобно иметь VG с запасом и план lvextend + xfs_growfs/resize2fs

Снапшоты:

  • для быстрых бэкапов можно делать LVM‑снапшот pgdata, монтировать read‑only и с него делать backup (например, pg_basebackup)
  • для корректности лучше всё равно использовать механизмы PostgreSQL (CHECKPOINT, pg_start_backup/pg_stop_backup или современный pg_basebackup + WAL‑архивация) [dev](https://dev.to/lovestaco/running-postgresql-in-docker-with-persistent-volume-4joe)

Thin vs thick:

  • для критичного прод‑PostgreSQL я бы избегал жёсткого oversubscription: thin‑пул без оверсейла или с очень аккуратной политикой мониторинга, иначе переполнение пула = ад
  • классический толстый LV проще и предсказуемей, особенно на bare‑metal/VM, где ты и так контролируешь диск

***

Где всё это особенно заходит

***
Тогда давай не абстрактно, а сразу три типовых «боевых» сценария, где LVM реально помогает. Я буду делать упор на структуру VG/LV и практические мелочи.

***

1. Bare metal сервер с кучей сервисов

Типичный Linux‑хост: nginx, PHP/Python, PostgreSQL/MySQL, Docker (частично), логи, бэкапы.

Разметка дисков и VG

Допустим, есть два диска:

Примерная схема:

  • /dev/sda1 — EFI (если нужно)
  • /dev/sda2 — /boot (вне LVM)
  • /dev/sda3 — PV pv_root → VG vg_sys
  • /dev/sdb — PV pv_data → VG vg_data

Почему два VG:

Логические тома

vg_sys:

vg_data:

  • lv_pgdata 200–500G → /var/lib/postgresql или /srv/pgdata
  • lv_mysql под MySQL/MariaDB, если надо
  • lv_www под сайты / статику (/srv/www или /var/www)
  • lv_docker если хочешь вытащить /var/lib/docker в отдельное место
  • lv_backup под локальные бэкапы (Borg, restic и т.п.)

Рекомендации: [mono](https://mono.software/2016/02/01/Hyper-V-Failover-Cluster-4-PostgreSQL/)

  • root не раздувать, 20–30G чаще хватает
  • /var и /var/log логически отделять, чтобы логами не убить систему
  • обязательно оставить свободное место в VG для будущих lvextend [cnblogs](https://www.cnblogs.com/goozgk/articles/5657582.html)

Снапшоты в проде

Для быстрых бэкапов:

lvcreate -L 20G -s -n pgdata_snap vg_data/pgdata
mount -o ro /dev/vg_data/pgdata_snap /mnt/pgsnap
# с /mnt/pgsnap делаешь backup, потом:
umount /mnt/pgsnap
lvremove vg_data/pgdata_snap

Для PostgreSQL лучше всё равно согласовывать с её механизмом бэкапа (checkpoint + WAL), но LVM‑снапшот сильно упрощает «заморозку» файловой системы. [digitalocean](https://www.digitalocean.com/community/tutorials/an-introduction-to-lvm-concepts-terminology-and-operations)

***

2. KVM‑хост: LV на каждую VM

Это очень приятный сценарий для LVM: хранишь диски VM как raw‑LV, без файловых образов. Меньше фрагментации, проще снапшоты и миграции. [medium](https://medium.com/@pash4stud2/understanding-thick-vs-thin-provisioning-in-kvm-3a3f9a8821ba)

База

Допустим, есть большой RAID‑массив /dev/md0 → PV pv_kvm → VG vg_kvm.

Из него режем:

Вариант 1: толстые LV (thick provisioning)

Каждая VM — отдельный LV:

lvcreate -n vm1_root -L 80G vg_kvm
lvcreate -n vm2_root -L 100G vg_kvm

В libvirt:

Плюсы:

  • предсказуемость по месту и скорости
  • минимум магии

Минусы:

  • заранее нужно решить размер, но можно потом lvextend + внутри гость расширить FS

Вариант 2: thin‑pool под VM‑диски

Создаём thin‑pool:

lvcreate -L 5T -n kvm_data vg_kvm
lvcreate -L 50G -n kvm_meta vg_kvm

lvconvert --type thin-pool \
  --poolmetadata vg_kvm/kvm_meta \
  vg_kvm/kvm_data

Теперь:

lvcreate -V 100G -T vg_kvm/kvm_data -n vm1_root
lvcreate -V 150G -T vg_kvm/kvm_data -n vm2_root

virt-install/virsh указывают те же /dev/vg_kvm/vm1_root как блок‑устройство. [forums.linbit](https://forums.linbit.com/t/kvm-libvirt-qemu-lvm-recommended-setup/918)

Плюсы: [medium](https://medium.com/@pash4stud2/understanding-thick-vs-thin-provisioning-in-kvm-3a3f9a8821ba)

  • быстрые клоны VM через thin‑снапшоты
  • можно не держать full‑reserve по месту, если есть мониторинг

Минусы:

  • нужно жёстко следить за процентом использования thin‑пула (alarm, мониторинг)
  • переполнение пула — очень больно

Снапшоты VM на уровне LVM

  • удобно делать снапшот LV перед обновлением ОС внутри VM:
  lvcreate -s -n vm1_root_pre_upgrade vg_kvm/vm1_root
  • VM можно оставить включённой, но для максимальной консистентности — freeze/guest‑agent, зависимостей куча

***

3. Одна VM с Docker и PostgreSQL внутри

Сценарий: есть KVM‑VM (disk = один LVM‑LV на хосте), внутри VM — тоже LVM или просто классические разделы.

Минимально разумно внутри VM

Внутри VM (гость):

То есть LVM по сути в двух слоях:

  • слой 1: хост — хранит VM диски как LVM‑LV
  • слой 2: гость — внутри него LVM под свои /var, pgdata и т.д.

Так делать можно, это обычный «LVM‑в‑LVM» (с точки зрения ядра — просто блочное устройство внутри блочного). [community.learnlinux](https://community.learnlinux.tv/t/help-me-understand-lvm-kvm/4183)

PostgreSQL внутри

Гость (VM):

pvcreate /dev/vdb      # допустим, второй диск VM
vgcreate vg_guest /dev/vdb
lvcreate -n pgdata -L 200G vg_guest
mkfs.xfs /dev/vg_guest/pgdata
mount /dev/vg_guest/pgdata /var/lib/postgresql

Расширение, когда место заканчивается:

1. На хосте:

2. Внутри гостя:

Получается двухэтапный grow, но довольно прозрачно.

Docker внутри

Сейчас здравый минимализм:

Пример в госте:

lvcreate -n docker -L 100G vg_guest
mkfs.ext4 /dev/vg_guest/docker
mount /dev/vg_guest/docker /var/lib/docker
# + запись в /etc/fstab
systemctl restart docker

***

Общие «золотые» советы по разметке

Собрано из практики и доков: [computingforgeeks](https://computingforgeeks.com/how-to-configure-a-logical-volume-storage-pool-in-kvm/)

  • Не занимать 100% VG — оставляй минимум 20–30% свободными.
  • Критичные вещи (PostgreSQL, /var/log, backup‑хранилище) выносить в отдельные LV.
  • На KVM‑хосте — один VG под всю «ферму» и LV‑диски для VM, либо thin‑pool с нормальным мониторингом.
  • Если делаешь thin — включай мониторинг usage thin‑pool’а (Prometheus/node‑exporter, zabbix и т.п.), алерты по 70/80/90%.
  • На root‑диски VM (особенно прод) лучше всё же thick‑LV: диск гостя не упирается в неожиданное переполнение thin‑пула.

***

[file-name 000376_2026-06-19_00-21-34.txt]