Geri yüklenemeyen yedek, yedek değildir — sadece diskte yer kaplayan bir yığın dosyadır. Bunu aylarca yedeklerimin sorunsuz çalıştığına inandıktan sonra zor yoldan öğrendim. Loglar başarı diyordu, cron job her gece tetikleniyordu, storage sürekli büyüyordu. Sonra bir müşteri geri yükleme istedi ve her bir yedeğin işe yaramaz olduğunu yine zor yoldan keşfettim.
Kimsenin konuşmadığı senaryo budur: dışarıdan sağlıklı görünen ama gerçekten geri yüklemeye çalıştığınızda sessizce başarısız olan yedekler. İşte ortamımda neyin yanlış gittiği, nasıl düzelttiğim ve geri yüklemenin gerçekten çalıştığından emin olmak için şimdi neyi test ettiğim.
Backup Loglarına Körü Körüne Güvenince Ne Olur
Kâğıt üzerinde kurulum sağlam görünüyordu. Her gece çalışan bir script veritabanlarını dump ediyor, sıkıştırıyor ve ikincil bir storage kutusuna gönderiyordu. Her sabah logları kontrol edip Backup completed successfully görüyordum. Hatta monitoring alertleri bile bağlamıştım — script başarısız olursa bildirim alacaktım.
Olmayan şey bir doğrulama adımıydı. Script boş gzip dosyaları üretiyordu çünkü veritabanı dump komutu haftalar önce sessizce başarısız olmuştu. Bir şifre rotasyonu connection string'i bozdu, dump komutu non-zero exit code ile çıktı ama script yine de devam edip boş stdout çıktısını sıkıştırdı. Backup completed successfully log satırı, gerçek veri dump'ı çalışsın ya da çalışmasın script'in sonunda her durumda yazılıyordu.
Tuzağı burası. Loglar size script'in çalıştığını söyler. Yedeğin kullanılabilir olduğunu söylemez.
Neden Geri Yükleme Testi Tek Gerçek Yedek Testidir
Eskiden dosya boyutlarını kontrol etmenin yeterli olduğunu düşünürdüm. Bugünün yedek dosyası dününkiyle yaklaşık aynı boyuttaysa, yedek iyidir, değil mi? Yanlış. Bozuk bir veritabanı yine de benzer boyutta bir dump dosyası üretebilir. Yarım kalmış bir yedek tüm tabloları kaçırabilir ama dizin listesinde yine de normal görünür.
Bir yedeğin çalıştığını bilmenin tek yolu onu geri yüklemektir. Üzerinden geçmek değil, dosya boyutunu kontrol etmek değil — gerçekten bir test sunucusuna geri yüklemek ve verinin orada olduğunu doğrulamak.
İşte şimdi düzenli olarak test ettiğim şeyler:
- Dosya bütünlüğü: Arşivi hatasız açabiliyor muyum?
- Veritabanı geri yükleme: Dump temiz bir veritabanı instance'ına sorunsuz import oluyor mu?
- Satır sayıları: Kritik tablolar geri yüklemeden sonra beklenen satır sayısına sahip mi?
- Uygulama başlangıcı: Uygulama geri yüklenen veriyle gerçekten başlayabiliyor mu?
- Point-in-time doğruluğu: Geri yüklenen veri, backup timestamp'inde production'ın nasıl göründüğüyle uyuşuyor mu?
Bu kontrollerden herhangi biri başarısız olursa, yedek bozuk demektir. Nokta.
Karşılaştığım Yaygın Sessiz Yedek Hataları
n Yıllar içinde bariz hatalar tetiklemeyen birkaç failure mode ile karşılaştım. İşte beni hazırlıksız yakalayanlar:
Boş veya kısmi dump'lar. Dediğim gibi, bir şifre değişikliği veya sessiz bir bağlantı hatası, yine de başarıyla sıkışan ve transfer olan boş yedek dosyaları üretebilir.
Encoding uyuşmazlıkları. Farklı bir varsayılan encoding'e sahip bir sunucuya geri yüklenen veritabanı dump'ı, metin verisini bozabilir. Geri yükleme hatasız çalışır ama Türkçe karakterler çöp olur.
Eksik bağımlılıklar. Yedek script'i Server A'da çalışır ama Server B'de geri yüklemeyi denediğinizde, gerekli bir araç eksiktir veya sürüm yanlıştır. Yedek başından beri iyiydi ama geri yükleme ortamı hiç hazırlanmamıştı.
Incremental backup zinciri kopması. Zincirdeki bir incremental bozuksa veya eksikse, ondan sonraki her incremental geri yüklenemez hale gelir. 30 günlük incremental yedeğiniz olabilir ama sadece ilk full backup gerçekten çalışır.
Backup hedefinde storage dolması. Yedek script'i local disk'e başarıyla yazar ama remote disk dolu olduğu için remote storage'a transfer sessizce başarısız olur. Eski yedekler birikir, yenileri asla ulaşmaz.
Şimdi Yedekleri Nasıl Doğruluyorum
O olaydan sonra, otomatik çalışan bir doğrulama rutini kurdum. İlke basit: bir insan yedeği kontrol etmiyorsa, bir script etmeli.
Veritabanı yedekleri için her hafta disposable bir container'da geri yükleme testi yapıyorum. Script şuna benzer bir şey:
#!/bin/bash
BACKUP_FILE=$(ls -t /backups/db/*.sql.gz | head -1)
tmpdir=$(mktemp -d)
gunzip -c "$BACKUP_FILE" > "$tmpdir/restore.sql"
docker run --rm \
-e POSTGRES_PASSWORD=test \
-v "$tmpdir/restore.sql":/restore.sql \
postgres:15 \
bash -c "pg_restore -U postgres -d postgres /restore.sql && \
psql -U postgres -d postgres -c 'SELECT count(*) FROM users;'"
if [ $? -ne 0 ]; then
echo "RESTORE FAILED for $BACKUP_FILE"
exit 1
fi
O script non-zero exit ederse monitoring sistemim bana alert atar. Alert yoksa yedek geri yüklendi ve kritik bir tablo satır sayısı döndü demektir. Tam bir veri doğrulaması mı? Hayır. Ama beni ısıran failure mode'u yakalıyor — kullanana kadar iyi görünen boş veya bozuk dump'ları.
Dosya seviyesinde yedekler için, periyodik olarak rastgele bir dosyayı test geri yükleme yapıp checksum'larını kaynakla karşılaştırıyorum. Checksum eşleşmezse yedek şüpheli olarak işaretleniyor.
Artık Gerçekten Uyduğum Yedek Kuralı
Eskiden klasik 3-2-1 kuralına uyardım: üç kopya, iki medya, bir offsite. Hâlâ uyuyorum ama diğerlerinden daha önemli olan bir gereksinim daha ekledim:
Her yedek geri yüklenebilir ve doğrulanmış olmalıdır.
Hiç geri yüklemediğiniz bir yedek, bir yedek değil bir hipotezdir. Çalıştığını tahmin ediyorsunuz. Ben aylarca tahmin ediyordum ve bunun yüzünden veri kaybettim.
Bu yazıdan bir şey alacaksanız şu olsun: bir yedek seçin, bu haftanın herhangi bir yedeği, ve şimdi hemen geri yüklemeyi deneyin. Yarın değil, script yazdıktan sonra değil. Şimdi, manuel olarak, bir terminalde. Çalışırsa harika — şimdi o testi otomatikleştirin. Çalışmazsa, gerçek bir felaket yapmadan önce bir sorunu keşfettiniz demektir.
Mesele tam olarak bu. Birisi sizden geri yüklemenizi istemeden önce bozuk yedeği bulun.
Kapak görseli: Lenharth Systems · CC0 (Openverse / kamu malı) · https://stocksnap.io/photo/computer-hard-2J3PLNMO9M
