LVM

Siehe auch

Der in Linux enthaltene Logical Volume Manager (LVM) abstrahiert Festplatten, Partitionen und Dateisysteme. Mit Hilfe des LVM können im Gegensatz zu fdisk dynamisch veränderbare Logical Volumes erzeugt werden, die sich auch über mehrere Festplatten hinweg erstrecken oder im RAID-Verbund gespiegelt werden können. Sofern Logical Volumes mit Dateisystemen wie Ext4 oder XFS arbeiten, lassen sie sich jederzeit in ihrer Grösse ändern (zumindest lassen sie sich problemlos vergrössern), abgespeicherte Daten bleiben dabei erhalten.

Begriffe:

  • Physical Volume (PV): Physische Geräte wie HDDs, SSDs, einzelne Partitionen wie /dev/sda2 etc. werden damit zu von LVM nutzbaren Geräten. Das PV lässt sich auch direkt auf einer Festplatte erstellen, also beispielsweise direkt auf /dev/sdc. Eine Partitionierung ist nicht nötig. Ein PV enthält am Anfang des Geräts ein Label.

  • Volume Group (VG): Eine VG fasst PVs zu einer virtuellen, benannten Festplatte zusammen, z.B. /dev/rhel.

  • Logical Volume (LV): Virtuelle Partitionen/virtuelle Block-Devices in einer VG, die vom OS genutzt werden. Prominente Beispiele sind /dev/rhel/swap und /dev/rhel/root.

Die Darstellung vg_.../lv_... entspricht also logisch gesehen disk/partition.

Schematische Darstellung:

LV      | LV
----------------
       VG
----------------
PV    PV    PV
----------------
sda2  sdb1  sdc

Die Befehle des LVM sind auf allen drei Ebenen gleich konstruiert, und werden beim Erstellen (als Eselsbrücke) in der Reihenfolge „PhyVoLo“ angewendet:

  • PV: pvscan, pvdisplay, pvcreate, pvremove, pvs

  • VG: vgscan, vgdisplay, vgcreate, vgextend, vgreduce, vgremove, vgs

  • LV: lvscan, lvdisplay, lvcreate, lvextend, lvreduce, lvremove, lvs

VG erstellen (einfachstes Beispiel)

Ziel: ein /backup-Verzeichnis soll über zusätzliche Disks/Partitionen separat im System eingehängt und bei Bedarf jederzeit vergrössert werden können.

Angenommen, das System verfügt über die nutzbare Partition /dev/sdb1; diese soll als /backup-Verzeichnis auf Basis einer neuen Volume Group dienen.

Zunächst gibt man dem LVM die physischen Volumes bekannt:

pvcreate /dev/sdb1

Anschliessend lassen sich die PVs zu einer Volume Group zusammenfassen:

VG=vg_backup
vgcreate $VG /dev/sdb1

Tipp

Mit vgcreate --physicalextentsize gibt man die Physical Extent Size der PVs vor - das kann man nicht bei den PVs selbst konfigurieren.

Logische Volumes erzeugen, optional mit Grössenangabe der logischen Partition:

LV=lv_backup
# using the complete capacity
lvcreate --extents +100%FREE --name $LV $VG

# with 1GB size
lvcreate --size 1G --name $LV $VG

Am Ende muss das Dateisystem erzeugt werden, hier XFS:

mkfs --type xfs /dev/$VG/$LV

Jetzt lässt sich das Dateisystem wie üblich mounten und verwenden:

mkdir /backup
mount /dev/$VG/$LV /backup

Sollen die Änderungen nach einem Reboot erhalten bleiben, muss das neue Volume in der Datei /etc/fstab angegeben werden:

/etc/fstab
/dev/mapper/vg_backup-lv_backup  /backup xfs defaults 0 0

Bemerkung

Die Schreibweise /dev/vg_backup/lv_backup oder /dev/mapper/vg_backup-lv_backup ist äquivalent, genau wie /dev/mapper/rhel-root vs. /dev/rhel/root. Am Ende verweisen diese Einträge auf die Kernel „Device Mapper“-Einträge /dev/dm-0, /dev/dm-1 usw.

VG mit 2 LVs erstellen

Ziel: ein /backup-Verzeichnis mit den beiden Unterverzeichnissen daily und weekly einrichten. Die beiden Unterverzeichnisse sollen bei Bedarf als eigene „Partitionen“ unabhängig voneinander vergrössert werden können.

Angenommen, das System verfügt über zwei Festplatten /dev/sdb und /dev/sdc. Die erste enthält zwei Partitionen /dev/sdb1 und /dev/sdb2, von denen die zweite nutzbar ist. /dev/sdc ist unpartitioniert.

Zunächst gibt man dem LVM die physischen Volumes bekannt:

pvcreate /dev/sdb2 /dev/sdc

Anschliessend lassen sich diese zu einer Volume Group zusammenfassen:

VG=vg_backup
vgcreate $VG /dev/sdb2 /dev/sdc

Logische Volumes erzeugen, optional (aber in dem Beispiel hier sinnvoll) mit Grössenangabe der logischen Partition. daily wird initial 77G gross, weekly erhält den Rest:

lvcreate --size 77G --name lv_daily $VG
lvcreate --extents 100%FREE --name lv_weekly $VG

Am Ende muss das Dateisystem erzeugt werden, hier XFS:

mkfs --type xfs /dev/mapper/$VG-lv_daily
mkfs --type xfs /dev/mapper/$VG-lv_weekly

Jetzt lässt sich das Dateisystem mounten und verwenden:

mkdir -p /backup/{daily,weekly}
mount /dev/$VG/lv_daily /backup/daily
mount /dev/$VG/lv_weekly /backup/weekly

Sollen die Änderungen nach einem Reboot erhalten bleiben, muss das neue Volume in der Datei /etc/fstab angegeben werden:

/etc/fstab
...
/dev/mapper/vg_backup-lv_daily  /backup/daily  xfs defaults 0 0
/dev/mapper/vg_backup-lv_weekly /backup/weekly xfs defaults 0 0

Volume vergrössern

Physischen Speicher vergrössern - mehrere Möglichkeiten

1.) Mit zusätzlicher Partition oder zusätzlicher Disk arbeiten

Neue Partitionen mit Hilfe von fdisk oder parted vom Typ 8e anlegen. Im nachfolgenden Beispiel soll das Volume /dev/rhel/root um die Partition /dev/sdb1 vergrössert werden:

pvs
vgs
lvs
DEVICE=/dev/sdb1

pvcreate $DEVICE

Den Namen und die Grösse des VG und des LV ermittelt man mit vgs und lvs. Wenn noch Platz im PV vorhanden ist (siehe pvs > „PFree“), muss natürlich kein weiteres PV hinzugefügt werden.

Volume Group um die neuen physischen Volumes erweitern:

VG=rhel; LV=root

vgextend $VG $DEVICE

2.) Bestehende/vorhandene Partition erweitern (wenn noch Platz auf der Disk)

Im Beispiel sollte Partition /dev/vda3 mehr vom noch zur Verfügung stehenden Platz erhalten.

lsblk
DEVICE=/dev/vda; PARTNO=3

# extend a partition in a partition table to fill available space
# growpart [OPTIONS] DISK PARTITION-NUMBER
dnf -y install cloud-utils-growpart
growpart $DEVICE $PARTNO

pvresize --verbose $DEVICE$PARTNO

In lvextend muss entweder die neue Gesamtgrösse des LV angegeben werden, oder der Platz, der hinzugefügt werden soll:

VG=rhel; LV=root

# Auf 10 GB Gesamtgrösse erweitern.
lvextend --size 10G /dev/$VG/$LV

# Um zusätzliche 4 GB erweitern. Man beachte das "+".
lvextend --size +4G /dev/$VG/$LV

# Auf die maximal zur Verfügung stehende Grösse erweitern.
lvextend --extents +100%FREE /dev/$VG/$LV

Jetzt noch das Dateisystem im laufenden Betrieb vergrössern:

  • für Ext4: resize2fs /dev/$VG/$LV

  • für XFS: xfs_growfs /dev/$VG/$LV

  • für btrfs: btrfs filesystem resize max / (/ = Mount Point)

Überprüfen mit:

lsblk
df -hT

Volume verkleinern

Bei XFS nicht möglich - hier hilft nur Backup, Format, Restore. Bei Ext4 möglich, sofern das LV nicht verwendet wird:

umount --force --lazy /backup/daily
lvreduce --size -4G /dev/$VG/$LV
resize2fs /dev/$VG/$LV
mount --all

Volume löschen

Das Löschen eines Volumes geschieht umgekehrt zur Erzeugung („PhyVoLo“) einer Volume Group.

umount --force --lazy /backup/daily

lvremove --force /dev/$VG/lv_daily

# optional deactivate VG
vgchange --activate n $VG
vgremove /dev/$VG
# Do you really want to remove volume group "data-vg" containing 1 logical volumes? [y/n]: y
# Do you really want to remove and DISCARD logical volume data-vg/data-lv? [y/n]: y

pvremove /dev/sdb1 /dev/sdb2 /dev/sdc

Nicht vergessen, den Eintrag in der /etc/fstab zu entfernen.

LVM-Snapshots

Wozu sind LVM-Snapshots gut? Beispiel: sich laufend ändernde, offen gehaltene Dateien sollen auf einen entfernten Server synchronisiert, das Quellsystem darf aber nicht heruntergefahren werden - das für DB-Server typische Szenario. Die Lösung liegt in der Erstellung plus Mounting eines neuen LVM-Snapshots, dessen Sync auf den entfernten Server und dem Entfernen des Snapshots.

# Create a COW Snapshot on the current $VG/$LV (because a size is specified)
# Allow 1GB amount of space that can be used for saving COW blocks as writes occur to the origin
lvcreate --snapshot $VG/$LV --size 1GB --name snappy
mount /dev/$VG/snappy /mnt/lvm-snapshot
# rsync goes here ...
# e.g. rsync /mnt/lvm-snapshot/anypath remote:/path/to/whatever
umount /dev/$VG/snappy
lvremove $VG/snappy

Troubleshooting

pvcreate /dev/sd{d,e,f}: Device /dev/sdd not found (or ignored by filtering)

Der verbose-Parameter -vvv hilft:

pvcreate -vvv /dev/sdd
/dev/sde: Skipping: Partition table signature found

Die Platte enthält oder enthielt schon mal ein Dateisystem, was sich z.B. bei ZFS mit fdisk nicht vollständig wegputzen lässt. Die Lösung ist hier ein dd if=/dev/zero of=/dev/sdd bs=100M && sync, um die ersten 100MB der Platte zu nullen.

Built on 2024-03-28