LVM Thin Provisioning ile Snapshot Optimizasyonu
Depolama yönetiminde en sık karşılaşılan sorunlardan biri şu: Bir sunucuya 2 TB disk tahsis ediyorsunuz, ama o diskin büyük çoğunluğu aylar boyunca boş kalıyor. Öte yandan snapshot almak istediğinizde ise her seferinde kaynak hacmin tam kopyasını çıkarmak zorunda kalıyorsunuz. LVM Thin Provisioning tam bu noktada hayat kurtarır. Hem disk alanını akıllıca kullanır hem de snapshot mekanizmasını dramatik biçimde optimize eder. Bu yazıda üretim ortamlarında gerçekten işe yarayan bir Thin Provisioning kurulumu yapacağız ve snapshot stratejilerini derinlemesine inceleyeceğiz.
Thin Provisioning Nedir, Neden Önemlidir?
Klasik LVM mantığında bir logical volume oluşturduğunuzda, o volume’e atadığınız alan fiziksel diskten hemen rezerve edilir. 500 GB’lık bir LV yaratıyorsanız, 500 GB’ı o anda “harcamış” oluyorsunuz. Thin provisioning ise farklı çalışır: Bir volume’e “500 GB’ın var” dersiniz ama fiziksel alan yalnızca veri yazıldıkça tüketilir. Bu yaklaşıma overcommit denir ve doğru yönetildiğinde disk kullanım verimliliğini ciddi ölçüde artırır.
Snapshot tarafında ise fark daha da belirgindir. Geleneksel LVM snapshot’larında copy-on-write mekanizması, her yazma işleminde kaynak bloğun önce snapshot alanına kopyalanmasını gerektirir. Bu hem performans maliyeti hem de alan yönetimi karmaşıklığı demektir. Thin snapshot’larda ise her iki volume da aynı thin pool üzerinde yaşar ve değişen bloklar metadata üzerinden izlenir. Sonuç: Daha hızlı snapshot, daha az alan tüketimi, daha temiz bir yönetim modeli.
Ortam Hazırlığı ve Gereksinimler
Başlamadan önce sistemin hazır olduğundan emin olalım. Önce mevcut LVM versiyonunu ve araçları kontrol edelim:
# LVM2 sürümünü kontrol et
lvm version
# Gerekli paketlerin kurulu olduğunu doğrula
dpkg -l lvm2 thin-provisioning-tools 2>/dev/null || rpm -qa | grep -E "lvm2|device-mapper"
# thin-provisioning-tools kurulumu (Debian/Ubuntu)
apt-get install -y lvm2 thin-provisioning-tools
# RHEL/CentOS için
yum install -y lvm2 device-mapper-persistent-data
thin-provisioning-tools paketi kritik öneme sahiptir. İçinde thin_check, thin_repair, thin_dump gibi araçlar bulunur ve thin pool’un tutarlılığını korumak için bunlara ihtiyaç duyarsınız.
Senaryo olarak elimizde iki adet disk olduğunu varsayalım: /dev/sdb (500 GB) ve /dev/sdc (500 GB). Bu diskleri birleştirerek bir volume group oluşturacak ve üzerinde thin provisioning yapılandıracağız.
# Diskleri PV olarak işaretle
pvcreate /dev/sdb /dev/sdc
# PV durumunu doğrula
pvs -o +pv_used,pv_free
# Volume group oluştur
vgcreate vg_production /dev/sdb /dev/sdc
# VG'yi kontrol et
vgs -o +vg_free,vg_extent_size vg_production
Thin Pool Oluşturma
Thin pool, thin volume’lerin ve snapshot’ların içinde yaşadığı havuzdur. İki temel bileşenden oluşur: data LV (asıl veriyi tutan kısım) ve metadata LV (hangi bloğun nerede olduğunu izleyen kısım). LVM bunları sizin için otomatik yönetebilir ama üretim ortamında metadata’yı ayrı bir cihaza almak akıllıca olur.
# Metadata için ayrı bir LV oluştur (önerilen yaklaşım)
# Metadata boyutu: pool boyutunun yaklaşık %0.1'i, minimum 2MB
lvcreate -L 1G -n tp_meta vg_production /dev/sdb
# Data için ana LV oluştur
lvcreate -L 800G -n tp_data vg_production /dev/sdc
# İkisini birleştirerek thin pool yap
lvconvert --type thin-pool
--poolmetadata vg_production/tp_meta
vg_production/tp_data
# Pool'u incele
lvs -o +lv_layout,lv_role,thin_count vg_production
Alternatif olarak LVM’in her şeyi otomatik yapmasına da izin verebilirsiniz:
# Tek komutla thin pool oluşturma (otomatik metadata boyutu)
lvcreate -L 800G --thinpool vg_production/tp_main
# Chunk size ayarı (varsayılan 64K, SSD için 512K önerilir)
lvcreate -L 800G --thinpool vg_production/tp_main --chunksize 512K
Chunk size seçimi performansı doğrudan etkiler. HDD tabanlı sistemlerde 64K-128K, SSD tabanlı sistemlerde 256K-512K tercih edin. Büyük sequential yazmalarda büyük chunk size avantajlıdır, küçük random yazmalarda ise küçük chunk size daha verimli çalışır.
Thin Volume Oluşturma ve Yönetimi
Pool hazır olduğunda içine thin volume’ler oluşturabilirsiniz. İşte overcommit’in gücü burada ortaya çıkar:
# 800GB'lık pool içinde birden fazla "büyük" volume yarat
lvcreate -V 200G --thin -n lv_database vg_production/tp_main
lvcreate -V 150G --thin -n lv_webapp vg_production/tp_main
lvcreate -V 100G --thin -n lv_logs vg_production/tp_main
lvcreate -V 300G --thin -n lv_backup vg_production/tp_main
# Toplam tanımlanmış alan: 750GB, ama gerçekte kullanılan çok daha az olabilir
# Tüm volume'leri listele
lvs -o lv_name,lv_size,data_percent,metadata_percent vg_production
Oluşturduğunuz volume’leri mount etmek için önce dosya sistemi oluşturmanız gerekir:
# Dosya sistemi oluştur
mkfs.xfs /dev/vg_production/lv_database
mkfs.ext4 -E lazy_itable_init=0,lazy_journal_init=0 /dev/vg_production/lv_webapp
# Mount noktaları oluştur ve bağla
mkdir -p /data/{database,webapp,logs,backup}
mount /dev/vg_production/lv_database /data/database
mount /dev/vg_production/lv_webapp /data/webapp
# fstab'a ekle (discard/trim desteğiyle)
echo "/dev/vg_production/lv_database /data/database xfs defaults,discard 0 0" >> /etc/fstab
Thin Snapshot Alma ve Yönetimi
İşte asıl konu burasıdır. Thin snapshot’lar, geleneksel LVM snapshot’larından köklü biçimde farklıdır. Geleneksel snapshot’ta kaynak volume’e bağımlı bir yapı varken, thin snapshot tam bağımsız bir noktadır ve üzerine ayrıca yazabilirsiniz.
# Database volume'ünün snapshot'ını al
lvcreate -s --name snap_db_$(date +%Y%m%d_%H%M)
vg_production/lv_database
# Birden fazla snapshot kontrol
lvs -o lv_name,origin,snap_percent,lv_time vg_production
# Snapshot'ı sadece okuma amaçlı mount et
mkdir -p /mnt/snap_db_restore
mount -o ro /dev/vg_production/snap_db_20241215_1430 /mnt/snap_db_restore
# Belirli bir dosyayı kurtarma
cp /mnt/snap_db_restore/postgresql/data/pg_wal/important.wal /data/database/recovery/
# İşimiz bitince unmount et
umount /mnt/snap_db_restore
Thin snapshot’ların güzel yanlarından biri: Bir snapshot’tan yeni bir volume türetebilirsiniz. Test ortamları kurmak için mükemmeldir:
# Production snapshot'ından test ortamı oluştur
lvcreate -s --name lv_database_test
vg_production/snap_db_20241215_1430
# Test volume'ünü ayrı bir mount noktasına bağla
mkdir -p /data/database_test
mount /dev/vg_production/lv_database_test /data/database_test
# Artık production'ı etkilemeden test ortamında çalışabilirsiniz
Otomatik Snapshot Scripti
Gerçek dünyada snapshot yönetimini elle yapmak sürdürülebilir değildir. Aşağıdaki script, belirli volume’lerin düzenli snapshot’larını alır ve eski olanları temizler:
#!/bin/bash
# /usr/local/bin/thin_snapshot_manager.sh
set -euo pipefail
VG="vg_production"
RETENTION_DAYS=7
LOG_FILE="/var/log/thin_snapshots.log"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Snapshot alınacak volume'ler
VOLUMES=(
"lv_database"
"lv_webapp"
"lv_logs"
)
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
check_pool_space() {
local pool_name="$1"
local usage
usage=$(lvs --noheadings -o data_percent "$VG/$pool_name" 2>/dev/null | tr -d ' ')
if (( $(echo "$usage > 85" | bc -l) )); then
log "UYARI: Pool $pool_name doluluk orani %$usage - kritik esik!"
# Sistem yoneticisine mail gonder
echo "Thin pool doluluk uyarisi: %$usage" |
mail -s "LVM Thin Pool Uyari - $(hostname)" [email protected]
return 1
fi
log "Pool $pool_name doluluk: %$usage - normal"
return 0
}
take_snapshot() {
local vol="$1"
local snap_name="${vol}_snap_${TIMESTAMP}"
log "Snapshot aliniyor: $VG/$vol -> $snap_name"
if lvcreate -s --name "$snap_name" "$VG/$vol" >> "$LOG_FILE" 2>&1; then
log "Snapshot basarili: $snap_name"
else
log "HATA: Snapshot alinamadi: $vol"
return 1
fi
}
cleanup_old_snapshots() {
local vol="$1"
log "Eski snapshot'lar temizleniyor: $vol"
# Belirli volume'e ait snapshot'lari listele, tarihe gore sirala
while IFS= read -r snap; do
local snap_date
snap_date=$(echo "$snap" | grep -oP 'd{8}')
local snap_epoch
snap_epoch=$(date -d "$snap_date" +%s 2>/dev/null || echo 0)
local cutoff_epoch
cutoff_epoch=$(date -d "$RETENTION_DAYS days ago" +%s)
if [[ "$snap_epoch" -lt "$cutoff_epoch" ]]; then
log "Siliniyor: $snap"
lvremove -f "$VG/$snap" >> "$LOG_FILE" 2>&1 &&
log "Silindi: $snap" ||
log "HATA: Silinemedi: $snap"
fi
done < <(lvs --noheadings -o lv_name "$VG" | grep "${vol}_snap_" | tr -d ' ')
}
# Ana mantik
main() {
log "=== Thin Snapshot Manager basliyor ==="
# Pool durumunu kontrol et
check_pool_space "tp_main" || {
log "Pool dolu, snapshot alinmiyor!"
exit 1
}
# Her volume icin islem yap
for vol in "${VOLUMES[@]}"; do
if lvs "$VG/$vol" &>/dev/null; then
cleanup_old_snapshots "$vol"
take_snapshot "$vol"
else
log "Volume bulunamadi, atlaniyor: $vol"
fi
done
log "=== Tum islemler tamamlandi ==="
}
main "$@"
Bu scripti cron’a ekleyin:
# Her gece 02:00'de calistir
echo "0 2 * * * root /usr/local/bin/thin_snapshot_manager.sh" > /etc/cron.d/thin_snapshots
# Script'e calistirma izni ver
chmod +x /usr/local/bin/thin_snapshot_manager.sh
Pool Doluluk Yönetimi ve Autoextend
Thin pool dolduğunda volume’ler yazma hatası vermeye başlar. Bu felaketi önlemek için iki katmanlı bir strateji izleyin: Otomatik genişletme ve proaktif izleme.
# lvm.conf'ta autoextend ayarla
# /etc/lvm/lvm.conf dosyasini duzenle
cat >> /etc/lvm/lvm.conf << 'EOF'
activation {
thin_pool_autoextend_threshold = 80
thin_pool_autoextend_percent = 20
}
EOF
# lvmd servisini yeniden baslat
systemctl restart lvm2-monitor
# Manuel pool genisletme (acil durumda)
lvextend -L +100G vg_production/tp_main
# Veya yuzde olarak
lvextend -l +25%FREE vg_production/tp_main
thin_pool_autoextend_threshold pool’un yüzde kaçında dolduğunda devreye gireceğini, thin_pool_autoextend_percent ise ne kadar büyütüleceğini belirler. Yukarıdaki örnekte: Pool %80’e ulaşınca mevcut boyutunun %20’si kadar otomatik büyür.
Monitoring ve Sorun Giderme
Thin provisioning’in en kritik noktası izlemedir. Pool dolup taşarsa felakete giden yol açılır.
# Detayli pool durumu
lvs -a -o +devices,seg_count,origin,snap_percent,data_percent,metadata_percent
vg_production 2>/dev/null | column -t
# dmsetup ile dusuk seviye durum
dmsetup status vg_production-tp_main-tpool
# Thin metadata'yi kontrol et (pool unmounted olmali)
thin_check /dev/mapper/vg_production-tp_main_tmeta
# Metadata dump (sorun analizi icin)
thin_dump /dev/mapper/vg_production-tp_main_tmeta > /tmp/thin_metadata.xml
# Hasar gorme durumunda repair
thin_repair -i /dev/mapper/vg_production-tp_main_tmeta
-o /dev/vg_production/tp_meta_repair
Yaygın bir sorun: Metadata dolu olduğunda pool kilitlenir. Bu durumda:
# Metadata LV'yi buyut
lvextend -L +500M vg_production/tp_main_tmeta
# Pool'u yeniden aktive et
lvchange -an vg_production/tp_main
lvchange -ay vg_production/tp_main
# Sorunlu snapshot'lari tespit et ve kaldir
lvs -o lv_name,lv_attr,snap_percent vg_production | grep "s"
Performans Tuning: Discard ve TRIM
SSD tabanlı sistemlerde TRIM/discard desteği thin provisioning ile çok iyi entegre çalışır. Bir thin volume’den veri silindiğinde, bu bloğun artık kullanılmadığı pool’a bildirilir ve fiziksel blok geri kazanılır:
# Online discard (mount parametresiyle)
mount -o discard /dev/vg_production/lv_database /data/database
# Toplu discard (zamanlayici ile daha verimli)
# Gunde bir kez fstrim calistir
systemctl enable fstrim.timer
systemctl start fstrim.timer
# Manuel fstrim
fstrim -v /data/database
# XFS icin ek optimizasyon
mkfs.xfs -f -d agcount=8 -l size=128m
/dev/vg_production/lv_database
# Readahead ayarla (HDD icin yuksek tut)
blockdev --setra 4096 /dev/vg_production/lv_database
Gerçek Dünya Senaryosu: PostgreSQL Yedekleme Pipeline’ı
Birleştirici bir senaryo verelim. Kritik bir PostgreSQL veritabanını thin snapshot kullanarak yedekliyoruz:
#!/bin/bash
# PostgreSQL tutarli snapshot + yedekleme
set -euo pipefail
PG_DATA="/data/database"
VG="vg_production"
LV="lv_database"
SNAP_NAME="snap_pg_$(date +%Y%m%d_%H%M)"
BACKUP_DEST="/data/backup/postgres"
PG_USER="postgres"
# 1. PostgreSQL'i backup moduna al (WAL akisini garantile)
echo "Backup modu baslatiliyor..."
psql -U "$PG_USER" -c "SELECT pg_backup_start('thin_snap', true);" postgres
# 2. Snapshot al
echo "Thin snapshot aliniyor..."
lvcreate -s --name "$SNAP_NAME" "$VG/$LV"
# 3. PostgreSQL backup modunu sonlandir
echo "Backup modu sonlandiriliyor..."
psql -U "$PG_USER" -c "SELECT pg_backup_stop();" postgres
# 4. Snapshot'i mount et
mkdir -p "/mnt/$SNAP_NAME"
mount -o ro,noatime "/dev/mapper/${VG}-${SNAP_NAME}" "/mnt/$SNAP_NAME"
# 5. rsync ile hedef dizine kopyala
echo "Veri kopyalaniyor..."
rsync -avz --delete
--exclude="pg_wal"
"/mnt/$SNAP_NAME/" "$BACKUP_DEST/"
# 6. Temizlik
umount "/mnt/$SNAP_NAME"
rmdir "/mnt/$SNAP_NAME"
# Snapshot'i sil (ihtiyaca gore saklanabilir)
lvremove -f "$VG/$SNAP_NAME"
echo "Yedekleme tamamlandi: $BACKUP_DEST"
Bu pipeline sayesinde PostgreSQL yalnızca birkaç saniyeliğine (adım 1-3 arası) backup modunda kalır. Asıl kopyalama işlemi snapshot üzerinde gerçekleştiği için production I/O minimum düzeyde etkilenir.
Thin Pool Migrate ve Genişletme Stratejileri
Üretim ortamında zaman içinde pool yetersiz kalabilir. Yeni disk ekleyerek pool’u büyütmek oldukça kolaydır:
# Yeni diski sisteme tanit
pvcreate /dev/sdd
# Mevcut VG'ye ekle
vgextend vg_production /dev/sdd
# PV durumunu kontrol et
pvs vg_production
# Pool'u yeni diskle genislet
lvextend -l +100%FREE vg_production/tp_main
# Veya sadece belirli miktarda
lvextend -L +200G vg_production/tp_main
# Thin volume'lerin dosya sistemini de genislet
lvextend -L +50G vg_production/lv_database
xfs_growfs /data/database
# veya ext4 icin:
resize2fs /dev/vg_production/lv_webapp
Sonuç
LVM Thin Provisioning, doğru yapılandırıldığında depolama yönetiminde gerçekten devrim niteliğinde bir yaklaşım sunar. Snapshot maliyetleri dramatik biçimde düşer, disk kullanım verimliliği artar ve test ortamı oluşturmak dakikalar içinde mümkün hale gelir.
Bununla birlikte, göz ardı edilemeyecek bazı kritik noktalar var. Pool doluluk takibi bir lüks değil zorunluluktur. Autoextend mekanizmasını mutlaka aktive edin ve üstüne bir de Prometheus/Grafana veya Zabbix ile pool doluluk metriklerini izleyin. Overcommit oranını %200’ün üzerine çıkarmayın: Kağıt üzerinde 10 TB tahsis edip 500 GB fiziksel disk kullanan bir yapı güzel görünür ama gerçek kullanım aniden artarsa felakete zemin hazırlar. Metadata LV’yi ayrı bir hızlı cihaza koymak da ihmal edilmemesi gereken bir performans optimizasyonudur.
Son olarak thin pool ve thin volume yapılarını thin_check ile düzenli aralıklarla kontrol edin. Metadata bozulması nadir ama yıkıcı bir durumdur ve erken tespitle kolaylıkla atlatılabilir. Artık elinizde hem teorik altyapı hem de production’a hazır script’ler var; tek yapmanız gereken test ortamında bir kez deneyip güven duymak.
