---
title: 'Yedek Doğrulama'
source: 'https://academia.sh/tr/kurslar/veritabani-yonetimi/yedek-dogrulama'
course: 'İlişkisel Veritabanı Yönetimi'
language: tr
updated: '2026-08-17T18:08:55+00:00'
license: 'CC BY-SA 4.0'
---

# Yedek Doğrulama

Yedeğin geçerliliğinin geri yükleme anından önce bilinmesi: dosya karmasıyla bütünlük denetimi, sessiz bozulmanın içerik karmasıyla yakalanması, yapısal denetimin kapsamı ve düzenli kurtarma tatbikatının kurulması.

Önceki iki ders yedek almayı ve yedekten dönmeyi kurdu. İkisi de aynı varsayıma
dayanıyordu: yedek dosyası okunabilir ve içeriği doğru. Bu varsayım sınanmadığı sürece bir
varsayımdır ve sınanmadığı sürece de doğru kabul edilir — arıza anına kadar.

Yedeklemenin en pahalı kusuru, alınmayan yedek değildir; **alındığı sanılan yedektir**.
Disk dolduğu için yarım yazılmış bir dosya, kopyalama sırasında bozulmuş bir bayt ya da
haftalardır sessizce başarısız olan bir yedekleme görevi, hepsi aynı sonucu verir:
kurtarma anında elde kullanılamaz bir dosya.

Bu ders yedeğin geçerliliğini **geri yükleme anından önce** bilmenin yollarını kuruyor.
Üç ayrı denetim vardır ve üçü ayrı şeyleri yakalar.

## Üç Denetim, Üç Kapsam

**Dosya karması.** Yedek alındığı anda dosyanın karması hesaplanır ve dosyanın yanında
saklanır. Sonradan yapılan karşılaştırma, dosyanın tek baytının bile değişmediğini
gösterir. Aktarım ve saklama sırasındaki bozulmaları yakalar; yedeğin **içeriğinin** doğru
olduğunu göstermez.

**Yapısal bütünlük denetimi.** Motorun kendi denetimi, veritabanı dosyasının sayfa
yapısının, ağaç bağlantılarının ve dizinlerin tutarlı olup olmadığını sınar. Yapıyı
denetler, değerleri denetlemez.

**İçerik karması.** Veritabanının satır değerlerinden hesaplanan karma, yedek alındığı
anda kaydedilir ve geri yüklendikten sonra yeniden hesaplanarak karşılaştırılır. Değerdeki
bozulmayı yakalayan tek denetim budur.

## Mantıksal Yedeğin İki Bozulma Biçimi

Aşağıdaki blok bir yedek alıyor, iki ayrı biçimde bozuyor ve üç dosyayı aynı tatbikattan
geçiriyor. Birinci bozulma tek bir baytın değişmesi — bir ödünç kaydının kitap numarası
başka bir sayıya dönüşüyor. İkincisi dosyanın son onda birinin kesilmesi, yani yarım
yazılmış bir yedek.

Blok yalnız kendi ürettiği geçici dosyalar üzerinde çalışır ve hiçbir yedeği yerinde
değiştirmez; bozuk sürümler ayrı dosyalara yazılır. Gerçek bir kurulumda tatbikat da
böyledir: yedek dosyasına dokunulmaz, kopyası üzerinde çalışılır.

```bash
rm -f kutuphane.db yedek.sql bozuk.sql kesik.sql tatbikat.db

sqlite3 kutuphane.db <<'SQL'
CREATE TABLE uye(id INTEGER PRIMARY KEY, ad TEXT NOT NULL, sube_id INT NOT NULL);
CREATE TABLE odunc(id INTEGER PRIMARY KEY, kitap_id INT NOT NULL, uye_id INT NOT NULL,
                   sube_id INT NOT NULL, alis TEXT NOT NULL, iade TEXT);
WITH RECURSIVE s(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM s WHERE n<5000)
INSERT INTO uye(id,ad,sube_id) SELECT n,'Uye-'||n,(n%3)+1 FROM s;
WITH RECURSIVE s(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM s WHERE n<40000)
INSERT INTO odunc(id,kitap_id,uye_id,sube_id,alis,iade)
SELECT n,(n%500)+1,(n%5000)+1,(n%3)+1,'2025-06-01',NULL FROM s;
SQL

sqlite3 kutuphane.db .dump > yedek.sql
shasum -a 256 yedek.sql | awk '{print "yedek karmasi (alindigi an): " substr($1,1,16)}'

# Iki bozulma bicimi uretilir: tek bayt degisimi ve dosyanin kesilmesi.
node -e '
const fs = require("node:fs");
const b = fs.readFileSync("yedek.sql");
const im = b.indexOf("VALUES(20000,");
const yer = im + "VALUES(20000,".length;       // kitap_id alaninin ilk basamagi
const c = Buffer.from(b);
c[yer] = b[yer] === 0x39 ? 0x38 : b[yer] + 1;  // basamagi degistir
fs.writeFileSync("bozuk.sql", c);
fs.writeFileSync("kesik.sql", b.subarray(0, Math.floor(b.length * 0.9)));
console.log("kaynak: " + b.subarray(im, im + 37).toString());
console.log("bozuk : " + c.subarray(im, im + 37).toString());
'

kaynak_karma=$(sqlite3 kutuphane.db '.sha3sum --schema --sha3-256')
echo
echo "yedek       | dosya karmasi | geri yukleme | odunc satir | icerik karmasi"
echo "------------|---------------|--------------|-------------|---------------"
for dosya in yedek.sql bozuk.sql kesik.sql; do
  rm -f tatbikat.db
  dosya_karma=$(shasum -a 256 "$dosya" | awk '{print substr($1,1,8)}')
  if sqlite3 tatbikat.db < "$dosya" 2>/dev/null; then yukleme="tamam"; else yukleme="HATA"; fi
  satir=$(sqlite3 tatbikat.db 'SELECT COUNT(*) FROM odunc;' 2>/dev/null || echo "yok")
  icerik=$(sqlite3 tatbikat.db '.sha3sum --schema --sha3-256' 2>/dev/null | tail -1)
  if [ "$icerik" = "$kaynak_karma" ]; then esit="ESIT"; else esit="FARKLI"; fi
  printf "%-11s | %-13s | %-12s | %11s | %s\n" "$dosya" "$dosya_karma" "$yukleme" "$satir" "$esit"
done
rm -f tatbikat.db
```

```text
yedek karmasi (alindigi an): d33cffac34951285
kaynak: VALUES(20000,1,1,3,'2025-06-01',NULL)
bozuk : VALUES(20000,2,1,3,'2025-06-01',NULL)

yedek       | dosya karmasi | geri yukleme | odunc satir | icerik karmasi
------------|---------------|--------------|-------------|---------------
yedek.sql   | d33cffac      | tamam        |       40000 | ESIT
bozuk.sql   | fb6cf157      | tamam        |       40000 | FARKLI
kesik.sql   | 799bd4e0      | HATA         |         yok | FARKLI
```

Orta satır bu dersin gerekçesidir. Bozuk yedek **hatasız geri yüklendi**. Satır sayısı
kaynakla aynı çıktı. Tablolar yerinde, dizinler kurulu, sorgular çalışıyor. Yalnız
içerik karması farklı — ve fark, kırk bin satırın birindeki bir sayıdan ibaret.

Bu bozulma biçimi kendini göstermez. Kırk bin ödünç kaydından birinin kitap numarası
yanlış olduğunda hiçbir sorgu hata vermez; yalnız o kitabı arayan kişi bulamaz. Yedeği
"başarıyla geri yükledik" diye kabul eden bir tatbikat bu kusuru geçirir.

Alt satır ise farklı bir şey öğretiyor. Kesik yedek geri yüklenmedi ve tablo bile
oluşmadı. Nedeni, mantıksal yedeğin tek bir işlem olarak yazılmasıdır: dosyanın başında
bir işlem başlatılır, sonunda kesinleştirilir. Dosya yarım kaldığında kesinleştirme
gelmez ve her şey geri alınır. Bu, kısmi geri yüklemeden iyidir — yarım bir veritabanı,
boş bir veritabanından tehlikelidir, çünkü kullanılabilir görünür.

Dosya karması sütunu üç dosya için de farklıdır. Yedek alındığı anda kaydedilen karma ile
karşılaştırıldığında iki bozulma da **geri yüklemeye hiç girişmeden** yakalanırdı. Bu, en
ucuz denetimdir ve her yedeğin yanında saklanması gereken tek satırlık bilgidir.

## Fiziksel Yedekte Yapısal Denetim

Fiziksel yedekte durum başkadır: dosya bir metin değil, sayfalardan oluşan bir yapıdır.
Motor bu yapıyı kendisi sınayabilir. Aşağıdaki blok aynı veritabanının iki kopyasını iki
ayrı konumdan bozuyor — biri bir sayfa başlığını, diğeri bir veri değerini.

```bash
rm -f fiziksel.db

sqlite3 fiziksel.db <<'SQL'
CREATE TABLE odunc(id INTEGER PRIMARY KEY, kitap_id INT NOT NULL, uye_id INT NOT NULL,
                   sube_id INT NOT NULL, alis TEXT NOT NULL);
WITH RECURSIVE s(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM s WHERE n<40000)
INSERT INTO odunc(id,kitap_id,uye_id,sube_id,alis)
SELECT n,(n%500)+1,(n%5000)+1,(n%3)+1,'2025-06-01' FROM s;
CREATE INDEX odunc_uye ON odunc(uye_id);
SQL

kaynak_karma=$(sqlite3 fiziksel.db '.sha3sum --schema --sha3-256')

# Iki ayri konumda tek bayt bozulur: sayfa basligi ve bir veri degeri.
for yer in 40960 200000; do
  cp fiziksel.db bozuk-$yer.db
  node -e "
const fs = require('node:fs');
const fd = fs.openSync('bozuk-$yer.db', 'r+');
const b = Buffer.alloc(1);
fs.readSync(fd, b, 0, 1, $yer);
fs.writeSync(fd, Buffer.from([b[0] ^ 0xff]), 0, 1, $yer);
fs.closeSync(fd);
"
done

echo "dosya              | integrity_check | icerik karmasi"
echo "-------------------|-----------------|---------------"
for d in fiziksel.db bozuk-40960.db bozuk-200000.db; do
  ic=$(sqlite3 "$d" 'PRAGMA integrity_check;' 2>&1 | head -1)
  karma=$(sqlite3 "$d" '.sha3sum --schema --sha3-256' 2>/dev/null | tail -1)
  if [ "$karma" = "$kaynak_karma" ]; then esit="ESIT"; else esit="FARKLI"; fi
  printf "%-18s | %-15s | %s\n" "$d" "${ic:0:15}" "$esit"
done
rm -f bozuk-40960.db bozuk-200000.db
```

```text
dosya              | integrity_check | icerik karmasi
-------------------|-----------------|---------------
fiziksel.db        | ok              | ESIT
bozuk-40960.db     | Error: stepping | FARKLI
bozuk-200000.db    | ok              | FARKLI
```

Bozulan bayt bir sayfa başlığındaysa yapısal denetim bunu yakalıyor: motor sayfayı
okuyamıyor ve dosyanın bozuk olduğunu bildiriyor. Bozulan bayt bir veri değerinin içindeyse
yapısal denetim **`ok` diyor** — yapı tutarlıdır, yalnız değer yanlıştır.

Buradaki bayt konumları bu motorun sayfa boyutuna ve tabloların dosyadaki yerleşimine
bağlıdır; sizde farklı konumlar farklı sonuç verebilir. Sonucun kendisi motora özgü
değildir: sayfa yapısını denetleyen hiçbir araç, sayfanın içindeki bir sayının doğru sayı
olduğunu bilemez.

Bu, yapısal denetimin sınırıdır ve içerik karmasının neden ayrıca gerektiğini gösterir.

## Kurtarma Tatbikatı

Yukarıdaki iki blok bir tatbikatın parçalarıdır. Bütünü şu adımlardan oluşur ve düzenli
aralıklarla, kimsenin acelesi yokken çalıştırılır.

**Yedek dosyasının karması, alındığı andaki karmayla karşılaştırılır.** Uymuyorsa
saklama ya da aktarım katmanında bir sorun var demektir; geri yüklemeye girişilmez.

**Yedek, üretim dışı bir ortama geri yüklenir.** Hedef her zaman yeni ve boş bir
veritabanıdır. Çalışan bir veritabanının üzerine tatbikat yapılmaz.

**Yapısal bütünlük denetimi çalıştırılır.** Fiziksel yedeklerde sayfa ve dizin
tutarlılığını doğrular.

**İçerik karması, yedeğin alındığı anda kaydedilmiş karmayla karşılaştırılır.** Bu adım,
satır sayısı karşılaştırmasının yerine geçer — sayılar tutup değerler bozuk olabilir.

**Süre ölçülür.** Geri yüklemenin ne kadar sürdüğü, kurtarma süresi hedefinin
karşılanabilir olup olmadığını söyleyen tek sayıdır. Bu sayı veri büyüdükçe artar;
ölçülmediği sürece plan bir varsayımdır.

**Uygulama, kurtarılan kopyaya bağlanır.** Yedeğin geri yüklenmiş olması, uygulamanın
çalışacağı anlamına gelmez: eksik bir dizin, kaydedilmemiş bir görünüm ya da yedeğe
girmemiş bir yapılandırma tablosu ancak burada ortaya çıkar.

Tatbikatın çıktısı bir rapor değil, bir karardır: yedek geçerli ya da değil. Aradaki
"muhtemelen iyidir" durumu, yedeğin doğrulanmamış olmasıyla aynı şeydir.

## Tatbikatın Sıklığı ve Kapsamı

Sıklık, kurtarma noktası hedefiyle birlikte belirlenir. Yedeği doğrulanmamış geçen her
gün, o günün yedeğinin güvenilmez olması riskidir. Yedekleme günlükse tatbikat da sık
olmalıdır; tam tatbikat pahalıysa, hafif bir bütünlük denetimi her yedek için, tam geri
yükleme tatbikatı daha seyrek çalıştırılır.

Kapsam, yedeklenen her nesneyi içerir. Kütüphane örneğinde ödünç tablosu yedekleniyorsa
ama şube tanımları ayrı bir yapılandırma dosyasında duruyorsa, tatbikat kütüphaneyi
çalışır hâle getirmez. Yedeğin kapsamı, uygulamanın çalışması için gereken her şeydir;
tatbikat bunu ortaya çıkarmanın yoludur.

Son olarak tatbikatın kendisi kayıt bırakır: hangi yedek, hangi tarihte, ne kadar sürede
geri yüklendi ve karmalar uydu mu. Bu kayıt, bir sonraki arızada "en son ne zaman
denedik" sorusuna yanıt verir.

## Özet

- Yedeğin geçerliliği alındığı anda değil, doğrulandığı anda bilinir; doğrulanmamış yedek
  alınmamış yedekle aynı güvenceyi verir.
- Dosya karması bozulmayı geri yüklemeye girişmeden yakalar ve her yedeğin yanında
  saklanır.
- Tek bayt değişmiş bir mantıksal yedek hatasız geri yüklenebilir ve satır sayısı
  tutabilir; bu bozulmayı yalnız içerik karması yakalar.
- Yapısal bütünlük denetimi sayfa ve dizin tutarlılığını sınar, değerlerin doğruluğunu
  sınamaz.
- Kesik bir mantıksal yedek, tek işlem olarak yazıldığı için kısmi değil boş bir
  veritabanı üretir.
- Kurtarma tatbikatı karma karşılaştırması, yapısal denetim, süre ölçümü ve uygulamanın
  bağlanmasını içerir; çıktısı geçerli/geçersiz kararıdır.

## Sonraki Adım

Yedek ve kurtarma, veriyi kaybetmemeyi güvence altına alır; sistemin kesintisiz
çalışmasını değil. Kırk dakika süren bir geri yükleme, o kırk dakika boyunca kütüphanenin
ödünç veremeyeceği anlamına gelir. Kesintiyi kısaltmanın yolu, verinin bir kopyasının
başka bir makinede zaten hazır durmasıdır. Sonraki ders fiziksel çoğaltmayı ele alıyor:
birincil sunucunun günlük kayıtlarının bir yedek sunucuya sürekli akıtılması, bu akışın
gecikmesi ve gecikmenin okuma tutarlılığına etkisi.
