Basi

LVM in Linux: volumi fisici, gruppi e volumi logici nella pratica

Aggiornato: · Skillaria.Top

LVM (Logical Volume Manager) in Linux è uno strato tra i dischi e i file system: i dischi diventano volumi fisici (PV), si uniscono in un gruppo di volumi (VG) e da lì si ricavano volumi logici (LV) di qualsiasi dimensione. Il vantaggio principale è che un volume si può estendere al volo con lvextend -r, aggiungere al gruppo un nuovo disco senza fermare il servizio e fotografare con uno snapshot prima di un'operazione rischiosa.

LVM (Logical Volume Manager) è il gestore di volumi logici di Linux, che separa i file system dai dischi fisici. Invece di legare /var in modo rigido alla partizione /dev/sdb1, si inseriscono i dischi in un pool comune e da lì si ricavano volumi della dimensione necessaria. Quando lo spazio non basta, il volume cresce con un solo comando, senza riavvio e senza fermare il servizio. Qui vedremo come è organizzato LVM in Linux, come creare i volumi da zero, come estenderli, come fare uno snapshot ed evitare gli errori più comuni che fanno perdere dati.

A cosa serve LVM se esistono le partizioni normali

Una partizione normale è un blocco continuo di un solo disco. La sua dimensione si decide al momento del partizionamento, e può crescere solo se subito dopo c'è spazio libero. Quando il disco finisce, bisogna comprarne uno nuovo, spostare i dati, riscrivere /etc/fstab e fermare il servizio per tutto il tempo necessario.

LVM risolve tre problemi:

  • Dimensioni flessibili. Un volume logico si può ingrandire (e per ext4 anche ridurre) in qualsiasi momento.
  • Unione dei dischi. Più dischi fisici diventano un unico pool; un solo volume può trovarsi su due dischi contemporaneamente.
  • Snapshot. Un'istantanea del volume prima di un aggiornamento, di una migrazione del database o di un'altra operazione rischiosa.

Per questo gli installer di Ubuntu Server, RHEL, Rocky e AlmaLinux propongono LVM per impostazione predefinita, e sui server dedicati ai dati viene quasi sempre usato.

I tre livelli di LVM: PV, VG e LV

Tutta la logica di LVM si riassume in tre concetti. Un paragone utile: i dischi sono sacchi di farina, il gruppo è il magazzino comune, i volumi logici sono le porzioni che si prelevano dal magazzino.

LivelloCos'èEsempio di nomeSi crea con
PV (Physical Volume)disco o partizione preparati per LVM/dev/sdb, /dev/sdc1pvcreate
VG (Volume Group)pool che unisce uno o più PVdata_vgvgcreate
LV (Logical Volume)volume ricavato da un VG; su di esso si crea il file system/dev/data_vg/applvcreate

Dentro il VG lo spazio è diviso in extent (PE, physical extents), blocchi di dimensione fissa, di default 4 MiB. Un volume logico è semplicemente un insieme di extent, che non devono essere contigui e possono stare su dischi diversi. Per questo un volume è così facile da ingrandire: LVM gli aggiunge extent liberi da qualsiasi posizione.

Il dispositivo di un volume logico è raggiungibile da due percorsi equivalenti: /dev/data_vg/app e /dev/mapper/data_vg-app. Sotto il cofano è un dispositivo device-mapper del kernel.

Come vedere cosa c'è già

Prima verifica che il pacchetto sia installato: su Debian e Ubuntu si tratta di lvm2 (sudo apt install lvm2), nella famiglia RHEL è installato di default. Per una panoramica ci sono comandi brevi e comandi dettagliati:

$ sudo pvs
  PV         VG      Fmt  Attr PSize   PFree
  /dev/sdb   data_vg lvm2 a--  <20.00g      0
  /dev/sdc   data_vg lvm2 a--  <20.00g  <10.00g

$ sudo vgs
  VG      #PV #LV #SN Attr   VSize  VFree
  data_vg   2   1   0 wz--n- 39.99g <10.00g

$ sudo lvs
  LV   VG      Attr       LSize  Pool Origin Data%  Meta%
  app  data_vg -wi-ao---- 30.00g

I dettagli si ottengono con pvdisplay, vgdisplay e lvdisplay. La visione d'insieme, insieme alle normali partizioni, la dà lsblk: i volumi logici compaiono con il tipo lvm.

$ lsblk /dev/sdb /dev/sdc
NAME             MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sdb                8:16   0  20G  0 disk
└─data_vg-app    253:0    0  30G  0 lvm  /srv/app
sdc                8:32   0  20G  0 disk
└─data_vg-app    253:0    0  30G  0 lvm  /srv/app

Si vede che il volume app da 30 GB si trova contemporaneamente su due dischi da 20 GB: con una partizione normale non sarebbe possibile.

LVM da zero: dal disco grezzo al volume montato

Supponiamo che al server sia stato aggiunto un disco vuoto /dev/sdb e che per i dati dell'applicazione serva un volume da 15 GB. Controlla il nome del disco con lsblk due volte: tutti i comandi qui sotto cancellano i dati presenti sul dispositivo indicato.

Passo 1. Creare il volume fisico

$ sudo pvcreate /dev/sdb
  Physical volume "/dev/sdb" successfully created.

Si può assegnare a LVM l'intero disco, oppure creare prima una partizione con fdisk o parted di tipo «Linux LVM» e usare quella (/dev/sdb1). La partizione è più chiara per gli altri amministratori e protegge da una partizione scritta per errore sopra LVM; l'intero disco, invece, è più facile da estendere nel cloud.

Passo 2. Creare il gruppo di volumi

$ sudo vgcreate data_vg /dev/sdb
  Volume group "data_vg" successfully created

Passo 3. Ricavare il volume logico

$ sudo lvcreate -n app -L 15G data_vg
  Logical volume "app" created.

Il flag -L indica una dimensione assoluta, -l una dimensione in extent o in percentuale: -l 100%FREE prende tutto lo spazio libero del gruppo, -l 50%VG metà del gruppo. Lasciare nel VG una riserva di spazio libero è una buona abitudine: in seguito può servire a qualsiasi volume o a uno snapshot.

Passo 4. File system e montaggio

$ sudo mkfs.ext4 /dev/data_vg/app
$ sudo mkdir -p /srv/app
$ sudo mount /dev/data_vg/app /srv/app
$ df -h /srv/app
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/data_vg-app   15G   24K   14G   1% /srv/app

Per montare il volume dopo il riavvio, aggiungi una riga in /etc/fstab. Per i volumi logici il percorso /dev/mapper/... è stabile, quindi si può usare lui oppure l'UUID ottenuto da blkid:

/dev/mapper/data_vg-app  /srv/app  ext4  defaults  0 2

Verifica la riga con sudo mount -a prima del riavvio: un errore in fstab può lasciare il server in modalità di emergenza.

Come estendere un volume LVM senza fermare il servizio

È il motivo principale per apprezzare LVM. Il volume cresce mentre il file system è montato e l'applicazione continua a scrivere. Il procedimento dipende dal fatto che nel gruppo ci sia spazio libero oppure no.

Se nel VG c'è spazio libero

$ sudo vgs data_vg
  VG      #PV #LV #SN Attr   VSize   VFree
  data_vg   1   1   0 wz--n- <20.00g <5.00g

$ sudo lvextend -r -L +4G /dev/data_vg/app
  Size of logical volume data_vg/app changed from 15.00 GiB to 19.00 GiB.
  Logical volume data_vg/app successfully resized.
resize2fs 1.47.0
Filesystem at /dev/mapper/data_vg-app is mounted on /srv/app; on-line resizing required

Il flag fondamentale è -r (--resizefs): subito dopo aver ingrandito il volume ridimensiona anche il file system. Senza di esso il volume diventa più grande, ma df -h mostra la dimensione precedente, perché il file system non sa dello spazio aggiunto. È l'errore più frequente: in quel caso basta eseguire a mano resize2fs per ext4 oppure xfs_growfs per XFS.

$ sudo resize2fs /dev/data_vg/app      # ext4, si indica il dispositivo
$ sudo xfs_growfs /srv/app             # XFS, si indica il punto di mount

Attenzione alla differenza: -L +4G aggiunge 4 GB, mentre -L 4G imposta la dimensione finale a 4 GB. Per assegnare al volume tutto lo spazio rimasto usa -l +100%FREE.

Se lo spazio nel VG è finito: aggiungere un disco

Collega il nuovo disco (nel cloud, collega il volume), trovalo con lsblk e aggiungilo al gruppo:

$ sudo pvcreate /dev/sdc
$ sudo vgextend data_vg /dev/sdc
  Volume group "data_vg" successfully extended
$ sudo lvextend -r -l +100%FREE /dev/data_vg/app

Tre comandi senza alcun tempo di fermo. Il file system ora si estende su due dischi, e l'applicazione non se ne accorge.

Se il disco è stato ingrandito nel cloud

Nel cloud spesso conviene non aggiungere un disco ma ingrandire quello esistente. In tal caso il kernel vede la nuova dimensione del dispositivo, e il volume fisico va esteso con pvresize:

$ sudo pvresize /dev/sdb
  Physical volume "/dev/sdb" changed
$ sudo lvextend -r -l +100%FREE /dev/data_vg/app

Se il PV è stato creato su una partizione (/dev/sdb1), prima estendi la partizione, ad esempio con growpart /dev/sdb 1 del pacchetto cloud-guest-utils, e solo dopo esegui pvresize /dev/sdb1.

È possibile ridurre un volume LVM

Sì, ma non per tutti i file system e non a caldo. XFS non si può ridurre affatto: solo ricreare con trasferimento dei dati. Ext4 si riduce, ma soltanto smontato:

$ sudo umount /srv/app
$ sudo lvreduce -r -L 10G /dev/data_vg/app

Con il flag -r LVM controlla da solo il file system (e2fsck) e lo comprime prima di ridurre il volume. Senza -r è facile tagliare il volume più piccolo del file system e danneggiare i dati. Prima di ridurre fai sempre una copia di backup.

Snapshot LVM: un'istantanea del volume prima di un'operazione rischiosa

Lo snapshot è una fotografia istantanea di un volume logico. Si crea in una frazione di secondo e non copia i dati: LVM lavora con il principio copy-on-write e salva nello snapshot solo i blocchi che cambiano sul volume originale dopo la sua creazione. Quindi lo snapshot richiede nel VG solo lo spazio per le modifiche, non per l'intero volume.

$ sudo lvcreate -s -n app_before_upgrade -L 2G /dev/data_vg/app
  Logical volume "app_before_upgrade" created.

$ sudo lvs data_vg
  LV                 VG      Attr       LSize  Origin Data%
  app                data_vg owi-aos--- 19.00g
  app_before_upgrade data_vg swi-a-s---  2.00g app    0.01

La colonna Data% mostra quanto è pieno lo spazio riservato alle modifiche. Se arriva al 100%, lo snapshot classico diventa invalido e non resta che cancellarlo. Dimensiona lo spazio con un margine rispetto alle modifiche previste, controlla gli snapshot lunghi con lvs ed estendili con lvextend quando serve.

Come tornare allo snapshot

Se l'aggiornamento è andato male, riporta il volume allo stato del momento dello snapshot:

$ sudo umount /srv/app
$ sudo lvconvert --merge /dev/data_vg/app_before_upgrade
  Merging of volume data_vg/app_before_upgrade started.
$ sudo mount /srv/app

Dopo il merge lo snapshot scompare. Se il volume non si può smontare (ad esempio è la radice del sistema), il merge viene rinviato alla successiva attivazione del volume, cioè al riavvio.

Se tutto è andato bene

Lo snapshot si elimina, così non rallenta le scritture e non occupa spazio:

$ sudo lvremove /dev/data_vg/app_before_upgrade

Uno snapshot conviene montarlo in sola lettura per ricavare una copia di backup coerente di un sistema in funzione: mount -o ro e poi copia con rsync o tar. Per XFS aggiungi l'opzione nouuid, altrimenti il montaggio viene rifiutato perché l'UUID coincide con quello dell'originale.

LVM e RAID: non confondere i compiti

LVM da solo non protegge dal guasto di un disco. Se un volume è esteso su due dischi e uno dei due si rompe, si perde l'intero volume, non solo la metà. Per la tolleranza ai guasti si mette sotto LVM un RAID (mdadm), oppure si usa la modalità specchio integrata in LVM (lvcreate --type raid1 -m 1).

E né il RAID né gli snapshot sostituiscono il backup. Lo snapshot sta sugli stessi dischi dell'originale, mentre il RAID ricopia fedelmente anche un rm -rf sbagliato. Serve una copia separata su un altro supporto.

Riepilogo dei comandi LVM

CompitoComando
Panoramica di PV, VG, LVpvs, vgs, lvs
Creare un volume fisicopvcreate /dev/sdb
Creare un gruppovgcreate data_vg /dev/sdb
Aggiungere un disco al gruppovgextend data_vg /dev/sdc
Creare un volumelvcreate -n app -L 15G data_vg
Estendere volume e file systemlvextend -r -L +5G /dev/data_vg/app
Estendere il PV dopo l'ingrandimento del discopvresize /dev/sdb
Snapshotlvcreate -s -n snap -L 2G /dev/data_vg/app
Ripristino dallo snapshotlvconvert --merge /dev/data_vg/snap
Rimuovere un disco dal gruppopvmove /dev/sdb, poi vgreduce data_vg /dev/sdb
Eliminare un volumelvremove /dev/data_vg/app

Errori tipici

  • Il volume è stato esteso, ma df mostra la dimensione vecchia. È stato dimenticato -r. Esegui resize2fs oppure xfs_growfs.
  • Insufficient free space. Nel gruppo non ci sono extent liberi: controlla con vgs e aggiungi un disco con vgextend oppure estendi il PV.
  • Device /dev/sdc excluded by a filter. Sul disco sono rimaste una vecchia partizione o la firma di un file system. Se i dati non servono davvero, cancellale con wipefs -a /dev/sdc.
  • Lo snapshot è diventato Invalid. Lo spazio per le modifiche si è riempito al 100%. Non è recuperabile: va eliminato e in futuro bisogna riservargli più spazio.

Conclusioni

LVM in Linux è composto da tre strati: i volumi fisici (PV) si uniscono in un gruppo (VG), dal quale si ricavano i volumi logici (LV). Questo offre ciò che non danno le partizioni normali: estensione del volume al volo con lvextend -r, aggiunta di dischi senza fermare il servizio e snapshot prima delle modifiche rischiose. Ricorda però che LVM non sostituisce né il RAID né i backup. Partizionamento, LVM, RAID e quote sono trattati in modo pratico nella lezione del corso Linux.

Domande frequenti

Posso passare a LVM una partizione già in uso con dati?

Direttamente no: pvcreate sovrascrive l'inizio del dispositivo. Bisogna creare LVM su un altro disco, copiare i dati con rsync, correggere fstab e solo dopo liberare la vecchia partizione.

LVM rallenta il disco?

Senza snapshot il costo di device-mapper è praticamente impercettibile. Gli snapshot classici attivi rallentano le scritture sul volume originale a causa del copy-on-write, quindi non conviene tenerli per settimane.

Serve LVM su un computer domestico o un portatile?

Non è obbligatorio, ma è utile con la cifratura del disco (LUKS con LVM sopra) e se vuoi cambiare le dimensioni delle partizioni senza ripartizionare. Sui server con dati è di fatto lo standard.

Cos'è il thin provisioning in LVM?

Sono i volumi sottili: si crea un pool (lvcreate --type thin-pool) e i volumi al suo interno occupano spazio reale solo man mano che si scrivono i dati. Così si possono assegnare ai volumi più spazio di quanto sia fisicamente presente, ma bisogna controllare il riempimento del pool.

Come tolgo un disco da un gruppo di volumi senza perdere dati?

Sposta gli extent su altri dischi del gruppo con pvmove /dev/sdb (serve spazio libero sufficiente), poi esegui vgreduce data_vg /dev/sdb e pvremove /dev/sdb.

Impara l’argomento in video

Questo argomento è trattato in modo approfondito, con pratica, nel corso «Linux: с нуля до уверенного администрирования».

Vai al corso