~/yazilar/lvm-ile-disk-yonetimi

LVM ile diski büyütmek ve snapshot almak

8 dk okuma

E: Write error - write (28: No space left on device)

apt güncelleme yaparken ya da bir servis log yazarken bu satır çıkıyorsa ilk bakılacak yer belli:

df -h /
Filesystem                         Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv   19G   19G     0 100% /

Cihaz adı /dev/mapper/... ile başlıyorsa kök dosya sistemi LVM üzerinde. Ubuntu Server kurulumunda disk düzenini varsayılan bıraktıysan durum büyük ihtimalle bu. İyi haber şu: çoğu durumda sunucuyu kapatmadan, birkaç komutla yer açabiliyorsun.

Önce nefes alacak kadar yer açıyorum. Dolu bir kök dosya sisteminde bazı araçlar geçici dosya bile yazamıyor:

sudo journalctl --vacuum-size=200M
sudo apt clean

Sonra asıl işe geçiyorum. Ama önce LVM'in üç katmanını oturtmak lazım, yoksa komutlar ezber kalıyor.

PV, VG, LV

En altta physical volume (PV) var. Bir disk ya da disk bölümü, LVM'e "bunu kullanabilirsin" diye verilmiş hali. PV'ler bir araya gelip volume group (VG) oluşturuyor, bunu ortak bir alan havuzu gibi düşünebilirsin. Logical volume (LV) ise bu havuzdan ayrılan, üzerine dosya sistemi kurulan parça. df çıktısında gördüğün şey LV.

Bu ayrımın faydası şu: dosya sistemi diskin fiziksel sınırlarına bağlı kalmıyor. Havuza yer eklersen LV'yi büyütebiliyorsun, havuzda boş yer bırakırsan snapshot alabiliyorsun.

lsblk
sudo pvs
sudo vgs
sudo lvs
NAME                      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sda                         8:0    0   40G  0 disk
├─sda1                      8:1    0    1M  0 part
├─sda2                      8:2    0    2G  0 part /boot
└─sda3                      8:3    0   38G  0 part
  └─ubuntu--vg-ubuntu--lv 252:0    0   19G  0 lvm  /

  PV         VG        Fmt  Attr PSize   PFree
  /dev/sda3  ubuntu-vg lvm2 a--  <38.00g 19.00g

  VG        #PV #LV #SN Attr   VSize   VFree
  ubuntu-vg   1   1   0 wz--n- <38.00g 19.00g

  LV        VG        Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  ubuntu-lv ubuntu-vg -wi-ao---- 19.00g

Bu tabloda dikkat çeken şey VFree değeri: havuzda 19 GB boş yer duruyor ama kök dosya sistemi dolmuş. Ubuntu kurulum sihirbazı bazı sürümlerde kök LV'ye VG'nin tamamını değil bir kısmını veriyor. Sebebi tam da bu yazının konusu: kalan alanı ileride büyütmek ya da snapshot için kullanabil diye.

/boot bölümünün LVM dışında, ayrı bir bölüm olduğuna da dikkat et. Snapshot kısmında buna geri döneceğim.

VG'de boş yer varsa

En kolay durum bu. Tek komut:

sudo lvextend -r -L +10G ubuntu-vg/ubuntu-lv
  Size of logical volume ubuntu-vg/ubuntu-lv changed from 19.00 GiB (4864 extents) to 29.00 GiB (7424 extents).
  Logical volume ubuntu-vg/ubuntu-lv successfully resized.
resize2fs ...
Filesystem at /dev/mapper/ubuntu--vg-ubuntu--lv is mounted on /; on-line resizing required
The filesystem on /dev/mapper/ubuntu--vg-ubuntu--lv is now 7602176 (4k) blocks long.

-r seçeneği LV'yi büyüttükten sonra dosya sistemini de büyütüyor. ext4 için resize2fs, XFS için xfs_growfs çağrılıyor ve ikisi de bağlıyken (mounted) büyüyebiliyor. -r unutulunca LV büyüyor ama df hâlâ eski boyutu gösteriyor. Panik yok, dosya sistemini sonradan elle büyütebilirsin:

sudo resize2fs /dev/ubuntu-vg/ubuntu-lv   # ext4
sudo xfs_growfs /                          # XFS, bağlama noktasını alıyor

Boş alanın hepsini vermek için -l +100%FREE da kullanılabiliyor ama ben bunu yapmıyorum. Gerektiği kadar büyütüp gerisini havuzda bırakıyorum. Büyütmek her zaman kolay, küçültmek ise çoğu zaman mümkün değil. Havuzda boş yer olmadan snapshot da alamıyorsun.

Hipervizörde diski büyüttüysen

Havuzda yer kalmamışsa sanal makinenin diskini hipervizörden büyütüyorsun. Diyelim 40 GB'lık diski 80 GB yaptın. Bu noktada Linux tarafında dört katman var ve her birini sırayla büyütmek gerekiyor: disk, bölüm, PV, LV.

Bazı hipervizörler sanal makinede snapshot varken disk büyütmeye izin vermiyor. Önce hipervizör tarafındaki snapshot'ları temizlemen gerekebilir.

Kernel yeni boyutu görsün

Çoğu zaman kernel yeni boyutu kendisi fark ediyor. Etmediyse SCSI diski yeniden taramasını söylüyorsun:

echo 1 | sudo tee /sys/class/block/sda/device/rescan
sudo dmesg | tail -n 3
lsblk /dev/sda
sd 2:0:0:0: [sda] 167772160 512-byte logical blocks: (85.9 GB/80.0 GiB)
sda: detected capacity change from 83886080 to 167772160

dmesg içinde şu uyarıyı da görebilirsin:

GPT:Alternate GPT header not at the end of the disk.
GPT:Use GNU Parted to correct GPT errors.

Disk büyüyünce GPT'nin diskin sonunda durması gereken yedek başlığı artık sonda kalmıyor. Bir sonraki adımdaki growpart bunu da düzeltiyor.

Bölümü büyüt

sudo growpart /dev/sda 3
CHANGED: partition=3 start=... old: size=... end=... new: size=... end=...

Disk ile bölüm numarası arasında boşluk var, /dev/sda3 yazarsan kullanım hatası alırsın. growpart cloud-guest-utils paketinden geliyor ve sunucu kurulumlarında genelde hazır. Bir şart var: büyüteceğin bölüm diskteki son bölüm olmalı. Varsayılan Ubuntu düzeninde öyle. Arkasında bir swap bölümü varsa önce onu kaldırmak gerekiyor.

PV ve LV

sudo pvresize /dev/sda3
  Physical volume "/dev/sda3" changed
  1 physical volume(s) resized or updated / 0 physical volume(s) not resized

Artık havuzda yeni yer var, sudo vgs ile görürsün. Gerisi bir önceki bölümle aynı:

sudo lvextend -r -L +20G ubuntu-vg/ubuntu-lv
df -h /

Hiçbir adımda sunucuyu yeniden başlatmadın, servisler çalışmaya devam etti.

Yeni disk eklemek

Diski büyütmek yerine sanal makineye ikinci bir disk de ekleyebilirsin. Disk çalışırken eklendiyse kernel'in görmesi için SCSI veriyollarını tara:

echo "- - -" | sudo tee /sys/class/scsi_host/host*/scan
lsblk

Yeni diski var olan havuza katmak iki komut:

sudo pvcreate /dev/sdb
sudo vgextend ubuntu-vg /dev/sdb

Bundan sonra lvextend her zamanki gibi çalışıyor. Yalnız artık VG iki diske yayılmış durumda ve kök dosya sistemi iki diskin birden sağlam olmasına bağlı. Sanal makinede, altta yedekli bir depolama varsa bu kabul edilebilir. Fiziksel sunucuda RAID'siz iki diske böyle yaymak riskini ikiye katlamak demek.

Veri dizinleri için ben farklı bir yol tercih ediyorum: yeni diske ayrı bir VG ve LV açıp veriyi oraya bağlıyorum. Böylece kök dosya sistemi ile veri birbirinden bağımsız büyüyor, istersen o diski hipervizörde farklı bir depolama katmanına da koyabiliyorsun.

sudo pvcreate /dev/sdb
sudo vgcreate veri-vg /dev/sdb
sudo lvcreate -n pg -L 50G veri-vg
sudo mkfs.ext4 /dev/veri-vg/pg

/etc/fstab satırı:

/dev/veri-vg/pg  /var/lib/postgresql  ext4  defaults,noatime  0  2

LV yolları disk sırası değişse de sabit kaldığı için fstab'da UUID yerine doğrudan LV yolunu kullanabiliyorsun. Satırı ekledikten sonra yeniden başlatmadan önce sudo mount -a ile dene. fstab'daki hatalı bir satır sunucuyu açılışta bakım moduna düşürüyor.

Küçültmek hakkında

Kısa cevap: mümkünse hiç küçültme. XFS hiç küçültülemiyor. ext4 küçültülebiliyor ama sadece bağlı değilken, yani kök dosya sistemi için kurtarma ortamından açman gerekiyor. lvreduce -r bunu yapıyor ama sırayı ya da boyutu yanlış verirsen dosya sistemini bozabiliyorsun. Küçük adımlarla büyütmenin asıl sebebi bu.

Snapshot

LVM snapshot, bir LV'nin o anki halini donduruyor. Klasik snapshot copy-on-write çalışıyor: snapshot alındıktan sonra asıl LV'de bir blok ilk kez değiştiğinde eski hali snapshot alanına kopyalanıyor. Snapshot'a verdiğin boyut, bu süre içinde değişecek veri kadar olmalı, LV'nin tamamı kadar değil.

Snapshot havuzdaki boş alandan yer alıyor. Yukarıda 100%FREE kullanmamamın bir nedeni de buydu.

sudo lvcreate --snapshot --name kok-snap --size 5G ubuntu-vg/ubuntu-lv
sudo lvs
  Logical volume "kok-snap" created.

  LV        VG        Attr       LSize  Pool Origin    Data%  Meta%  Move Log Cpy%Sync Convert
  kok-snap  ubuntu-vg swi-a-s---  5.00g      ubuntu-lv 0.01
  ubuntu-lv ubuntu-vg owi-aos--- 29.00g

Data% sütunu snapshot alanının ne kadarının dolduğunu gösteriyor. Bunu izlemek gerekiyor, sebebini aşağıda yazıyorum.

Snapshot'tan tutarlı yedek almak

Benim en çok işime yarayan kullanım bu. Çalışan bir dosya sisteminden yedek alırken dosyalar yedek sırasında değişiyor. Snapshot'ı salt okunur bağlayıp yedeği oradan alınca bütün dosyalar aynı anın görüntüsü oluyor:

sudo mkdir -p /mnt/snap
sudo mount -o ro /dev/ubuntu-vg/kok-snap /mnt/snap
# /mnt/yedek: yedek sunucusundan bağlanmış bir paylaşım
sudo rsync -a --delete /mnt/snap/ /mnt/yedek/web01/
sudo umount /mnt/snap
sudo lvremove -y ubuntu-vg/kok-snap

XFS kullanıyorsan snapshot asıl dosya sistemiyle aynı UUID'yi taşıdığı için bağlarken -o ro,nouuid gerekiyor.

Geri dönmek

Bir değişiklik ters gittiyse snapshot'ı asıl LV'ye geri birleştirebiliyorsun:

sudo lvconvert --merge ubuntu-vg/kok-snap
  Delaying merge since origin is open.
  Merging of snapshot ubuntu-vg/kok-snap will occur on next activation of ubuntu-vg/ubuntu-lv.

Kök dosya sistemi kullanımda olduğu için birleştirme bir sonraki açılışa kalıyor. sudo reboot sonrası LV, snapshot alındığı ana dönmüş oluyor ve snapshot kendiliğinden siliniyor. Kök dışındaki bir LV'yi önce umount edersen birleştirme hemen yapılıyor.

Her şey yolunda gittiyse snapshot'ı silmeyi unutma:

sudo lvremove ubuntu-vg/kok-snap
Do you really want to remove active logical volume ubuntu-vg/kok-snap? [y/n]: y
  Logical volume "kok-snap" successfully removed.

Snapshot'ın sınırları

Kullanışlı bir araç ama yanlış beklentiyle kullanılınca can yakıyor. Bilmen gerekenler:

Snapshot aynı diskte, aynı VG'de duruyor. Disk giderse ikisi birlikte gidiyor. Yedeği başka bir yere aldığın sürece snapshot sadece o yedeği tutarlı yapmanın bir aracı.

Dolarsa geçersiz oluyor. Data% 100'e ulaşınca snapshot kullanılamaz hale geliyor ve geri dönüş imkânı kayboluyor. lvs çıktısında Attr sütununda I harfi görürsün. Snapshot'ı otomatik büyütmek için /etc/lvm/lvm.conf içindeki activation bölümünde iki ayar var:

snapshot_autoextend_threshold = 70
snapshot_autoextend_percent = 20

Doluluk yüzde 70'i geçince snapshot yüzde 20 büyütülüyor. Bunun çalışması için havuzda boş yer olması ve LVM izlemesinin (dmeventd) açık olması gerekiyor.

Yazma performansını düşürüyor. Klasik snapshot açıkken asıl LV'deki her ilk yazma, eski bloğun kopyalanmasıyla birlikte yapılıyor. Snapshot'ı günlerce açık bırakma. İşin bitince sil.

/boot snapshot'ın içinde değil. Kök LV'nin snapshot'ını alıp kernel güncellemesi yaparsan, sonra geri döndüğünde /lib/modules eski haline dönüyor ama /boot altındaki yeni kernel ve initramfs yerinde kalıyor. Sunucu, modülleri olmayan bir kernel ile açılmaya çalışıyor. Sürüm yükseltme gibi işlerden önce sanal makinedeysen hipervizör snapshot'ı daha güvenli, çünkü bütün diski kapsıyor. LVM snapshot ile yapacaksan /boot içeriğini de ayrıca yedekle.

Veritabanları için tutarlılık garanti değil. Snapshot, elektrik kesilmiş bir makinenin diski kadar tutarlı. Çoğu veritabanı bundan kendini kurtarabiliyor ama buna güvenip veritabanı yedeğini atlamak riskli. Veritabanının kendi yedekleme aracını kullan, snapshot'ı ancak veritabanı yazmaları durdurulmuşken al.

Birden fazla snapshot'ı uzun süre tutman gerekiyorsa thin provisioning ile oluşturulan thin snapshot'lar bu performans sorununu büyük ölçüde azaltıyor. Ama thin pool'un kendisi de dolabilen bir şey ve izlenmesi gerekiyor. Başka bir yazının konusu.

Sıradaki yazı: Windows Server'ı masaüstü olmadan yönetmek