Btrfs Snapshot ile Sistem Koruması: Adım Adım Rehber

Sistem yöneticiliğinde “keşke yedek alsaydım” cümlesi, en çok duyulan pişmanlıklardan biridir. Bir paket güncellemesi sonrası bozulan sistem, yanlış silinen kritik dosyalar ya da çöken bir uygulama güncellemesi… Bunların hepsi, anlık sistem görüntüleri yani snapshot’ların ne kadar değerli olduğunu acı bir şekilde öğretiyor. Btrfs dosya sistemi, bu noktada geleneksel ext4’ün çok ötesinde bir snapshot altyapısı sunuyor ve bu yazıda bu altyapıyı nasıl etkili kullanacağımızı derinlemesine inceleyeceğiz.

Btrfs Snapshot Nedir ve Neden Önemlidir?

Btrfs (B-tree File System), Linux dünyasında copy-on-write (CoW) mimarisiyle çalışan modern bir dosya sistemidir. Snapshot mekanizması, bu CoW yapısının doğal bir sonucudur. Geleneksel yedekleme yöntemlerinin aksine, Btrfs snapshot’ları anlıktır ve başlangıçta neredeyse sıfır disk alanı kaplar.

Peki bu nasıl çalışır? CoW mimarisinde, bir dosya değiştirildiğinde sistem mevcut veriyi değiştirmez; yeni veriyi farklı bir bloğa yazar ve pointer’ı günceller. Snapshot aldığınızda, o anki tüm pointer’ların bir kopyası çıkarılır. Disk üzerinde herhangi bir veri kopyalanmaz. Zamanla orijinal dosyalarda değişiklik oldukça, snapshot sadece değişen blokları barındırır. Bu yüzden snapshot almak saniyeler içinde tamamlanır.

Btrfs snapshot’larını gerçekten değerli kılan özellikler şunlardır:

  • Anlık alım: Büyük bir sistem için bile snapshot işlemi birkaç saniye sürer
  • Verimli depolama: Yalnızca değişen bloklar için ekstra alan kullanılır
  • Yazılabilir snapshot’lar: Salt okunur değil, üzerinde değişiklik yapılabilir snapshot’lar oluşturulabilir
  • Nested subvolume desteği: Hiyerarşik bir yapıda yönetim imkanı
  • Send/receive ile taşıma: Snapshot’ları başka bir diske veya sunucuya aktarma

Btrfs Subvolume Yapısını Anlamak

Snapshot’lara geçmeden önce subvolume kavramını netleştirmek gerekiyor. Btrfs’de subvolume, bağımsız bir dosya sistemi ağacıdır. Snapshot, temelde bir subvolume’ün anlık kopyasıdır.

Fedora, openSUSE ve modern Ubuntu kurulumlarında Btrfs varsayılan layout’u genellikle şuna benzer:

# Mevcut subvolume'leri listele
sudo btrfs subvolume list /

# Tipik çıktı:
# ID 256 gen 847 top level 5 path @
# ID 257 gen 847 top level 5 path @home
# ID 258 gen 400 top level 5 path @snapshots

Eğer sisteminizde Btrfs kullanıyorsunuz ama subvolume yapısını görmek istiyorsanız, önce Btrfs’nin bağlı olduğu noktayı bulmanız gerekir:

# Btrfs partition'ını bul
findmnt -t btrfs

# Root subvolume'e eriş
sudo mount /dev/sda2 /mnt/btrfs-root -o subvolid=5
sudo btrfs subvolume list /mnt/btrfs-root

İlk Snapshot’ınızı Almak

Teori yeterli, artık pratiğe geçelim. En basit snapshot komutu şu şekildedir:

# Salt okunur snapshot alma (önerilen yedekleme için)
sudo btrfs subvolume snapshot -r / /mnt/btrfs-root/@snapshots/root-$(date +%Y%m%d-%H%M%S)

# Yazılabilir snapshot alma (test ortamı için)
sudo btrfs subvolume snapshot / /mnt/btrfs-root/@snapshots/root-test

Burada -r parametresi önemli. Salt okunur snapshot’lar değiştirilemediği için yedekleme amacıyla daha güvenlidir. Yazılabilir snapshot’lar ise “şunu deneyelim, bozulursa geri döneriz” senaryolarında kullanışlıdır.

Günlük kullanım için tipik bir snapshot alma rutini şöyle olabilir:

#!/bin/bash
# /usr/local/bin/take-snapshot.sh

BTRFS_ROOT="/mnt/btrfs-root"
SNAPSHOT_DIR="$BTRFS_ROOT/@snapshots"
DATE=$(date +%Y%m%d-%H%M%S)
HOSTNAME=$(hostname)

# Root snapshot
sudo btrfs subvolume snapshot -r / "$SNAPSHOT_DIR/root-$DATE"

# Home snapshot
sudo btrfs subvolume snapshot -r /home "$SNAPSHOT_DIR/home-$DATE"

echo "Snapshot alindi: $DATE"
echo "Konum: $SNAPSHOT_DIR"

Gerçek Dünya Senaryosu 1: Sistem Güncellemesi Öncesi Koruma

Bu senaryo sysadmin’lerin en çok işine yarayan durumdur. Production sunucusunda büyük bir paket güncellemesi yapmadan önce snapshot almak, geri dönüş kapısını açık tutar.

#!/bin/bash
# /usr/local/bin/pre-update-snapshot.sh

SNAPSHOT_DIR="/mnt/btrfs-root/@snapshots"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
DESCRIPTION="pre-update"

echo "Guncelleme oncesi snapshot aliniyor..."

# Ana sistem snapshot'i
btrfs subvolume snapshot -r / "$SNAPSHOT_DIR/root-${DESCRIPTION}-${TIMESTAMP}"

if [ $? -eq 0 ]; then
    echo "Snapshot basariyla alindi: root-${DESCRIPTION}-${TIMESTAMP}"
    echo "Guncelleme baslatiliyor..."
    apt-get update && apt-get upgrade -y
else
    echo "HATA: Snapshot alinamadi, guncelleme iptal edildi!"
    exit 1
fi

Bu scripti apt hook’larıyla otomatize etmek de mümkün. /etc/apt/apt.conf.d/80-btrfs-snapshot dosyası oluşturarak:

# /etc/apt/apt.conf.d/80-btrfs-snapshot
DPkg::Pre-Invoke {"if [ -x /usr/local/bin/pre-update-snapshot.sh ]; then /usr/local/bin/pre-update-snapshot.sh; fi"};

Snapshot’tan Geri Dönme

İşte kritik an. Sistem güncelleme sonrası boot etmiyor ya da uygulama çöktü. Snapshot’tan nasıl geri döneceğiz?

Yöntem 1: Subvolume’leri Takas Etmek

Bu yöntem en güvenilir olanıdır. Live USB veya rescue mode’dan yapılır:

# Önce Btrfs'yi root olarak bağla
mount /dev/sda2 /mnt/btrfs-root -o subvolid=5

# Bozuk root'u yeniden adlandır
mv /mnt/btrfs-root/@ /mnt/btrfs-root/@broken-$(date +%Y%m%d)

# Snapshot'ı yeni root olarak ayarla
btrfs subvolume snapshot /mnt/btrfs-root/@snapshots/root-20240115-143022 /mnt/btrfs-root/@

# Yeniden başlat
reboot

Yöntem 2: Default Subvolume Değiştirme

Eğer GRUB üzerinden farklı subvolume’den boot edebiliyorsanız:

# Snapshot'ın ID'sini öğren
btrfs subvolume list /mnt/btrfs-root | grep "root-20240115"

# Default subvolume'ü değiştir (ID 312 örnek)
btrfs subvolume set-default 312 /mnt/btrfs-root

# Sistemi yeniden başlat
reboot

Snapshot Yönetimi ve Temizlik

Snapshot’lar birikir. Haftalarca her gün snapshot alırsanız, disk dolmaya başlar. Otomatik temizlik politikası oluşturmak şart.

#!/bin/bash
# /usr/local/bin/snapshot-cleanup.sh
# Son 7 günlük snapshot'ları tut, eskilerini sil

SNAPSHOT_DIR="/mnt/btrfs-root/@snapshots"
KEEP_DAYS=7

echo "Eski snapshot'lar temizleniyor..."

# 7 günden eski snapshot'ları listele ve sil
find "$SNAPSHOT_DIR" -maxdepth 1 -name "root-*" -mtime +$KEEP_DAYS | while read snapshot; do
    echo "Siliniyor: $snapshot"
    btrfs subvolume delete "$snapshot"
done

# Kalan snapshot'ları listele
echo ""
echo "Mevcut snapshot'lar:"
btrfs subvolume list "$SNAPSHOT_DIR" | grep -E "root-|home-"

Daha sofistike bir yaklaşım için snapshot’lara rotation politikası uygulayabilirsiniz:

  • Günlük: Son 7 gün
  • Haftalık: Son 4 hafta
  • Aylık: Son 3 ay

Bu rotasyonu elle yazmak zahmetlidir. Bu yüzden snapper gibi araçları kullanmak tercih edilebilir.

Snapper ile Profesyonel Snapshot Yönetimi

snapper, openSUSE tarafından geliştirilen ve Btrfs snapshot yönetimini otomatize eden bir araçtır. Ubuntu ve Debian’da da kullanılabilir.

# Snapper kurulumu (Ubuntu/Debian)
sudo apt install snapper

# Root için snapper konfigürasyonu oluştur
sudo snapper -c root create-config /

# Konfigürasyonu görüntüle
sudo snapper -c root get-config

Snapper’ın güzel yanı, değişiklikleri karşılaştırabilmesidir:

# Snapshot listesini gör
sudo snapper list

# İki snapshot arasındaki farkı gör
sudo snapper diff 1..3

# Belirli bir dosyanın değişimini izle
sudo snapper status 1..5 | grep "/etc/nginx"

Snapper ile otomatik snapshot için cron ayarı:

# /etc/cron.d/snapper
# Her saat başı snapshot al
0 * * * * root /usr/bin/snapper -c root create --description "hourly"

# Günde bir kez temizlik yap
0 2 * * * root /usr/bin/snapper -c root cleanup number

Gerçek Dünya Senaryosu 2: Uygulama Deployment’ı Güvence Altına Alma

Bir web uygulaması güncellemesi yapacaksınız. Kod güncelleme, veritabanı migration’ları, konfigürasyon değişiklikleri… Her şeyin ters gidebileceği bir süreç.

#!/bin/bash
# deployment-with-snapshot.sh

APP_NAME="mywebapp"
DEPLOY_DIR="/var/www/$APP_NAME"
SNAPSHOT_DIR="/mnt/btrfs-root/@snapshots"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)

# Deployment öncesi snapshot
echo "[1/5] Deployment oncesi snapshot aliniyor..."
btrfs subvolume snapshot -r / "$SNAPSHOT_DIR/pre-deploy-${APP_NAME}-${TIMESTAMP}"

if [ $? -ne 0 ]; then
    echo "KRITIK: Snapshot alinamadi! Deployment iptal."
    exit 1
fi

# Uygulamayı durdur
echo "[2/5] Uygulama durduruluyor..."
systemctl stop $APP_NAME

# Yeni kodu deploy et
echo "[3/5] Yeni kod deploy ediliyor..."
git -C $DEPLOY_DIR pull origin main

# Servisi başlat ve health check yap
echo "[4/5] Servis baslatiliyor..."
systemctl start $APP_NAME
sleep 10

# Health check
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost/health)

if [ "$HTTP_STATUS" != "200" ]; then
    echo "HATA: Health check basarisiz! (HTTP $HTTP_STATUS)"
    echo "Rollback baslatiliyor..."
    
    systemctl stop $APP_NAME
    git -C $DEPLOY_DIR reset --hard HEAD~1
    systemctl start $APP_NAME
    
    echo "Rollback tamamlandi. Snapshot ID: pre-deploy-${APP_NAME}-${TIMESTAMP}"
    exit 1
fi

echo "[5/5] Deployment basarili!"
echo "Rollback gerekirse: btrfs subvolume set-default pre-deploy-${APP_NAME}-${TIMESTAMP}"

Btrfs Send/Receive ile Offsite Yedekleme

Snapshot’larınızı sadece aynı diskte tutmak, disk arızasına karşı koruma sağlamaz. btrfs send ve btrfs receive komutları, snapshot’ları başka bir sisteme aktarmanızı sağlar.

# İlk tam yedek gönderme
sudo btrfs send /mnt/btrfs-root/@snapshots/root-20240115-120000 | 
    ssh backup-server "sudo btrfs receive /backup/snapshots/"

# Artımlı (incremental) yedek gönderme
# Önceki snapshot: root-20240114-120000
# Yeni snapshot: root-20240115-120000
sudo btrfs send -p /mnt/btrfs-root/@snapshots/root-20240114-120000 
                   /mnt/btrfs-root/@snapshots/root-20240115-120000 | 
    ssh backup-server "sudo btrfs receive /backup/snapshots/"

Artımlı yedekleme burada devreye giriyor ve bu Btrfs’nin en güçlü özelliklerinden biri. -p parametresiyle parent snapshot belirttiğinizde, sadece iki snapshot arasındaki delta aktarılır. Büyük bir sistem için bu, gigabytes yerine megabytes düzeyinde transfer anlamına gelebilir.

Offsite yedekleme için otomatik bir script:

#!/bin/bash
# /usr/local/bin/offsite-backup.sh

BACKUP_SERVER="backup.company.com"
BACKUP_USER="btrfs-backup"
LOCAL_SNAP_DIR="/mnt/btrfs-root/@snapshots"
REMOTE_SNAP_DIR="/backup/server1/snapshots"
SNAP_PREFIX="root"

# Son iki snapshot'ı bul
LATEST=$(ls -t $LOCAL_SNAP_DIR/${SNAP_PREFIX}-* | head -1)
PREVIOUS=$(ls -t $LOCAL_SNAP_DIR/${SNAP_PREFIX}-* | head -2 | tail -1)

echo "Gonderiliyor: $LATEST"
echo "Parent: $PREVIOUS"

if [ "$LATEST" == "$PREVIOUS" ]; then
    echo "Yeni snapshot yok, islem atlaniyor."
    exit 0
fi

# Artimli transfer
btrfs send -p "$PREVIOUS" "$LATEST" | 
    ssh ${BACKUP_USER}@${BACKUP_SERVER} "btrfs receive $REMOTE_SNAP_DIR"

if [ $? -eq 0 ]; then
    echo "Yedekleme basarili: $(basename $LATEST)"
else
    echo "HATA: Yedekleme basarisiz!"
    exit 1
fi

GRUB ile Snapshot’tan Boot Etme

Fedora ve openSUSE gibi dağıtımlarda GRUB, doğrudan Btrfs snapshot’larından boot edebilir. Bu, sistem kurtarma için çok güçlü bir mekanizmadır.

openSUSE’de bu özellik grub-btrfs paketi ile gelir. Ubuntu’da kurulum şöyle yapılır:

# grub-btrfs kurulumu
sudo apt install grub-btrfs

# GRUB konfigürasyonunu güncelle
sudo update-grub

# Artık GRUB menüsünde "Btrfs snapshots" seçeneği görünecek

Snapshot’tan boot ettikten sonra sistemi o snapshot’a kalıcı olarak almak için:

# Hangi snapshot'tan boot ettiğini öğren
mount | grep "subvol="

# Bu snapshot'ı kalıcı root yap
btrfs subvolume set-default [snapshot-id] /

Performans ve Dikkat Edilmesi Gereken Noktalar

Btrfs snapshot kullanırken bazı tuzakları bilmek önemli:

Fragmentation sorunu: Çok sayıda snapshot, CoW mekanizması nedeniyle dosya fragmentasyonunu artırabilir. Veritabanı sunucularında (MySQL, PostgreSQL doğrudan I/O kullanmıyorsa) bu performans sorununa yol açabilir.

# Btrfs'nin durumunu kontrol et
sudo btrfs filesystem df /
sudo btrfs filesystem show /

# Disk kullanımını detaylı gör
sudo btrfs qgroup show /

Quota grupları ile snapshot boyutlarını takip etme:

# Quota aktifleştir
sudo btrfs quota enable /

# Quota gruplarını senkronize et
sudo btrfs quota rescan /

# Her snapshot'ın ne kadar alan kullandığını gör
sudo btrfs qgroup show -reF /

Dikkat edilmesi gereken diğer noktalar:

  • RAID5/6 ile snapshot: Btrfs RAID5/6 hala stabil değil, production’da kullanmayın
  • Çok fazla snapshot: 500+ snapshot performansı olumsuz etkileyebilir, makul bir sayı tutun
  • Snapshot silerken: rm -rf ile değil, mutlaka btrfs subvolume delete kullanın
  • Nested snapshot: Bir subvolume içindeki subvolume’ler otomatik olarak snapshot’a dahil olmaz, dikkatli planlayın

Monitoring ve Uyarı Sistemi

Snapshot’larınızın düzgün alındığını ve disk dolmadığını izlemek için basit bir monitoring scripti:

#!/bin/bash
# /usr/local/bin/snapshot-monitor.sh

SNAPSHOT_DIR="/mnt/btrfs-root/@snapshots"
DISK_THRESHOLD=85  # Yüzde
ALERT_EMAIL="[email protected]"
MIN_SNAPSHOTS=2

# Disk kullanımını kontrol et
DISK_USAGE=$(df "$SNAPSHOT_DIR" | awk 'NR==2 {print $5}' | tr -d '%')

if [ "$DISK_USAGE" -gt "$DISK_THRESHOLD" ]; then
    echo "UYARI: Btrfs disk kullanimi %$DISK_USAGE" | 
        mail -s "UYARI: Snapshot disk dolmak uzere" $ALERT_EMAIL
fi

# Snapshot sayisini kontrol et
SNAPSHOT_COUNT=$(btrfs subvolume list "$SNAPSHOT_DIR" | grep "root-" | wc -l)

if [ "$SNAPSHOT_COUNT" -lt "$MIN_SNAPSHOTS" ]; then
    echo "KRITIK: Sadece $SNAPSHOT_COUNT snapshot mevcut!" | 
        mail -s "KRITIK: Yetersiz snapshot" $ALERT_EMAIL
fi

# Son snapshot'ın yaşını kontrol et (24 saatten eski olmamalı)
LATEST_SNAP=$(ls -t $SNAPSHOT_DIR/root-* 2>/dev/null | head -1)
if [ -z "$LATEST_SNAP" ]; then
    echo "KRITIK: Hic snapshot bulunamadi!" | 
        mail -s "KRITIK: Snapshot bulunamadi" $ALERT_EMAIL
    exit 1
fi

SNAP_AGE=$(find "$LATEST_SNAP" -maxdepth 0 -mtime +1 2>/dev/null)
if [ -n "$SNAP_AGE" ]; then
    echo "UYARI: Son snapshot 24 saatten eski" | 
        mail -s "UYARI: Eski snapshot" $ALERT_EMAIL
fi

echo "Snapshot monitoring tamamlandi. Disk: %$DISK_USAGE, Snapshot sayisi: $SNAPSHOT_COUNT"

Bu scripti cron’a ekleyerek düzenli kontrol yapabilirsiniz:

# Crontab
0 8 * * * root /usr/local/bin/snapshot-monitor.sh

Sonuç

Btrfs snapshot altyapısı, doğru kullanıldığında sistem yöneticisine inanılmaz bir güven duygusu verir. Bir güncelleme yapmadan önce snapshot alıp “ne olursa olsun geri dönerim” diyebilmek, özellikle production sistemlerde çalışma stresini ciddi ölçüde azaltır.

Özetlemek gerekirse, sağlam bir Btrfs snapshot stratejisi şu unsurları içermelidir: Sistem değişikliklerinden önce otomatik snapshot alma, makul bir retention politikası ile eski snapshot’ların temizlenmesi, btrfs send/receive ile offsite kopyalama ve düzenli monitoring ile disk doluluk takibi.

Btrfs’yi henüz kullanmıyorsanız, yeni kurulum yapacağınız sistemlerde tercih etmenizi öneririm. Mevcut ext4 sistemleri Btrfs’ye taşımak ise ayrı bir yazı konusu, ancak kritik veri kaybı riski göz önüne alındığında temiz kurulum her zaman daha güvenlidir.

Son bir not: Snapshot, tam yedeklemenin yerini tutmaz. Snapshot’lar aynı disk üzerinde yaşar ve diskin fiziksel arızasında hepsi birlikte gider. Bu yüzden btrfs send/receive ile farklı bir fiziksel ortama kopyalama yapmak, gerçek anlamda felaket kurtarma stratejisinin vazgeçilmez parçasıdır.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir