Bacula ile Retention Policy: Yedek Saklama Süresi Nasıl Yapılandırılır?

Yedek aldım, işim bitti diye düşünüyorsanız, retention policy konusunu atlamışsınız demektir. Bacula kullanıcılarının en çok ihmal ettiği konulardan biri tam da bu: aldığınız yedeklerin ne kadar süre saklanacağını doğru yapılandırmak. Disk dolduğunda ya da eski bir yedeği geri yüklemek istediğinizde “nerede bu yedek?” diye sorduğunuzda iş işten geçmiş olur. Bu yazıda Bacula’da retention policy kavramını, nasıl çalıştığını ve gerçek senaryolara uygun nasıl yapılandırılacağını adım adım anlatacağım.

Retention Policy Nedir ve Neden Önemlidir?

Retention policy, Bacula’nın yedek kayıtlarını ve yedek dosyalarını ne kadar süre saklayacağını belirleyen kural setidir. Burada iki farklı katman var ve bunları birbirine karıştırmak çok yaygın bir hata:

  • Catalog Retention: Bacula’nın veritabanında (catalog) job kayıtlarının, dosya listelerinin ve ilgili metadata’nın ne kadar süre tutulacağı
  • Volume Retention: Fiziksel yedek dosyalarının (volume’ların) üzerine yazılmadan önce ne kadar süre korunacağı

İkisi birbirinden bağımsız çalışır. Catalog’dan bir kaydı silmek, fiziksel yedeği silmez. Fiziksel volume’un süresi dolmak, catalog’daki kaydı silmez. Bu ayrımı kafanıza kazıyın çünkü ilerleyen bölümlerde çok işe yarayacak.

Retention policy’nin düzgün kurgulanmaması şu sonuçlara yol açar:

  • Disk/tape dolarak yeni yedeklerin alınamaması
  • Gereksiz yere eski yedeklerin silinmesi ve recovery senaryolarında veri kaybı yaşanması
  • Catalog veritabanının şişmesi ve sorgu performansının düşmesi
  • Uyumluluk gereksinimlerinin (KVKK, ISO 27001 vb.) karşılanamaması

Bacula’da Retention Parametreleri

Bacula’da retention sürelerini üç temel nesnede tanımlıyorsunuz: Client, Pool ve FileSet. Her birinin rolü farklı.

Client Düzeyinde Retention

Client tanımında üç kritik parametre var:

  • File Retention: Catalog’da dosya kayıtlarının saklanma süresi
  • Job Retention: Catalog’da job kayıtlarının saklanma süresi
  • AutoPrune: Süresi dolan kayıtların otomatik temizlenip temizlenmeyeceği
# /etc/bacula/bacula-dir.conf içinde Client tanımı
Client {
  Name = webserver01-fd
  Address = 192.168.1.10
  FDPort = 9102
  Catalog = MyCatalog
  Password = "gizli_sifre_buraya"
  File Retention = 60 days
  Job Retention = 180 days
  AutoPrune = yes
}

Bu örnekte, webserver01 için dosya kayıtları 60 gün, job kayıtları 180 gün tutulacak. AutoPrune açık olduğu için Bacula her job tamamlandığında eski kayıtları otomatik temizleyecek.

Pool Düzeyinde Retention

Pool tanımı, fiziksel volume’ların davranışını belirler. Buradaki Volume Retention parametresi en kritik olanı:

# Pool tanımı - günlük full yedekler için
Pool {
  Name = Daily-Full-Pool
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 30 days
  Maximum Volume Bytes = 10G
  Maximum Volumes = 20
  Label Format = "Daily-Full-"
}
# Pool tanımı - haftalık yedekler için
Pool {
  Name = Weekly-Pool
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 90 days
  Maximum Volume Bytes = 50G
  Maximum Volumes = 15
  Label Format = "Weekly-"
}
# Pool tanımı - aylık arşiv yedekler için
Pool {
  Name = Monthly-Archive-Pool
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 365 days
  Maximum Volume Bytes = 200G
  Maximum Volumes = 24
  Label Format = "Monthly-Archive-"
}

Burada dikkat edin: Recycle = yes dediğinizde, Volume Retention süresi dolmuş ve başka volume yoksa Bacula bu volume’u yeniden kullanabilir. Recycle = no yaparsanız volume sonsuza kadar korunur ama bu da diskinizi doldurur.

Zaman Birimi Sözdizimi

Bacula’da süreleri yazarken şu formatları kullanabilirsiniz:

  • seconds veya secs: Saniye
  • minutes veya mins: Dakika
  • hours: Saat
  • days: Gün
  • weeks: Hafta
  • months: Ay (30 gün olarak hesaplanır)
  • quarters: 3 aylık periyot
  • years: Yıl

Örneğin 6 months yerine 180 days yazmak daha öngörülebilir davranış sağlar çünkü Bacula’da “ay” kavramı her zaman 30 gün olarak işlenir.

Gerçek Dünya Senaryosu: Küçük Şirket Yedekleme Stratejisi

Diyelim ki 20 kişilik bir şirkette sysadmin olarak çalışıyorsunuz. 3 sunucunuz var: web sunucusu, veritabanı ve dosya sunucusu. Compliance gereksinimleriniz yok ama “geçen ayki haliyle dosyaları geri getir” gibi taleplere hazırlıklı olmak istiyorsunuz. İşte bu senaryo için makul bir yapılandırma:

# Günlük incremental yedekler - 14 gün sakla
Pool {
  Name = Incremental-Pool
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 14 days
  Maximum Volume Bytes = 5G
  Maximum Volumes = 30
  Label Format = "Inc-"
}

# Haftalık differential yedekler - 30 gün sakla
Pool {
  Name = Differential-Pool
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 30 days
  Maximum Volume Bytes = 20G
  Maximum Volumes = 10
  Label Format = "Diff-"
}

# Aylık full yedekler - 1 yıl sakla
Pool {
  Name = Monthly-Full-Pool
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 365 days
  Maximum Volume Bytes = 100G
  Maximum Volumes = 12
  Label Format = "MonFull-"
}

Bu yapıda her pool farklı bir retention süresiyle çalışır. Günlük incrementaller 2 hafta sonra recycle edilebilir hale gelir, aylık full’lar ise 1 yıl boyunca korunur.

Job Tanımlarında Pool Bağlantısı

Pool tanımları tek başına yetmez, job’larınızın doğru pool’u kullanması gerekir:

# Günlük incremental job
Job {
  Name = "DailyIncremental-webserver"
  JobDefs = "DefaultJob"
  Level = Incremental
  Client = webserver01-fd
  FileSet = "WebserverFiles"
  Schedule = "DailySchedule"
  Storage = File1
  Pool = Incremental-Pool
  Write Bootstrap = "/var/lib/bacula/webserver01-incremental.bsr"
}

# Haftalık differential job
Job {
  Name = "WeeklyDifferential-webserver"
  JobDefs = "DefaultJob"
  Level = Differential
  Client = webserver01-fd
  FileSet = "WebserverFiles"
  Schedule = "WeeklySchedule"
  Storage = File1
  Pool = Differential-Pool
  Write Bootstrap = "/var/lib/bacula/webserver01-differential.bsr"
}

# Aylık full backup job
Job {
  Name = "MonthlyFull-webserver"
  JobDefs = "DefaultJob"
  Level = Full
  Client = webserver01-fd
  FileSet = "WebserverFiles"
  Schedule = "MonthlySchedule"
  Storage = File1
  Pool = Monthly-Full-Pool
  Write Bootstrap = "/var/lib/bacula/webserver01-full.bsr"
}

bconsole ile Retention Yönetimi

Yapılandırma dosyalarını düzenlemek dışında, çalışan bir sistemde retention yönetimi için bconsole kullanmanız gerekir. İşte günlük işlerde lazım olan komutlar:

# bconsole'a giriş
bconsole

# Mevcut volume'ların retention durumunu listele
*list volumes

# Belirli bir pool'daki volume'ları göster
*list volumes pool=Daily-Full-Pool

# Süresi dolmuş volume'ları prune et (catalog kayıtlarını temizle)
*prune volume

# Belirli bir volume'u manuel prune et
*prune volume=Daily-Full-0001

# Volume'ların detaylı bilgisini görüntüle
*llist volumes pool=Monthly-Full-Pool

# Süresi dolmuş job'ları prune et
*prune jobs client=webserver01-fd

Prune işlemi catalog’daki kayıtları temizler ama volume’u fiziksel olarak silmez. Volume’u tekrar kullanılabilir hale getirmek için recycle mekanizması devreye girer.

Volume Durumları ve Recycle Mekanizması

Bacula’da bir volume’un lifecycle’ı şöyle ilerler:

  • Append: Aktif olarak yazılıyor
  • Full: Doldu, yeni iş yazılamaz
  • Used: Kullanıldı ama henüz retention süresi dolmadı
  • Purged: Tüm job’lar prune edildi, recycle için hazır
  • Recycle: Üzerine yazılmaya hazır
  • Error: Hata durumu
  • Archive: Arşivlendi

Retention süresi dolup prune edilen bir volume otomatik olarak Purged durumuna geçer. Eğer Pool’da Recycle = yes varsa Bacula bu volume’u bir sonraki yazma işlemi için yeniden kullanabilir.

# Purged volume'ları recycle için işaretle
*purge volume action=recycle pool=Incremental-Pool

# Volume'un durumunu manuel olarak değiştir
*update volume=Inc-0001 volstatus=Purged

# Volume retention süresini güncelle
*update volume=Inc-0001 volretention=21

AutoPrune ve Manuel Prune Farkı

AutoPrune açıkken Bacula her job tamamlandığında, storage doludurken veya yeni volume gerektiğinde otomatik prune işlemi yapar. Bu genellikle iyidir ama bazı durumlarda beklenmedik davranışlara yol açabilir.

Manuel prune ise tam kontrol sağlar. Maintenance window’larında ya da disk dolmadan önce proaktif olarak yapmak isteyebilirsiniz:

# Tüm client'lar için expired job kayıtlarını temizle
*prune jobs

# Tüm expired file kayıtlarını temizle
*prune files

# Tüm expired volume'ları temizle
*prune volumes

# Detaylı çıktı ile prune
*prune jobs client=dbserver-fd yes

Veritabanı Sunucusu İçin Özel Retention: Gerçek Senaryo

Çalıştığım bir projede Oracle veritabanı sunucusu için retention policy belirlerken yasal gereksinimler devreye girdi. Finans sektöründe 7 yıllık veri saklama zorunluluğu vardı. İşte o yapılandırmanın Bacula karşılığı:

# Veritabanı sunucusu client tanımı
Client {
  Name = dbserver-oracle-fd
  Address = 10.0.1.50
  FDPort = 9102
  Catalog = MyCatalog
  Password = "db_gizli_sifre"
  File Retention = 365 days
  Job Retention = 2555 days  # 7 yıl
  AutoPrune = yes
}

# 7 yıllık arşiv pool
Pool {
  Name = LongTerm-Archive-Pool
  Pool Type = Backup
  Recycle = no              # Kesinlikle silinmesin
  AutoPrune = no            # Manuel kontrol
  Volume Retention = 2555 days
  Maximum Volume Bytes = 500G
  Maximum Volumes = 100
  Label Format = "LTA-"
  Storage Type = File
}

# Yıllık full backup job
Job {
  Name = "YearlyFull-OracleDB"
  JobDefs = "DefaultJob"
  Level = Full
  Client = dbserver-oracle-fd
  FileSet = "OracleDataFiles"
  Schedule = "YearlySchedule"
  Storage = LongTermStorage
  Pool = LongTerm-Archive-Pool
  Priority = 5
  Write Bootstrap = "/var/lib/bacula/oracle-yearly.bsr"
  Messages = Standard
}

Burada Recycle = no ve AutoPrune = no kombinasyonu kritik. Yasal yükümlülük olan durumlarda otomasyona tamamen güvenmemek, manuel onay mekanizması kurmak daha güvenli.

Retention Policy’yi Test Etmek

Yapılandırmanızı yazdınız ama doğru çalışıyor mu? Test etmek için birkaç yöntem:

# Belirli bir job'ın ne zaman prune edileceğini kontrol et
bconsole
*list joblog jobid=123

# Volume'un detaylı bilgisini ve retention süresini göster
*llist volume=Daily-Full-0001

# Simülasyon: Prune yapmadan ne temizlenecek göster
# (Bacula'nın bunu direkt desteklemediği için log'u takip edin)
*setdebug level=50 director
*prune jobs client=webserver01-fd

# Test amaçlı volume retention süresini kısalt
*update volume=Test-Volume-001 volretention=60

Retention testini production öncesinde bir test ortamında yapmanızı kesinlikle öneririm. Özellikle Recycle = yes ile kısa retention sürelerini bir arada test edin çünkü yanlış yapılandırılmış bir sistemde henüz gerekmekte olan yedeklerin üzerine yazılabilir.

Sık Yapılan Hatalar ve Çözümleri

Hata 1: File Retention’ı Job Retention’dan uzun tutmak

File Retention süresi Job Retention süresinden uzun olamaz mantıksal olarak. Eğer Job Retention 30 gün ama File Retention 60 günse, job kaydı silindiğinde dosya kayıtları da gider. Her zaman File Retention <= Job Retention kuralını uygulayın.

Hata 2: Catalog dolunca panik

Catalog büyüdüğünde bazen yeni job açılmıyor gibi görünür. Aslında prune çalışmıyordur:

# Catalog boyutunu kontrol et (MySQL/MariaDB kullanıyorsanız)
mysql -u bacula -p bacula -e "SELECT table_name, 
  ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'MB'
  FROM information_schema.TABLES 
  WHERE table_schema = 'bacula'
  ORDER BY (data_length + index_length) DESC;"

# Manüel olarak tüm expire olmuş kayıtları temizle
bconsole
*prune files yes
*prune jobs yes
*prune volumes yes

Hata 3: Volume Retention süresi dolmadan disk dolması

Maximum Volumes ve Maximum Volume Bytes parametrelerini retention süresiyle uyumlu hesaplamamak bu soruna yol açar. Günlük 5 GB incremental alıyorsanız ve 14 günlük retention istiyorsanız, minimum 70 GB + %20 buffer olan 84 GB alan ve buna uygun volume sayısı ayarlamanız gerekir.

Retention Durumunu İzlemek İçin Script

Üretime aldığınız sistemlerde retention durumunu düzenli izlemek için basit bir kontrol scripti:

#!/bin/bash
# /usr/local/bin/check-bacula-retention.sh

LOG="/var/log/bacula-retention-check.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')

echo "=== Bacula Retention Check - $DATE ===" >> $LOG

# Purged durumundaki volume sayısını kontrol et
PURGED=$(echo "list volumes" | bconsole | grep -c "Purged")
echo "Purged volumes: $PURGED" >> $LOG

# Son 24 saatte expire olan job sayısı
EXPIRED=$(echo "list jobs" | bconsole | grep -c "E")
echo "Jobs in Error state: $EXPIRED" >> $LOG

# Disk kullanımını kontrol et (storage path'inizi değiştirin)
DISK_USAGE=$(df -h /var/bacula | awk 'NR==2 {print $5}')
echo "Backup disk usage: $DISK_USAGE" >> $LOG

# %85 üzerindeyse uyarı ver
DISK_PERCENT=$(df /var/bacula | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$DISK_PERCENT" -gt 85 ]; then
    echo "UYARI: Backup diski %$DISK_PERCENT dolu!" | 
    mail -s "Bacula Disk Uyarisi" [email protected]
fi

echo "Check completed" >> $LOG

Bu scripti crontab’a ekleyin:

# Her gün sabah 07:00'de çalıştır
0 7 * * * /usr/local/bin/check-bacula-retention.sh

Catalog Maintenance Önemi

Uzun vadede Bacula’yı sağlıklı tutmak için catalog bakımını da retention policy’nize dahil edin:

# bacula-dir.conf içinde catalog maintenance job
Job {
  Name = "BackupCatalog"
  JobDefs = "DefaultJob"
  Level = Full
  FileSet = "Catalog"
  Schedule = "WeeklyCycleAfterBackup"
  RunBeforeJob = "/etc/bacula/scripts/make_catalog_backup.pl MyCatalog"
  RunAfterJob  = "/etc/bacula/scripts/delete_catalog_backup"
  Write Bootstrap = "/var/lib/bacula/BackupCatalog.bsr"
  Priority = 11
  Pool = Catalog-Pool
}

# Catalog cleanup job
Job {
  Name = "RestoreCatalog"
  Type = Restore
  Client = bacula-fd
  FileSet = "Catalog"
  Storage = File1
  Pool = Default
  Messages = Standard
  Where = /tmp/bacula-restores
}

Catalog backup’ını da kendi retention policy’sine tabi tutun. Catalog’u kaybederseniz fiziksel yedekleriniz olsa bile hangi tape’te ne olduğunu bilemezsiniz.

Sonuç

Bacula’da retention policy, kurulduktan sonra unutulacak bir şey değil. Sistematik bir yaklaşımla başlamak gerekiyor: önce kaç günlük kapsama ihtiyacınız olduğunu belirleyin, sonra bunu volume retention ve catalog retention olarak birbirinden bağımsız iki katmanda planlayın.

Özet olarak hatırlamanız gerekenler:

  • Volume Retention ve Catalog Retention farklı kavramlardır, birlikte düşünülmelidir
  • AutoPrune = yes ve Recycle = yes ikilisi günlük operasyonel sistemler için uygundur
  • Yasal gereksinimler olan sistemlerde Recycle = no ve AutoPrune = no kombinasyonunu tercih edin
  • File Retention her zaman Job Retention’dan kısa veya eşit olmalıdır
  • Disk hesaplamalarınızı retention süresi, günlük veri miktarı ve buffer’ı göz önünde bulundurarak yapın
  • Retention policy değişikliklerini önce test ortamında doğrulayın
  • Monitoring scriptleri ile sistemi gözlemleyin, sorunları önceden yakalayın

Doğru yapılandırılmış bir retention policy, hem diskinizi gereksiz veriden korur hem de ihtiyaç anında doğru noktaya dönebilmenizi sağlar. Yedek almak başlangıç, bu yedekleri yönetmek ise asıl iş.

Bir yanıt yazın

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