İçeriğe geç
NarDBv0.2.0-dev

Dosya biçimi

.ndbc kapsayıcısının içi — dosyalar, sayfalar, yazma günlüğü, katalog ve B+tree.

Bir veritabanı bir klasördür:

Metin
magaza.ndbc/
  nardb.toml            biçim sürümü, sayfa boyutu, sarılı veri anahtarı
  nardb.lock            tek sahip kilidi
  wal.log               yazma günlüğü (write-ahead log)
  catalog.db            katalog belgesi ve tablo sayaçları
  indexes.db            ikincil indeksler, partition'lar arası
  schemas/s0001/p0.db   şema 1'in partition 0'ı
  schemas/s0001/p1.db   ...

Dosya adları anlam taşımaz: şemalar s0001 gibi kimliklerle anılır, adları kataloğun içindedir. Partition dosyaları ilk satır eklendiğinde oluşur. Bir şema silinince dosyaları da silinir.

Sayfalar#

Her .db dosyası eşit boyutlu sayfalardan oluşur. Sayfa boyutu varsayılan olarak 4 KiB'tır; 4 ile 64 KiB arasında ikinin bir kuvveti seçilebilir. Bütün tamsayılar little-endian yazılır.

Sayfa 0 dosyanın başlığıdır: magic (NARDB\r\n\x1a), biçim sürümü, sayfa boyutu, özellik bitleri (tanınmayan bir bit varsa dosya açılmaz), sayfa sayısı, boş sayfa listesi, kök sayfa ve CRC-32C sağlama toplamı.

Şifreli bir veritabanında sayfa 0 dışındaki her sayfa diskte şifrelidir (bkz. Şifreleme); aşağıdaki düzen sayfanın çözülmüş halidir.

Diğer sayfaların her birinin başında 16 baytlık bir başlık vardır: sayfa türü ve sayfanın CRC-32C sağlama toplamı. Sağlama toplamı tutmayan bir sayfa okunmaz ve ErrCorrupt döner. Motor bozuk veriyi onarmaya çalışmaz.

TürKullanım
freelistboş sayfa listesi
branch / leafB+tree dal ve yaprakları
overflowsayfaya sığmayan değerler ve katalog belgesi
table-metatablo başına satır sayısı ve otomatik artan sayaçlar

Yazma günlüğü ve işlemler#

Her ifade tek bir işlemdir. Bir ifade sırasında değişen bütün sayfalar, hangi dosyada olurlarsa olsunlar, önce işlemin içinde tutulur. Commit şu sırayla olur:

  1. Değişen sayfaların tam görüntüleri ve bir commit kaydı wal.log'a yazılır ve diske indirilir (fsync).
  2. Ancak bundan sonra değişiklik görünür olur.
  3. Günlük 8 MiB'a ulaşınca ya da veritabanı kapanırken sayfalar dosyalarına aktarılır (checkpoint) ve günlük boşaltılır.

Açılışta günlük taranır. Commit kaydıyla biten işlemler geri yüklenir, yarım kalan son işlem atılır. Her günlük kaydının kendi sağlama toplamı vardır ve her boşaltmada değişen bir tuz taşır; böylece önceki nesilden kalmış kayıtlar yeni günlükle karışmaz.

Sonuçları:

  • Ani bir kapanmada commit edilmiş her ifade geri gelir.
  • Katalog, bir partition ve bir indeks aynı ifadede değişiyorsa, üçü birlikte uygulanır ya da hiçbiri uygulanmaz.
  • Hata veren bir ifade hiçbir şey yazmamış olur.

Önbellek#

Commit edilmiş sayfalar bellekte en son kullanılan önceliğiyle tutulur. Varsayılan 4096 sayfadır; 4 KiB sayfalarla 16 MiB eder. Okumalar önce işlemin kendi değişikliklerine, sonra önbelleğe, sonra günlüğe, en son dosyaya bakar.

Katalog#

Şemalar, kullanıcılar, havuz ayarları ve dağıtım haritası sürümlü bir belgedir ve catalog.db'de overflow sayfalarından oluşan bir zincirde durur. Başlıktaki kök sayfa bu zinciri gösterir. Katalog değişiklikleri de diğer her şey gibi işlemle yazılır.

Tablolar#

  • Her partition dosyasında bir birincil anahtar ağacı vardır (anahtar → kayıt). Kökü her zaman sayfa 1'dir.
  • Satırın hangi partition'a gideceğini partition anahtarı belirler: (değer − start) / period. Partition tanımlı değilse bütün satırlar p0.db'dedir.
  • İkincil indeksler indexes.db'dedir ve partition'lar arasıdır. Anahtar değer ‖ birincil anahtar, değer satırın partition numarasıdır. Bu sayede benzersizlik bütün partition'larda denetlenir ve indeks araması doğrudan doğru dosyaya gider.
  • Birincil anahtar partition anahtarı değilse, birincil anahtarla arama bütün partition dosyalarına bakar.

Bir kayıt (alan kimliği, uzunluk, değer) üçlülerinden oluşur ve null alanlar yazılmaz. Bu düzenin sonuçları:

  • Silinen alanların baytları okunurken atlanır.
  • Sonradan eklenen alanlar eski kayıtlarda varsayılan değerle görünür.
  • int8 → int64, string → text gibi genişletmeler kayıtları yeniden yazmadan yapılır.

İndeks anahtarları sıra koruyan biçimde kodlanır: bayt sırası değer sırasıyla aynıdır.

Sınırlar ve bilinen eksikler#

  • Her commit diske indirilir (fsync); bu yüzden çok sayıda küçük ifade yavaştır. Toplu commit (group commit) henüz yok.
  • Silinen satırların yaprakları birleştirilmez; boş sayfalar ileride vacuum ile toplanacak.
  • Bir veritabanını aynı anda yalnızca bir süreç açabilir. Kilit unix sistemlerinde flock ile alınır. Windows'ta kilit henüz yazılmadığı için veritabanı açılmaz.
  • Eski sürümlerin tek dosyalı .ndbc'leri açılınca bu yapıya taşınır; eski dosya .v1 uzantısıyla yedek kalır.