---
title: 'Geri Yükleme Tatbikatı'
source: 'https://academia.sh/tr/kurslar/sunucu-ve-sertlestirme/geri-yukleme-tatbikati'
course: 'Sunucu, Ağ ve Sertleştirme'
language: tr
updated: '2026-08-17T18:09:10+00:00'
license: 'CC BY-SA 4.0'
---

# Geri Yükleme Tatbikatı

Yedeğin çalıştığının kanıtlanması: gerçek dosyaların yedeklenip silinmesi ve geri yüklenmesi, birebir aynı olduğunun özetle doğrulanması, yalnız tatbikatla görülen beş kusurun sayılması, geri yükleme süresinin beş bileşene ayrılıp kurtarma hedefiyle karşılaştırılması ve tatbikat sıklığının biriken belirsizlikle birlikte taranması.

Önceki ders yedeğin kapsamını, sıklığını ve saklamasını sayıya bağladı; o sayılar bir yedek
**kümesinden** okundu. Varsayılanın bıraktığı kalem en sessiz olanıdır: **yedek alma adımı
başarılı döner.** Arşiv üretilir, boyutu yazılır, kayıt tutulur — ve o kayıt yedeğin geri
yüklenebildiğine dair hiçbir şey söylemez. Ölçü geri döndürülebilirliğin **kanıtıdır**: üretimdeki
bayt ile geri gelen baytı karşılaştıran bir özet.

## Tatbikat Gerçekten Koşuyor

- **ST31** — Kurgu bölgesel ölçüm ağının üretim ağacı gerçekten diske yazılıyor: beş kalem,
  içerikleri kendi üretecimizden, tohum 51703; geçici dizin koşum sonunda siliniyor.
- **ST32** — Arşiv kabı kendi biçimimizdir; parola ve tuz kurgudur.
- **ST33** — Beş kusurun üçü gerçekten enjekte edilir (kapsam dışı kalem, çevrilmiş bayt,
  başka anahtar); yanlış sıra ile eksik yetki modeldir.
- **ST34** — Kurtarma süresi hedefi Dayanıklılık Kalıpları kursundan girdidir: 240 dakika. İndirme
  süresi önceki dersin 649,8 GiB tam yedeğinden ve 80 MiB/s'lik kurgu bir hattan türer; öteki dört
  bileşen modeldir.
- **ST35** — Üretim kümesi ayda üç yapılandırma değişikliği ve çeyrekte bir kalem alır; bir tatbikat
  bir kişinin altı saatidir, ayrı bir geri yükleme ortamında koşar.
- **ST36** — Süre ölçülür ama basılmaz; yalnız bant denetiminden geçirilir.

```js
// tatbikat/kap.mjs — arsiv kabi kendi bicimimizdir: bildirim + ardisik icerikler.
// Parola ve tuz kurgudur, gercek sir yazilmaz.
import { readFileSync, writeFileSync, readdirSync, mkdirSync } from "node:fs";
import { join } from "node:path";
import { gzipSync, gunzipSync } from "node:zlib";
import { createCipheriv, createDecipheriv, createHash, scryptSync } from "node:crypto";

export const TOHUM = 51703;              // ureteci kendimiz yaziyoruz, tohum gorunur
let x = TOHUM >>> 0;
export const uret = (n) => {
  const b = Buffer.allocUnsafe(n);
  for (let i = 0; i < n; i += 4) { x = (Math.imul(x, 1103515245) + 12345) >>> 0; b.writeUInt32LE(x, i); }
  return b;
};
export const ozet = (b) => createHash("sha256").update(b).digest("hex");
const tuz = Buffer.from("kurgu-tuz-ornek-gecersiz");
export const ANAHTAR = scryptSync("kurgu-yedek-parolasi-ornek-gecersiz", tuz, 32);
export const BASKA = scryptSync("kurgu-baska-parola-ornek-gecersiz", tuz, 32);
const IV = Buffer.from("kurgu-iv-12b");  // 12 bayt, sabit ve kurgu

export function paketle(dizin, atla = []) {       // atla: plan disi birakilan kalem
  const adlar = readdirSync(dizin).sort().filter((a) => !atla.includes(a));
  const govde = adlar.map((a) => readFileSync(join(dizin, a)));
  const bildirim = Buffer.from(JSON.stringify(adlar.map((a, i) => [a, govde[i].length])));
  const bas = Buffer.allocUnsafe(4);
  bas.writeUInt32LE(bildirim.length, 0);
  return Buffer.concat([bas, bildirim, ...govde]);
}
export function ac(kap, dizin) {
  const n = kap.readUInt32LE(0);
  let p = 4 + n;
  mkdirSync(dizin, { recursive: true });
  for (const [ad, boy] of JSON.parse(kap.subarray(4, 4 + n).toString())) {
    writeFileSync(join(dizin, ad), kap.subarray(p, p + boy));
    p += boy;
  }
}
export function sifrele(kap) {
  const s = createCipheriv("aes-256-gcm", ANAHTAR, IV);
  return { govde: Buffer.concat([s.update(gzipSync(kap)), s.final()]), etiket: s.getAuthTag() };
}
export function coz({ govde, etiket }, anahtar = ANAHTAR) {
  try {                                  // bozuk arsiv ya da yanlis anahtar duser
    const d = createDecipheriv("aes-256-gcm", anahtar, IV).setAuthTag(etiket);
    return gunzipSync(Buffer.concat([d.update(govde), d.final()]));
  } catch { return null; }
}
```

```js
// tatbikat/tatbikat.mjs — GERCEKTEN kosar: kurgu uretim agaci diske yazilir, arsivlenir,
// SILINIR ve geri yuklenir; birebir ayni oldugu ozetle dogrulanir. Sure basilmaz.
import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, readdirSync, rmSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { TOHUM, uret, ozet, paketle, ac, sifrele, coz, BASKA } from "./kap.mjs";

const KALEM = [["olcum.veri", 262144], ["is-emri.veri", 131072], ["tarife.veri", 65536],
  ["servis.yapilandirma", 2048], ["ad-bolge.kayit", 1024]];   // kurgu olcum agi agaci
const ICERIK = KALEM.map(([ad, n]) => [ad, uret(n)]);
const kok = mkdtempSync(join(tmpdir(), "tatbikat-"));
const uretim = join(kok, "uretim");
const durum = () => readdirSync(uretim).sort().map((a) => [a, ozet(readFileSync(join(uretim, a)))]);

function kos({ atla = [], boz = false, anahtar = undefined }) {
  rmSync(uretim, { recursive: true, force: true });
  mkdirSync(uretim, { recursive: true });
  for (const [ad, b] of ICERIK) writeFileSync(join(uretim, ad), b);
  const oncesi = durum();
  let a = sifrele(paketle(uretim, atla));
  if (boz) a = { ...a, govde: Buffer.concat([a.govde.subarray(0, 64),         // tek bayt cevrilir
    Buffer.from([a.govde[64] ^ 1]), a.govde.subarray(65)]) };
  rmSync(uretim, { recursive: true });                  // uretim silindi: donus arsivden
  const kap = coz(a, anahtar);
  if (kap) ac(kap, uretim);
  const m = new Map(kap ? durum() : []);
  return { oncesi, acildi: !!kap, arsiv: a.govde.length,
    ayni: oncesi.filter(([ad, o]) => m.get(ad) === o).length };
}

const t0 = process.hrtime.bigint();
const saglikli = kos({});
const sn = Number(process.hrtime.bigint() - t0) / 1e9;
const bayt = ICERIK.reduce((a, [, b]) => a + b.length, 0);
const geri = new Map(durum());
console.log(`${KALEM.length} kalem, ${bayt} bayt (tohum ${TOHUM}); arsiv ${saglikli.arsiv} bayt`);
console.log("kalem               | uretimdeki ozet (ilk 16) | geri gelen ayni");
console.log("--------------------|--------------------------|----------------");
for (const [ad, o] of saglikli.oncesi)
  console.log(`${ad.padEnd(19)} | ${o.slice(0, 16).padStart(24)} | ` +
    `${(geri.get(ad) === o ? "evet" : "hayir").padStart(15)}`);

// MODEL: sira bozulunca kac adim bos veriyle acilir
const BAGLI = { sir: [], veri: ["sir"], yapilandirma: [], servis: ["veri", "yapilandirma"] };
const YANLIS = ["servis", "veri", "yapilandirma", "sir"];
const bos = YANLIS.filter((a, i) => BAGLI[a].some((b) => YANLIS.indexOf(b) > i)).length;
// MODEL: geri yukleme kimliginin gereken/verilen yetkileri
const GEREKEN = { "yedek-deposu": "oku", "nesne-deposu": "yaz", "sir-deposu": "oku", "servis-yoneticisi": "baslat" };
const VERILEN = { "yedek-deposu": "oku", "sir-deposu": "oku" };
const yetki = Object.keys(GEREKEN).filter((k) => VERILEN[k] !== GEREKEN[k]);

console.log("\ndeneme                     | acildi | birebir | eksik | yedek alma adimi");
console.log("---------------------------|--------|---------|-------|------------------");
let bulunan = 2;                                        // iki MODEL kusuru bastan
for (const [ad, secenek] of [["saglikli tatbikat", {}],
  ["eksik kalem (yapilandirma)", { atla: ["servis.yapilandirma"] }],
  ["bozuk arsiv (tek bayt)", { boz: true }], ["cozulemeyen sifre", { anahtar: BASKA }]]) {
  const r = kos(secenek), n = r.oncesi.length;
  if (r.ayni < n) bulunan += 1;
  console.log(`${ad.padEnd(26)} | ${(r.acildi ? "evet" : "hayir").padStart(6)} | ` +
    `${(r.ayni + "/" + n).padStart(7)} | ${String(n - r.ayni).padStart(5)} | ` +
    `${(r.ayni < n ? "basarili gorundu" : "basarili").padStart(16)}`);
}
console.log(`yanlis sira (MODEL)        | ${bos}/${YANLIS.length} adim bos veriyle aciliyor` +
  `${" ".repeat(11)}| basarili gorundu`);
console.log(`eksik yetki (MODEL)        | ${yetki.length} kalem: ${yetki.join(", ")} | basarili gorundu`);
console.log(`\ntatbikatin buldugu kusur ${bulunan}; yedek alma adiminda gorulen 0`);
const mib = bayt / 1024 / 1024, [ALT, UST] = [0.5, 20000];   // MiB/s bandi; ham olcum basilmaz
console.log(`yedekle+sil+geri yukle hizi ${ALT}-${UST} MiB/s bandinda: ` +
  `${mib / sn >= ALT && mib / sn <= UST ? "evet" : "hayir"}`);
rmSync(kok, { recursive: true, force: true });               // gecici agac silinir
```

```
5 kalem, 461824 bayt (tohum 51703); arsiv 462113 bayt
kalem               | uretimdeki ozet (ilk 16) | geri gelen ayni
--------------------|--------------------------|----------------
ad-bolge.kayit      |         b7c0e693cd032524 |            evet
is-emri.veri        |         5c4512d9a8016d51 |            evet
olcum.veri          |         3edf42c01d4f883f |            evet
servis.yapilandirma |         4ead0d5566a44d75 |            evet
tarife.veri         |         434443d05cecee54 |            evet

deneme                     | acildi | birebir | eksik | yedek alma adimi
---------------------------|--------|---------|-------|------------------
saglikli tatbikat          |   evet |     5/5 |     0 |         basarili
eksik kalem (yapilandirma) |   evet |     4/5 |     1 | basarili gorundu
bozuk arsiv (tek bayt)     |  hayir |     0/5 |     5 | basarili gorundu
cozulemeyen sifre          |  hayir |     0/5 |     5 | basarili gorundu
yanlis sira (MODEL)        | 2/4 adim bos veriyle aciliyor           | basarili gorundu
eksik yetki (MODEL)        | 2 kalem: nesne-deposu, servis-yoneticisi | basarili gorundu

tatbikatin buldugu kusur 5; yedek alma adiminda gorulen 0
yedekle+sil+geri yukle hizi 0.5-20000 MiB/s bandinda: evet
```

Birinci tablo bu dersin kanıtıdır: üretim ağacı yazıldı, arşivlendi, **silindi** ve yalnız arşivden
geri getirildi; beş kalemin beşinde özetler aynı çıktı. Bir cümle değil, beş karşılaştırma.

İkinci tablonun son sütunu bulgudur. Kapsam dışı bırakılan yapılandırma geri gelmiyor ama arşiv
açılıyor; tek baytı çevrilmiş arşiv ile başka anahtarla şifrelenmiş arşiv hiç açılmıyor ve
beş kalem birden gidiyor. Yanlış sırada dört adımın ikisi boş veriyle açılıyor, kimlikte iki yetki
eksik. **Beş kusurun beşi de yedek alma adımında görünmedi.**

## Süre Bileşenlere Ayrılıyor

```js
// tatbikat/sure.mjs — geri yukleme suresi bilesenlerine ayrilir, hedefle karsilastirilir ve
// tatbikat sikligi taranir. MODELDIR; indirme suresi 05'in tam yedek boyutundan turer.
const HEDEF = 240;                       // dakika; onceki kurstan girdi
const TAM_GIB = 649.8, HAT_MIBS = 80;    // tam yedek boyutu; hat hizi kurgudur
const INDIRME = (TAM_GIB * 1024) / HAT_MIBS / 60;
const BILESEN = {                        // [tatbikatsiz, tatbikatli] dakika
  bulma: [95, 12], indirme: [INDIRME, INDIRME], acma: [65, 38],
  dogrulama: [40, 15], "servisi acma": [85, 22],
};
const g = (x, n, d = 1) => x.toFixed(d).padStart(n);
const topla = (i) => Object.values(BILESEN).reduce((a, b) => a + b[i], 0);
const PAY = HEDEF / Object.keys(BILESEN).length;         // esit pay

console.log(`hedef ${HEDEF} dk; tam yedek ${TAM_GIB} GiB, hat ${HAT_MIBS} MiB/s, esit pay ${PAY} dk.`);
console.log("\nbilesen      | tatbikatsiz | tatbikatli | hedefin yuzdesi");
console.log("-------------|-------------|------------|----------------");
for (const [ad, [y, t]] of Object.entries(BILESEN))
  console.log(`${ad.padEnd(12)} | ${g(y, 11)} | ${g(t, 10)} | ${("%" + g((100 * t) / HEDEF, 6)).padStart(15)}`);
console.log(`${"toplam".padEnd(12)} | ${g(topla(0), 11)} | ${g(topla(1), 10)} | ` +
  `${("%" + g((100 * topla(1)) / HEDEF, 6)).padStart(15)}`);
const asan = Object.entries(BILESEN).filter(([, [, t]]) => t > PAY).map(([a]) => a);
console.log(`tatbikatli surede esit payi asan ${asan.length} bilesen: ${asan.join(", ")}`);

const DEGISIM = 3 / 30 + 1 / 90;         // gunluk degisim: ayda 3 yapilandirma, ceyrekte 1 kalem
const KALEM = 16, SAAT = 6;              // envanter; bir tatbikat alti saat
console.log("\nsiklik    | yilda | yillik saat | dogrulanmamis degisiklik | geri yukleme | hedef");
console.log("----------|-------|-------------|--------------------------|--------------|-------");
for (const gun of [90, 180, 365, null]) {
  const n = gun ? Math.floor(365 / gun) : 0;
  const belirsiz = gun ? gun * DEGISIM : 365 * DEGISIM + KALEM;
  const sure = gun ? topla(1) : topla(0);
  console.log(`${(gun ? gun + " gunde" : "hic").padEnd(9)} | ${String(n).padStart(5)} | ` +
    `${String(n * SAAT).padStart(11)} | ${(g(belirsiz, 4) + (gun ? " kalem" : " kalem+kume")).padStart(24)}` +
    ` | ${g(sure, 12)} | ${(sure > HEDEF ? "asildi" : "tuttu").padStart(6)}`);
}
```

```
hedef 240 dk; tam yedek 649.8 GiB, hat 80 MiB/s, esit pay 48 dk.

bilesen      | tatbikatsiz | tatbikatli | hedefin yuzdesi
-------------|-------------|------------|----------------
bulma        |        95.0 |       12.0 |         %   5.0
indirme      |       138.6 |      138.6 |         %  57.8
acma         |        65.0 |       38.0 |         %  15.8
dogrulama    |        40.0 |       15.0 |         %   6.3
servisi acma |        85.0 |       22.0 |         %   9.2
toplam       |       423.6 |      225.6 |         %  94.0
tatbikatli surede esit payi asan 1 bilesen: indirme

siklik    | yilda | yillik saat | dogrulanmamis degisiklik | geri yukleme | hedef
----------|-------|-------------|--------------------------|--------------|-------
90 gunde  |     4 |          24 |               10.0 kalem |        225.6 |  tuttu
180 gunde |     2 |          12 |               20.0 kalem |        225.6 |  tuttu
365 gunde |     1 |           6 |               40.6 kalem |        225.6 |  tuttu
hic       |     0 |           0 |          56.6 kalem+kume |        423.6 | asildi
```

Tatbikatsız düzende geri yükleme 423,6 dakika sürüyor, hedefi 183,6 dakika aşıyor; tatbikatlı
düzende 225,6 dakikaya iniyor ve hedef 14,4 dakikalık payla tutuyor. Tatbikatın kısalttığı şey
bilgidir: doğru noktayı bulma 95 dakikadan 12'ye, servisleri açma 85'ten 22'ye iniyor — prova
edilmiş adımlar.

İndirme sütunu hiç değişmiyor: 138,6 dakika, hedefin yüzde 57,8'i ve eşit payı aşan tek bileşen. Bu
süre bilgi eksikliğinden değil, 649,8 GiB'i 80 MiB/s'lik bir hattan geçirmekten geliyor; tatbikat
ölçer ama kısaltmaz. **Hedefi tutturmanın yolu daha çok tatbikattan değil, yedeği geri
yükleneceği yere yaklaştırmaktan geçiyor.** Sıklık taraması bedeli ve alternatifini yan yana
koyuyor: doksan günde bir tatbikat yılda yirmi dört saat ve 10 kalemlik belirsizlik, yılda bir
tatbikat altı saat ve 40,6 kalem. Hiç yapılmadığında bedel sıfır, belirsizlik on altı kalemin
tamamı ve süre hedefi aşıyor.

## Özet

- Yedek alma adımı beş kusurun beşinde de başarılı döndü; hepsi yalnız tatbikatta görüldü: kapsam
  dışı kalem, bozuk arşiv, çözülemeyen şifre, yanlış sıra, eksik yetki.
- Kanıt bir özet karşılaştırmasıdır: beş kalem yazıldı, arşivlendi, silindi, geri yüklendi ve özetler
  aynı çıktı.
- Geri yükleme süresi tatbikatsız 423,6, tatbikatlı 225,6 dakikadır; hedef yüzde 94 doluluğla
  tutar. Tatbikat dört bileşeni kısaltır, indirmeye dokunmaz: 138,6 dakika hedefin yüzde 57,8'i ve
  eşit payı aşan tek bileşendir.
- Tatbikat sıklığı bir bedel-belirsizlik takasıdır: doksan günde bir yılda 24 saat ve 10 kalem,
  hiç yapılmadığında 0 saat ve on altı kalemin tamamı.

## Kurs Kapanışı

| Ders | Varsayılanın açık bıraktığı | Kapatılan / yanlış kapatılan | Kapatmanın getirdiği yeni yüzey |
|---|---|---|---|
| Web sunucusu rolleri | 18 kalem | 13 kapandı / 4 meşru iş | 3 yeni kalem |
| Ters vekil yapılandırması | 4 kayıp bilgi | 4 çözüldü / 2 kalem gizlendi | sahte başlık, 4 istek |
| Taşıma katmanı sonlandırma | 19 zayıf kalem | 19 kapandı / 65 cihaz | sertifika 6 noktada |
| Sertifika otomasyonu | 1.700 saat pencere | 0 saat / 12 gereksiz yenileme | 4 yeni kalem |
| Önbellek sunucusu | 179 sızan istek | 0 sızıntı / 2 kat yük | kaçan yayın, sessiz pencere |
| Servis ağı | 40 servise 40 dokunuş | 508 iş kalemi / 3 serviste pahalı | 162 yan araba kalemi |
| DNS yönetimi | 4 ölü, 2 devralınabilir kayıt | 5 dakikaya / 288 kat sorgu | bölgeye yazan kimlik |
| Gönderen doğrulama kayıtları | sahipsiz gönderim serbest | 5/6 sahte / 2 meşru düştü | 254 fazla yetkili adres |
| Alan adı politika kaydı | 61 sahte ulaşıyor | 49 engellendi / 43 meşru ayrıldı | 12 uyumlu taklit |
| Posta teslim sorunları | 12 puan tavan | tavan kalktı / 1.078 ileti kayıp | alıcı kararı ölçülemez |
| Güvenlik duvarı yapılandırması | 100 kalem, 107.265 deneme | 10 satır hepsi / 2 akış | dış satır, 20.650 deneme |
| Uzak erişim sertleştirme | 2.340 üçlü, 16.505 deneme | 16.505 kapandı / 0 meşru | 34 anahtar kopyası |
| Sır yönetimi sistemleri | 36 kalem, sonsuz pencere | 2,5 dakika / 9 kalem ömürsüz | tek nokta, 18 örnek |
| Yama yönetimi | 60 kalem, 28,94 gün | 1,22 güne / 4 geri alma, 82 kesinti | 15 kalem, yama ajanı |
| Yedekleme stratejisi | 13 kalem kapsam dışı | 3 kaleme / servis yine 2/4 | okunabilir yüzey iki katı |
| Geri yükleme tatbikatı | 5 kusur görünmez, 423,6 dk | 5 bulundu / 225,6 dk | 24 saat, 2 eksik yetki |

İkinci sütunda hiçbir satırda bir kararın izi yok: **varsayılan bir karar değildir, kimsenin
vermediği karardır.** Üçüncü sütunda yanlış kapatma on altı satırın on dördünde doludur: hiçbir
adım bedava değil. Dördüncü sütunda üç yüzey türü tekrar ediyor: **yeni bir kimlik ya da yazma
yetkisi** beş derste, **bütün yükü taşıyan tek nokta** dört derste, **kendisi yapılandırılması
gereken yeni bir katman** dört derste. Her savunma kendi yüzeyini getirir — kapatılan kalem yok
olmaz, biçim değiştirir.

Yedi kurstur her katman ayrı ayrı kuruldu ve sertleştirildi. Tablodaki her satır bir kararlar
dizisidir: hangi kapı, hangi eşik, hangi kalem. Ama bunların hepsini **her ekibin yeniden
kurması** mı gerekiyor? Platform Mühendisliği bu soruyla başlıyor.
