Ders 18 / 22
Dosya Düğümleri ve Meta Veri
Aynı dosya sisteminde blok doluluk 0,0125 iken dosya düğümü doluluğu 1,0000 ve yazma başarısız: disk yüzde bir dolu ve sistem dolu. Adı silinip tanıtıcısı açık kalan bir dosya 120.000 bloğu du çıktısından gizliyor.
İçindekiler
Önceki ders meta veri defterini bir tasarım ekseni olarak saydı: sabit mi tutulur, gerektikçe mi büyür. Bu ders o defterin içindeki tek kaydı alır ve onun bir kaynak olduğunu gösterir — tükenebilen, tükendiğinde tuhaf bir arıza üreten bir kaynak.
Kurgu sunucunun /veri bölümü otuz bin ölçüm dosyası taşıyor ve bölümün doluluğu yüzde birin
biraz üzerinde. Bu ders o bölüme yeni bir dosya yazmayı deneyecek ve deneme başarısız
olacak. Aradaki çelişki bir hata değil, iki ayrı sınırın aynı hata iletisini üretmesidir.
Dosya Düğümünün Taşıdığı Kayıt
Dosya düğümü (inode), bir dosyanın adı dışındaki her şeyini taşıyan kayıttır. İşletim Sistemi Kavramları kursundaki dosya sistemi soyutlaması dersi bu kaydı tanımladı ve adın dosyada değil dizinde durduğunu gösterdi; o tanım burada tekrarlanmaz. Eklenen tek şey operatörün görebildikleridir.
Kayıt bir numarayla anılır ve o numara dosya sistemi içinde tekildir. ls -i numarayı
listeler, stat kaydın tamamını açar, find bir numaradan dosyanın adlarına geri gidebilir.
Kaydın alanları arasında en çok yanlış okunanı bağ sayısıdır: kaça dizin girdisi bu
kayda işaret ediyor. Bağ sayısı sıfıra düştüğünde ve kaydı açık tutan hiçbir süreç
kalmadığında blok listesi serbest bırakılır. İki koşul da gereklidir ve ikincisi bu dersin
ikinci ölçümünün konusudur.
Aşağıdaki döküm stat çıktısının biçimini gösteren bir örnek dökümdür; çalıştırılmamıştır
ve bu derste hiçbir sayı iddiası buradan gelmez.
File: /veri/olcum/2f9c.veri Size: 1731 Blocks: 8 IO Block: 4096 regular file Device: 8,18 Inode: 1048604 Links: 1 Access: (0640/-rw-r-----) Uid: ( 997/ olcum) Gid: ( 997/ olcum)
Dökümde Size ile Blocks ayrı satırlarda durur ve ikisi ayrı şeyi söyler: birincisi
dosyanın bildirdiği bayt, ikincisi dosya sisteminin gerçekten ayırdığı yer. Bu ayrım ikinci
ölçümde altı yanlış okumanın kaynağı olacak.
İki Sınır, Tek Hata İletisi
Bir dosya sistemi iki ayrı kaynağı tüketir. Birincisi bloktur: içeriğin yazıldığı yer. İkincisi dosya düğümüdür: her dosya için bir tane gerekir ve sabit tablo tutan tasarımlarda toplam sayı biçimlendirme anında sabitlenmiştir. İkisinden biri bittiğinde yazma aynı hata iletisiyle reddedilir.
- DP14 — Ortak tanımın dosya sistemi 2.621.440 blok ve 32.768 dosya düğümü taşır; blok 4096 bayttır. Sayılar modeldendir, hiçbir gerçek aygıttan alınmamıştır.
- DP15 — Küçük dosya iş yükünde boyutlar 1 ile 2000 bayt arasındadır; her dosya bir blok tutar. Büyük dosya iş yükünde üst sınır 2.000.000 bayttır.
- DP16 — Uyarı kuralı doluluk 0,90 eşiğine bakar. Kural üç biçimde sınanır: yalnız blok yüzdesi, yalnız dosya düğümü yüzdesi, ikisi birlikte.
- DP17 — Sınanan tanı tek sorudur: bu duruma yeni bir 1 KB dosya yazılabilir mi.
"""M03/K03 ortak tanim (Bolum 6): iki ayri sinir , tek hata iletisi.""" TOHUM = 20260218 BLOK = 4096 def uretec(tohum): d = tohum def sonraki(n): nonlocal d d = (d * 1103515245 + 12345) % 2147483648 return d % n return sonraki def dosya_sistemi(tohum=TOHUM, dosya=30000, ust=2000, dugum_sayisi=32768, blok_sayisi=2621440): r = uretec(tohum) boyutlar = [r(ust) + 1 for _ in range(dosya)] kullanilan_blok = sum(-(-b // BLOK) for b in boyutlar) return {"dosya": dosya, "kullanilan_blok": kullanilan_blok, "toplam_blok": blok_sayisi, "blok_doluluk": round(kullanilan_blok / blok_sayisi, 4), "kullanilan_dugum": dosya, "toplam_dugum": dugum_sayisi, "dugum_doluluk": round(dosya / dugum_sayisi, 4)} def yazma_denemesi(fs, boyut): """Yeni dosya yazilabilir mi. Iki ayri sinir , tek hata iletisi.""" blok_yeter = fs["kullanilan_blok"] + -(-boyut // BLOK) <= fs["toplam_blok"] dugum_yeter = fs["kullanilan_dugum"] + 1 <= fs["toplam_dugum"] return blok_yeter and dugum_yeter for d in (30000, 32768): fs = dosya_sistemi(dosya=d) print(f"{d:6d} dosya | blok doluluk {fs['blok_doluluk']:.4f}" f" | dugum doluluk {fs['dugum_doluluk']:.4f}" f" | yeni 1 KB dosya: {yazma_denemesi(fs, 1024)}") print() KUCUK = [(d, 2000) for d in (4096, 12288, 20480, 28672, 32000, 32768)] BUYUK = [(d, 2000000) for d in (2000, 4000, 6000, 8000, 10000, 12000)] KURAL = {"yalniz blok yuzdesi": lambda f: f["blok_doluluk"] < 0.90, "yalniz dugum yuzdesi": lambda f: f["dugum_doluluk"] < 0.90, "ikisi birlikte": lambda f: f["blok_doluluk"] < 0.90 and f["dugum_doluluk"] < 0.90} print("is yuku dosya blok doluluk dugum doluluk yazilabilir") for ad, yuk in (("kucuk", KUCUK), ("buyuk", BUYUK)): for d, ust in yuk: fs = dosya_sistemi(dosya=d, ust=ust) print(f"{ad:7s} {d:6d} {fs['blok_doluluk']:13.4f} {fs['dugum_doluluk']:14.4f}" f" {yazma_denemesi(fs, 1024)}") print() print("kural kacirilan yanlis uyari yanlis tani") for ad, k in KURAL.items(): kacan = uyari = 0 for _, yuk in (("kucuk", KUCUK), ("buyuk", BUYUK)): for d, ust in yuk: fs = dosya_sistemi(dosya=d, ust=ust) guvenli, gercek = k(fs), yazma_denemesi(fs, 1024) kacan += guvenli and not gercek uyari += (not guvenli) and gercek print(f" {ad:20s} {kacan:9d} {uyari:12d} {kacan + uyari:11d}") print() for tohum in (TOHUM, 20260219): satir = [] for ad, k in KURAL.items(): y = 0 for _, yuk in (("kucuk", KUCUK), ("buyuk", BUYUK)): for d, ust in yuk: fs = dosya_sistemi(tohum, d, ust) y += k(fs) != yazma_denemesi(fs, 1024) satir.append(f"{ad} {y}") print(f"tohum {tohum}: " + " | ".join(satir) + " / 12")
30000 dosya | blok doluluk 0.0114 | dugum doluluk 0.9155 | yeni 1 KB dosya: True 32768 dosya | blok doluluk 0.0125 | dugum doluluk 1.0000 | yeni 1 KB dosya: False is yuku dosya blok doluluk dugum doluluk yazilabilir kucuk 4096 0.0016 0.1250 True kucuk 12288 0.0047 0.3750 True kucuk 20480 0.0078 0.6250 True kucuk 28672 0.0109 0.8750 True kucuk 32000 0.0122 0.9766 True kucuk 32768 0.0125 1.0000 False buyuk 2000 0.1894 0.0610 True buyuk 4000 0.3693 0.1221 True buyuk 6000 0.5553 0.1831 True buyuk 8000 0.7416 0.2441 True buyuk 10000 0.9283 0.3052 True buyuk 12000 1.1168 0.3662 False kural kacirilan yanlis uyari yanlis tani yalniz blok yuzdesi 1 1 2 yalniz dugum yuzdesi 1 1 2 ikisi birlikte 0 2 2 tohum 20260218: yalniz blok yuzdesi 2 | yalniz dugum yuzdesi 2 | ikisi birlikte 2 / 12 tohum 20260219: yalniz blok yuzdesi 2 | yalniz dugum yuzdesi 2 | ikisi birlikte 2 / 12
Üç sayı yan yana. Kâhin: 32.768 dosyalı durumda dosya düğümü tablosu tamamen doludur ve bloğun yüzde 98,75’i boştur; yazma başarısızdır. Araç çıktısı: doluluk sorulduğunda gelen sayı 0,0125’tir — yüzde bir. Yanlış tanı: on iki durumun ikisinde uyarı kuralı yanılıyor ve bu iki yanlış, kural değiştirilerek yok edilmiyor.
Ortak tanımın iki satırı kursun en temiz örneğidir. Otuz bin dosyada blok doluluk 0,0114, dosya düğümü doluluğu 0,9155 ve yazma başarılı; 32.768 dosyada blok doluluk 0,0125, dosya düğümü doluluğu 1,0000 ve yazma başarısız. Aradaki fark 2768 dosyadır ve toplam alanın binde biridir. Disk yüzde bir dolu ve sistem dolu.
Kural tablosu ikinci iddiayı ödüyor. Yalnız blok yüzdesine bakan kural bir arızayı kaçırıyor ve bir kez yersiz uyarı veriyor. Yalnız dosya düğümü yüzdesine bakan kural da aynı sayıyı veriyor — büyük dosya iş yükünde blok dolarken dosya düğümü yüzdesi 0,3662’de kalıyor. İkisi birlikte kullanıldığında kaçırılan sıfıra iniyor, ama yersiz uyarı ikiye çıkıyor ve toplam yine 2. Sütun eklemek yanlış tanının türünü değiştirdi, sayısını değil. İkinci tohumda üç kuralın üçü de yine 2 veriyor; sonuç kurguya değil, iki sınırın birbirinden bağımsız oluşuna bağlı.
Adı Olmayan Dosya
İkinci ölçüm aynı dosya sisteminde ayrılan alanı üç ayrı yöntemle sayıyor. df dosya
sisteminin kendi defterini okur, du dizin ağacını gezip bulduğu dosyaların bloklarını
toplar, dosya listesinden elde edilen toplam ise bildirilen baytları toplar. Üçü de aynı
soruya cevap veriyor ve üçü aynı sayıyı vermiyor.
- DP18 — Beş an sırayla geçilir: başlangıç, aynı dosyalara 200 ikinci ad verilmesi, 40 seyrek dosyanın yazılması, 120.000 bloklu günlük dosyasının silinmesi ve o dosyayı açık tutan tanıtıcının kapanması.
- DP19 — Aynı dosya düğümüne verilen ikinci ada sabit bağ (hard link) denir. Seyrek dosya (sparse file) 25.600 blokluk boyut bildirir, gerçekte 8 blok ayırır. Meta verinin kendi tuttuğu yer bu ölçümde sayılmaz; kâhin yalnız veri bloklarıdır.
"""Ayrilan blok gercekte kac , hangi arac kacini goruyor.""" TOHUM = 20260218 BLOK = 4096 DOSYA = 30000 SEYREK = 40 # seyrek dosya sayisi SEYREK_MANTIKSAL = 25600 # blok cinsinden bildirilen boyut SEYREK_AYRILAN = 8 # gercekte ayrilan blok GUNLUK_BLOK = 120000 # buyuk gunluk dosyasi SERT_BAG = 200 # ayni dosyaya verilen ikinci adlar def uretec(tohum): d = tohum def sonraki(n): nonlocal d d = (d * 1103515245 + 12345) % 2147483648 return d % n return sonraki def taban(tohum=TOHUM): r = uretec(tohum) return [r(2000) + 1 for _ in range(DOSYA)] def durum(an, bayt): """an 0..4 . Kahin: dosya sisteminin gercekten ayirdigi veri blogu.""" seyrek = an >= 2 gunluk_var = an < 4 # an 3'te silindi , tanitici acik ayrilan = DOSYA + GUNLUK_BLOK * gunluk_var + SEYREK * SEYREK_AYRILAN * seyrek # du: yalniz ADI OLAN dosyalari gezer , sert bagi bir kez sayar du = DOSYA + GUNLUK_BLOK * (an < 3) + SEYREK * SEYREK_AYRILAN * seyrek # dosya listesi toplami: bildirilen bayt , her ADI ayri sayar ls = sum(bayt) + sum(bayt[:SERT_BAG]) * (an >= 1) ls += GUNLUK_BLOK * BLOK * (an < 3) ls += SEYREK * SEYREK_MANTIKSAL * BLOK * seyrek return {"kahin": ayrilan, "df": ayrilan, "du": du, "ls": ls // BLOK} AN = ("t0 baslangic", "t1 sert bag", "t2 seyrek dosya", "t3 gunluk silindi", "t4 tanitici kapandi") BAYT = taban() print("an kahin df du ls toplami") for i, ad in enumerate(AN): d = durum(i, BAYT) print(f"{ad:18s} {d['kahin']:8d} {d['df']:8d} {d['du']:8d} {d['ls']:15d}") print() print("arac dogru okuma yanlis okuma") for arac in ("df", "du", "ls"): yanlis = sum(durum(i, BAYT)[arac] != durum(i, BAYT)["kahin"] for i in range(5)) print(f" {arac:9s} {5 - yanlis:11d} {yanlis:12d}") print("yanlis tani:", sum(durum(i, BAYT)[a] != durum(i, BAYT)["kahin"] for i in range(5) for a in ("df", "du", "ls")), "/ 15") print() for tohum in (TOHUM, 20260219): b = taban(tohum) print(f"tohum {tohum}: t0 kahin {durum(0, b)['kahin']} ls {durum(0, b)['ls']}" f" | t3 kahin {durum(3, b)['kahin']} du {durum(3, b)['du']}" f" | t4 kahin {durum(4, b)['kahin']} ls {durum(4, b)['ls']}")
an kahin df du ls toplami t0 baslangic 150000 150000 150000 127313 t1 sert bag 150000 150000 150000 127361 t2 seyrek dosya 150320 150320 150320 1151361 t3 gunluk silindi 150320 150320 30320 1031361 t4 tanitici kapandi 30320 30320 30320 1031361 arac dogru okuma yanlis okuma df 5 0 du 4 1 ls 0 5 yanlis tani: 6 / 15 tohum 20260218: t0 kahin 150000 ls 127313 | t3 kahin 150320 du 30320 | t4 kahin 30320 ls 1031361 tohum 20260219: t0 kahin 150000 ls 127292 | t3 kahin 150320 du 30320 | t4 kahin 30320 ls 1031339
Üç sayı yan yana. Kâhin: üçüncü anda gerçekten ayrılmış olan 150.320 bloktur. Araç
çıktısı: du aynı anda 30.320 blok görüyor. Yanlış tanı: on beş okumanın altısı
yanlış — beşi dosya listesi toplamından, biri du çıktısından.
Üçüncü an operatörün en sık düştüğü tuzaktır. Günlük dosyası silinmiştir, du çıktısı 120.000
blok azalmıştır ve dizin ağacında o dosya yoktur; ama onu açık tutan süreç hâlâ çalıştığı için
bağ sayısı sıfıra düşmüş olsa bile bloklar serbest bırakılmamıştır. df doğruyu söylemeye
devam eder ve iki araç arasındaki 120.000 bloklu fark açıklanmadıkça yer açma girişimi
sonuçsuz kalır. Çözüm silmek değil, dosyayı açık tutan süreci yeniden başlatmaktır; hangi
sürecin tuttuğu ise açık tanıtıcıları listeleyen bir araçla bulunur.
Dosya listesi toplamı beş anın beşinde de yanılıyor ve iki ayrı yönde yanılıyor. Başlangıçta eksik sayıyor: otuz bin küçük dosyanın bildirdiği bayt toplamı 127.313 blok karşılığıdır, gerçekte 150.000 blok ayrılmıştır çünkü 1731 baytlık bir dosya da tam bir blok tutar. Seyrek dosyalar yazıldıktan sonra fazla sayıyor: 40 dosya 1.024.000 blokluk boyut bildiriyor, gerçekte 320 blok tutuyor. İkinci tohumda bu iki sayı 127.292 ve 1.031.339 oluyor; yön değişmiyor.
Tükenmiş Tabloyu Onarmak
Dosya düğümü tükendiğinde yapılabilecek üç şey vardır ve üçünün de bir bedeli vardır. Birincisi dosya silmektir; bu, tablodaki kaydı geri verir ve tek satırlık ölçüm dosyalarının bir arşive toplanması genellikle en hızlı çözümdür. İkincisi dosya sistemini büyütmektir; sabit tablo tutan tasarımlarda büyütme tabloyu da genişletebilir, ama oranı biçimlendirme anındaki karara bağlıdır. Üçüncüsü yeniden biçimlendirmektir ve bu, bölümdeki her şeyi geri alınamaz biçimde siler.
Üçüncü yol bu derste çalıştırılabilir tam biçimde verilmez. Biçimlendirme komutu, dosya
düğümü sayısını belirleyen seçeneğiyle birlikte yazıldığında yanlış bir bölüm adıyla
çalıştırılırsa uyarı üretmeden bütün veriyi siler ve geri alınamaz. Güvenli sınama yolu
üç adımdır: hedef bölümün kimliğini blkid ile doğrulamak, denemeyi geri döngü aygıtı
olarak bağlanmış bir dosyada yapmak ve gerçek bölümde çalıştırmadan önce bölümün bir anlık
görüntüsünü almak.
Önlemin kendisi ise ölçmektir. Dosya düğümü doluluğu, blok doluluğuyla aynı sıklıkta sorulmadığı sürece tablonun dolduğu an bir uyarıya değil, bir arızaya dönüşür; ve arıza geldiğinde çıktıdaki tek sayı hâlâ yüzde bir olacaktır.
Özet
- Dosya düğümü, bir dosyanın adı dışındaki her şeyini taşıyan kayıttır; bağ sayısı sıfıra düşmesi tek başına yer boşaltmaz, kaydı açık tutan süreç de kalmamalıdır.
- Bir dosya sistemi iki ayrı kaynağı tüketir ve ikisi de aynı hata iletisini üretir: 30.000 dosyada blok doluluk 0,0114 ve dosya düğümü doluluğu 0,9155 iken yazma başarılı, 32.768 dosyada 0,0125 ve 1,0000 iken başarısız.
- Uyarı kuralı yalnız blok yüzdesine baktığında on iki durumda 2 yanlış tanı veriyor; yalnız dosya düğümü yüzdesine baktığında da 2, ikisi birlikte kullanıldığında da 2. Kaçırılan sıfıra iniyor, yersiz uyarı ikiye çıkıyor.
- Ayrılan alan üç yöntemle sayıldığında on beş okumanın altısı yanlış: dosya listesi toplamı
beş anın beşinde yanılıyor,
duise adı silinip tanıtıcısı açık kalan 120.000 bloğu göremiyor. - Tükenmiş tabloyu onarmanın üç yolundan biri yeniden biçimlendirmedir ve geri alınamaz; bu ders o komutu tam biçimde vermez, güvenli sınama yolu kimlik doğrulaması, geri döngü aygıtı ve anlık görüntüdür.
Sonraki Adım
Bu dersin ölçümleri tek bir varsayıma dayanıyordu: bakılan dizin gerçekten o dosya sisteminin dizini. Oysa bir dosya sistemi ağaçta bir noktaya takılır ve o nokta takma öncesinde de sonrasında da yazılabilir bir dizindir. Sonraki ders takma noktasını ölçer ve bir dosya sistemi takılmadan önce oraya yazılan verinin nereye gittiğini, takıldıktan sonra hangi araçların onu göremediğini sayar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.