Depolama Pool Yönetimi: Bacula ile Disk ve Tape Yapılandırması

Bacula kurulumunu tamamladınız, Director çalışıyor, Storage Daemon ayakta ve Client’larınız kayıtlı. Şimdi asıl kritik noktaya geliyoruz: depolama pool yönetimi. Pool kavramını anlamadan Bacula’yı verimli kullanmak neredeyse imkansız. Diskleriniz dolup taşıyor, tape sürücünüz boşta kalıyor ya da yedeklerinizin nerede olduğunu takip edemiyorsunuz ise büyük ihtimalle pool yapılandırmanızda bir sorun var.

Pool Nedir ve Neden Önemlidir

Bacula’da pool, bir grup Volume’ün (yedek ortamının) mantıksal koleksiyonudur. Disk tabanlı yedeklerde bu bir dizine yazılan dosyalar olabilir, tape’de ise fiziksel kasetler olur. Pool yapısı sayesinde farklı işler için farklı saklama politikaları tanımlayabilirsiniz.

Örneğin günlük yedekleri 7 gün saklayan bir disk pool’u, haftalık yedekleri 4 hafta saklayan başka bir disk pool’u ve aylık arşivleri tape’e yazan bir tape pool’u aynı anda yönetebilirsiniz. Bu ayrım olmadan her şey tek bir havuza gider ve hangi yedeğin ne zaman silineceğini, neyin üzerine yazılabileceğini takip etmek kabus haline gelir.

Retention kavramı burada merkezi rol oynar. Her pool’da iki kritik değer vardır:

  • Volume Retention: Bir volume’deki verinin ne kadar süre korunacağı
  • Job Retention: Catalog’daki iş kayıtlarının ne kadar tutulacağı

Bu iki değer birbirinden bağımsızdır ve karıştırılması ciddi sorunlara yol açar.

Disk Pool Yapılandırması

Disk tabanlı pool’ların konfigürasyonu Director’ın bacula-dir.conf dosyasında yapılır. Temel bir disk pool tanımı şu şekilde görünür:

Pool {
  Name = DailyDisk
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 7 days
  Maximum Volume Bytes = 10G
  Maximum Volumes = 20
  Label Format = Daily-
  Storage = LocalDisk
}

Bu konfigürasyonda birkaç önemli parametre var:

  • Recycle: Süresi dolan volume’lerin otomatik yeniden kullanılmasını sağlar
  • AutoPrune: Retention süresi dolan volume’leri otomatik temizler
  • Maximum Volume Bytes: Tek bir volume dosyasının alabileceği maksimum boyut
  • Maximum Volumes: Pool’da bulunabilecek maksimum volume sayısı
  • Label Format: Yeni volume oluşturulduğunda kullanılacak isim ön eki

Disk storage tanımı için ise şu yapıyı kullanıyorum:

Storage {
  Name = LocalDisk
  Address = storage.sirket.local
  SDPort = 9103
  Password = "sd_password_buraya"
  Device = FileStorage
  Media Type = File
}

Storage Daemon tarafında ise bacula-sd.conf içinde cihaz tanımı yapılır:

Device {
  Name = FileStorage
  Media Type = File
  Archive Device = /backup/bacula
  LabelMedia = yes
  Random Access = yes
  AutomaticMount = yes
  RemovableMedia = no
  AlwaysOpen = no
  Maximum Concurrent Jobs = 5
}

/backup/bacula dizininin var olduğundan ve Bacula kullanıcısının bu dizine yazma iznine sahip olduğundan emin olun:

mkdir -p /backup/bacula
chown -R bacula:bacula /backup/bacula
chmod 750 /backup/bacula

Çoklu Disk Pool Senaryosu

Gerçek dünyada genellikle tek bir disk pool yeterli olmaz. Bir e-ticaret şirketinde kurduğum yapıyı örnek verebilirim. Database sunucuları için ayrı, uygulama sunucuları için ayrı, dosya sunucuları için ayrı pool’lar tanımladık.

Pool {
  Name = DB-Daily
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 3 days
  Maximum Volume Bytes = 50G
  Maximum Volumes = 10
  Label Format = DBDaily-
  Storage = FastDisk
}

Pool {
  Name = DB-Weekly
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 30 days
  Maximum Volume Bytes = 100G
  Maximum Volumes = 8
  Label Format = DBWeekly-
  Storage = FastDisk
}

Pool {
  Name = FileServer-Monthly
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 365 days
  Maximum Volume Bytes = 200G
  Maximum Volumes = 15
  Label Format = FSMonthly-
  Storage = SlowDisk
}

Burada FastDisk ve SlowDisk farklı storage cihazlarına işaret ediyor. Database yedekleri SSD tabanlı hızlı depolamaya, dosya sunucusu arşivleri ise kapasitesi yüksek ama daha yavaş HDD’lere yazılıyor.

Job tanımlarında hangi pool’un kullanılacağını belirtmek kritik:

Job {
  Name = DatabaseBackup-Daily
  Type = Backup
  Client = db01-fd
  FileSet = DatabaseFiles
  Schedule = WeekdaySchedule
  Storage = FastDisk
  Pool = DB-Daily
  Full Backup Pool = DB-Weekly
  Messages = Standard
  Priority = 10
}

Full Backup Pool parametresi özellikle işe yarıyor. Incremental yedekler DB-Daily pool’una giderken, otomatik olarak tetiklenen Full yedekler DB-Weekly pool’una yazılıyor.

Tape Pool Yapılandırması

Tape yönetimi disk’e göre çok daha fazla dikkat gerektiriyor. Özellikle enterprise ortamlarda tape kütüphanesi (library) kullanıyorsanız, changer mekanizmasını doğru yapılandırmanız şart.

Tape için storage tanımı:

Storage {
  Name = TapeLibrary
  Address = storage.sirket.local
  SDPort = 9103
  Password = "sd_password_buraya"
  Device = TapeDrive
  Media Type = LTO-8
  Autochanger = yes
}

Autochanger yapılandırması bacula-sd.conf içinde:

Autochanger {
  Name = TapeChanger
  Device = Drive-1, Drive-2
  Changer Command = "/usr/lib/bacula/mtx-changer %c %o %S %a %d"
  Changer Device = /dev/sg0
}

Device {
  Name = Drive-1
  Media Type = LTO-8
  Archive Device = /dev/nst0
  AutomaticMount = yes
  AlwaysOpen = yes
  RemovableMedia = yes
  RandomAccess = no
  AutoChanger = yes
  Drive Index = 0
  Alert Command = "sh -c 'tapeinfo -f %c | grep TapeAlert'"
}

Device {
  Name = Drive-2
  Media Type = LTO-8
  Archive Device = /dev/nst1
  AutomaticMount = yes
  AlwaysOpen = yes
  RemovableMedia = yes
  RandomAccess = no
  AutoChanger = yes
  Drive Index = 1
  Alert Command = "sh -c 'tapeinfo -f %c | grep TapeAlert'"
}

Tape pool tanımı disk’ten farklıdır. Tape’in fiziksel özellikleri nedeniyle bazı parametreler anlamsız olur ama bazıları kritik önem kazanır:

Pool {
  Name = TapeMonthly
  Pool Type = Backup
  Recycle = yes
  AutoPrune = yes
  Volume Retention = 1 year
  Volume Use Duration = 23 hours
  Maximum Volumes = 50
  Label Format = TAPE-M-
  Storage = TapeLibrary
  Cleaning Prefix = CLN
}
  • Volume Use Duration: Bir tape kasedinin ne kadar süre aktif olarak kullanılabileceği. LTO sürücülerde aynı kaseti uzun süre kullanmak mekanik yıpranmayı artırır
  • Cleaning Prefix: Temizleme kasetlerini normal kasetlerden ayırt etmek için önek

Tape Etiketleme ve Inventory

Tape kullanımında en sık yapılan hata, kasetleri etiketlemeden kullanmaya çalışmak. Bacula’nın her kaseti tanıması için önce catalog’a kaydetmesi gerekir. Bu işlemi bconsole üzerinden yapıyoruz:

# bconsole'a bağlan
bconsole

# Tape pool için toplu etiketleme
*label barcodes storage=TapeLibrary pool=TapeMonthly

# Ya da tek tek etiketleme
*label storage=TapeLibrary pool=TapeMonthly

# Kütüphanedeki mevcut kasetleri listele
*update slots storage=TapeLibrary

# Pool içindeki volume'leri görüntüle
*list volumes pool=TapeMonthly

Barkod okuyucusu olan kütüphanelerde label barcodes komutu çok hayat kurtarır. Fiziksel barkodu otomatik olarak okuyup catalog’a kaydeder.

Volume Durumları ve Yönetimi

Her volume’ün bir durumu vardır ve bu durumları anlamak pool yönetiminin temelidir:

  • Append: Volume aktif, üzerine veri yazılabilir
  • Full: Volume doldu, yeni veri yazılamaz
  • Used: Volume kullanıldı ama retention süresi dolmadı
  • Purged: Tüm job’lar expire oldu, yeniden kullanılabilir
  • Recycle: Volume temizlendi ve yeniden yazılmaya hazır
  • Error: Volume’de sorun var, kullanılamaz
  • Disabled: Manuel olarak devre dışı bırakıldı
  • Cleaning: Temizleme kasedi (yalnızca tape için)

Bir volume’ün durumunu manuel değiştirmeniz gerektiğinde bconsole üzerinden update komutunu kullanırsınız:

# Volume durumunu manuel güncelle
*update volume=Daily-0001 volstatus=Purged

# Tüm expired volume'leri temizle
*purge volume pool=DailyDisk action=purge

# Pool içindeki tüm volume'leri listele (durumlarıyla birlikte)
*list volumes pool=DailyDisk

Disk Pool Doluluğu Sorunu ve Çözümü

Pratikte en çok karşılaştığım sorun disk pool’larının dolup taşması. “No appendable volumes” hatası görüyorsanız şu adımları takip edin:

# Önce durumu kontrol et
bconsole <<EOF
list volumes pool=DailyDisk
EOF

# Süresi dolmuş volume'leri temizle
bconsole <<EOF
purge volume pool=DailyDisk action=purge
EOF

# Disk üzerinde gerçekten silinmesini sağla
bconsole <<EOF
truncate pool=DailyDisk
EOF

Bu işlemi otomatize etmek için bir cron script’i yazabilirsiniz:

#!/bin/bash
# /usr/local/sbin/bacula-pool-maintenance.sh

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

echo "[$DATE] Pool maintenance başladı" >> $LOG

# Expired volume'leri purge et
bconsole << EOF >> $LOG 2>&1
@output /dev/null
messages
@output
purge expired volume pool=DailyDisk
purge expired volume pool=DB-Daily
purge expired volume pool=DB-Weekly
truncate pool=DailyDisk
truncate pool=DB-Daily
messages
quit
EOF

echo "[$DATE] Pool maintenance tamamlandı" >> $LOG

Bu script’i crontab’a ekleyin:

# Her gece 02:00'de çalıştır
0 2 * * * root /usr/local/sbin/bacula-pool-maintenance.sh

Disk’ten Tape’e Migration (Staging)

En değerli Bacula özelliklerinden biri disk staging. Önce hızlı diske yaz, sonra tape’e taşı. Bu yönteme “D2D2T” (Disk to Disk to Tape) denir. Büyük kurumsal ortamlarda standart pratik haline gelmiştir.

Bunun için Copy job’u kullanılır:

Job {
  Name = CopyToDailyToTape
  Type = Copy
  Messages = Standard
  Selection Type = PoolOccupancy
  Selection Pattern = 70
  Pool = DailyDisk
  Next Pool = TapeMonthly
  Storage = TapeLibrary
  SpoolData = no
  Priority = 15
}
  • Selection Type = PoolOccupancy: Pool doluluk oranına göre kopyalama tetiklenir
  • Selection Pattern = 70: Pool’un %70’i dolduğunda tape’e kopyalamayı başlat

Alternatif olarak zaman bazlı migration da yapabilirsiniz:

Job {
  Name = MigrateWeeklyToTape
  Type = Migration
  Messages = Standard
  Selection Type = Volume
  Selection Pattern = "DBWeekly-.*"
  Pool = DB-Weekly
  Next Pool = TapeMonthly
  Storage = TapeLibrary
  Schedule = TapeArchiveSchedule
  Priority = 20
}

Schedule {
  Name = TapeArchiveSchedule
  Run = Full sun at 03:00
}

Copy ve Migration arasındaki fark şudur: Copy orijinal veriyi kaynak pool’da bırakır, Migration ise kaynaktan siler ve hedefe taşır.

Pool Kullanımı İzleme ve Raporlama

Bir pool’un ne kadar dolduğunu, kaç job’ın başarılı olduğunu ve tape kasedinin ne kadar ömrü kaldığını takip etmek için SQL sorguları veya bconsole komutları kullanabilirsiniz:

#!/bin/bash
# /usr/local/sbin/bacula-pool-report.sh
# Pool durumu raporu

REPORT="/tmp/bacula-pool-report-$(date +%Y%m%d).txt"

bconsole << EOF > $REPORT
@output /dev/null
messages
@output
list pools
list volumes pool=DailyDisk
list volumes pool=TapeMonthly
status storage=LocalDisk
status storage=TapeLibrary
quit
EOF

# Raporu mail ile gönder
mail -s "Bacula Pool Durumu - $(date +%Y-%m-%d)" [email protected] < $REPORT

# Disk doluluk uyarısı
DISK_USAGE=$(df /backup/bacula | tail -1 | awk '{print $5}' | tr -d '%')
if [ "$DISK_USAGE" -gt 85 ]; then
    echo "UYARI: /backup/bacula disk dolulugu %${DISK_USAGE}" | 
    mail -s "Bacula Disk Uyarisi" [email protected]
fi

Tape Rotasyonu ve Offsite Yedekleme

Tape’in en büyük avantajı fiziksel taşınabilirliğidir. Offsite backup için tape rotasyon politikası oluşturmanız gerekir. Yaygın kullanılan “Grandfather-Father-Son” (GFS) yöntemi şu şekilde uygulanır:

# Haftalık tape pool (4 kaset)
Pool {
  Name = WeeklyTape-Son
  Pool Type = Backup
  Volume Retention = 4 weeks
  Maximum Volumes = 4
  Label Format = SON-
  Storage = TapeLibrary
}

# Aylık tape pool (12 kaset)
Pool {
  Name = MonthlyTape-Father
  Pool Type = Backup
  Volume Retention = 12 months
  Maximum Volumes = 12
  Label Format = FATHER-
  Storage = TapeLibrary
}

# Yıllık tape pool (offsite kasa için)
Pool {
  Name = YearlyTape-Grandfather
  Pool Type = Backup
  Volume Retention = 7 years
  Maximum Volumes = 7
  Label Format = GF-
  Storage = TapeLibrary
}

Offsite’a gönderilecek kasetleri takip etmek için catalog’u düzenli sorgulamanız gerekir:

# bconsole üzerinden offsite kaseti safemode'a al
*update volume=GF-2024 volstatus=Disabled

# Kaseti kütüphaneden çıkar ve fiziksel olarak işaretle
*export storage=TapeLibrary srcslots=10

Yaygın Sorunlar ve Çözümleri

“Volume is already mounted” hatası: Storage Daemon bazen beklenmedik kapanmalar sonrasında kilit dosaları bırakır.

# SD servisini yeniden başlat
systemctl restart bacula-sd

# Eğer çözülmezse lock dosyasını temizle
ls /var/lib/bacula/*.state
rm /var/lib/bacula/bacula-sd.*.state
systemctl restart bacula-sd

“No writable volumes” hatası disk pool’da: Genellikle tüm volume’lerin Full veya Used durumunda olduğu anlamına gelir.

bconsole << 'EOF'
purge volume pool=DailyDisk action=purge
truncate pool=DailyDisk
label barcodes pool=DailyDisk storage=LocalDisk
EOF

Tape sürücü hataları: tapeinfo ve st komutlarıyla teşhis yapın.

# Tape durumunu kontrol et
tapeinfo -f /dev/nst0

# SCSI sorgulama
sg_inq /dev/st0

# Tape'i temizle ve geri sar
mt -f /dev/nst0 rewind
mt -f /dev/nst0 status

Sonuç

Bacula’da pool yönetimi, başlangıçta karmaşık görünse de doğru yapılandırıldığında son derece güçlü ve esnek bir yedekleme altyapısı sunar. Disk ve tape’i birlikte kullanmak, hem hızlı erişim hem de uzun vadeli arşivleme ihtiyaçlarını karşılar. GFS rotasyon politikası, otomatik migration job’ları ve düzenli pool maintenance script’leriyle kurduğunuz sistem büyük ölçüde “set and forget” seviyesine gelir.

En kritik hatırlatma: Pool konfigürasyonunu değiştirmeden önce mevcut volume durumlarını mutlaka kontrol edin. Yanlış bir retention ayarı, silmemeniz gereken verilerin üzerine yazılmasına neden olabilir. Test ortamında mutlaka doğrulayın, üretim ortamına bakım penceresi açarak alın ve her değişiklikten sonra bir test restore yapın. Yedek almak kadar o yedeği geri yükleyebilmek de kritik, bunu asla unutmayın.

Bir yanıt yazın

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