deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak dev.to (home feed)

SQLite 3.53 bayat expression index'leri satır satır onarıyor — ve yalnızca yazdığınız satırları

dev.to üzerindeki testler, SQLite 3.53'ün kendi kendini onarma mekanizmasının bayat expression index girdilerini yalnızca bir satıra yazım yapıldığında onardığını gösteriyor; dokunulmayan satırlar, REINDEX EXPRESSIONS çalıştırılana kadar yanlış sonuçlar dönmeye devam ediyor.

SQLite 3.53 bayat expression index'leri satır satır onarıyor — ve yalnızca yazdığınız satırları

Expression index'ler nasıl bayatlar

SQLite, düz bir sütun yerine bir ifadenin sonucunu indeksleyebilir; örneğin CREATE INDEX ... ON docs(lower(email)) gibi. Index hesaplanan değerleri sakladığı için, yalnızca ifade aynı girdi için her zaman aynı çıktıyı ürettiği sürece doğru kalır. Bu varsayım, özel bir SQL fonksiyonunda hata düzeltmesi yapıldığında, bir bağımlılık davranış değiştirdiğinde ya da SQLite'ın kendi belgelerinde yer verdiği bir örnekte olduğu gibi, motor sürümleri arasında kayan nokta dönüşümünün son basamakta bir birim kayması durumunda bozulur. Satırlar sağlamdır; index girdileri yalnızca onları doğru biçimde tanımlamayı bırakır ve index üzerinden yanıtlanan sorgular hiçbir uyarı olmadan yanlış sonuçlar döndürebilir.

Hatanın yeniden oluşturulması

dev.to üzerinde yayımlanan uygulamalı bir deney, Nisan 2026'da yayımlanan SQLite 3.53.0 ile gelen kendi kendini onarma mekanizmasının gerçekte ne kadar ileri gittiğini ölçmeyi amaçladı. Yazar, floor(x100) dönen deterministik bir skaler fonksiyon olan classify(x)'i kaydetti, classify(x) üzerinde expression index'li 1.000 satırlık bir tablo oluşturdu, sonra aynı veritabanı dosyasını floor(x100)+1 dönen düzeltilmiş bir varyantla yeniden açtı — bu, kimsenin bir index yeniden oluşturma işlemiyle eşleştirmediği bir kod değişikliğini temsil ediyordu. Resmî amalgamation'dan derlenen iki build, sürümü tek değişken olarak yalıttı: kendi kendini onarmadan önce gelen 3.51.0 ve 3.53.4.

3.51.0'da sapma anında görüldü. Index üzerinden classify(x)=500 istendiğinde 309 numaralı satır dönerken, aynı verinin tam taraması 308 numaralı satırı döndürdü — iki farklı yanıt, hiçbir hata verilmedi. O build üzerinde etkilenen satırları güncelleme denemeleri, veritabanının başka hiçbir yerinde hasar olmamasına rağmen SQLITE_CORRUPT ve "database disk image is malformed" iletisiyle başarısız oldu. dev.to yazısına göre bu, 3.53'ten önceki tüm SQLite sürümlerinin davranışı.

Kendi kendini onarma neyi kapsıyor, neyi kapsamıyor

3.53.4'te tablo karışık. Herhangi bir yazım yapılmadan önce okuma sorgusu hâlâ yanlış satırı döndürdü, çünkü kendi kendini onarma yazma ifadeleriyle tetiklenir, okumalarla değil. 300 ile 320 arasındaki satırlara dokunan bir güncellemeden sonra — bu aralık hem 308'i hem 309'u içeriyor — ifade sorunsuz tamamlandı ve index'li ile tam tarama yolları artık 308 numaralı satırda hemfikirdi.

Ancak onarımın kapsamı, tam olarak yazımın dokunduğu satırlardır. Bir bütünlük denetimi, güncellemeden önce 1.000 bayat girdi, sonrasında ise 979 bayat girdi saydı. Dokunulmayan satırlar aynı kadar yanlış kalmaya devam etti ve bayat index'ten hiçbir şikâyet olmadan sunulmaya devam etti; bu da salt okunur ağırlıklı bir tablonun 3.53 üzerinde süresiz biçimde, hatasız ve hiçbir yazımın düzeltmeyi zorlamadığı şekilde yanlış yanıtlar döndürebileceği anlamına geliyor.

REINDEX EXPRESSIONS eksiksiz çözümdür

Yine 3.53 ile gelen REINDEX EXPRESSIONS, sıradan sütun index'lerine dokunmadan expression index'lerini yeniden oluşturur. 3.51.0'da ifade, anahtar bir nesne adı olarak okunduğu için "unable to identify the object to be reindexed" hatasıyla başarısız olur; 3.53.4'te ise kalan 979 satırın tamamını anında onardı.

Hedeflenen kapsam, bakım pencereleri açısından önemlidir. Dört index'li — biri expression tabanlı, üçü geleneksel — 500.000 satırlık bir tabloda deney, REINDEX EXPRESSIONS'u 0,198 saniyede, tablonun tamamına yapılacak REINDEX'e kıyasla 0,990 saniyede ölçtü; bu, kabaca beş kat daha hızlı ve dört yerine tek bir index'i yeniden oluşturmakla tutarlı.

Yük ve eşzamanlılık

Onarım, ölçülebilir bir yazım maliyeti getiriyor. 200.000 satır üzerinde özdeş güncellemeler, index zaten tutarlıyken 0,164 saniye, her satırın onarım gerektirdiği durumda ise 0,239 saniye sürdü — yaklaşık yüzde 46 daha yavaş, ya da satır başına kabaca 0,4 mikrosaniye. Bu maliyet, altta yatan fonksiyon değiştikten sonra satır başına bir kez ödenir ve satır sonrasında temiz kalır.

Busy timeout olmadan çakışan güncellemeler yapan beş bağlantıyla yapılan bir eşzamanlılık testi, üç SQLITE_BUSY başarısızlığı ve iki başarı üretti; yazar bunu, kendi kendini onarmanın getirdiği yeni bir şeye değil, SQLite'ın sıradan tek yazıcı kilidine bağlıyor.

Neden önemli

Bayat bir expression index sessiz bir doğruluk hatasıdır: veri sağlamdır, sorgular başarılıdır ve yanıtlar yanlıştır. Özel bir fonksiyonu SQLITE_DETERMINISTIC olarak işaretlemek motora, saklanan index girdilerini yeniden hesaplamadan güvenebileceğini söyler; dolayısıyla normal sorgu yolundaki hiçbir şey bu sapmayı işaretlemeyecektir. Sürüm 3.53 en alarm verici belirtiyi — rutin güncellemelerin bozulma hatalarıyla başarısız olmasını — ortadan kaldırıyor, ama yoğun okuma yapılan tabloları güvenli kılmıyor, çünkü hiç yazılmayan satırlar hiç onarılmıyor. Geliştiriciler için pratik kural açık: bir expression index içinde kullanılan bir fonksiyon her değiştiğinde ya da kayan nokta davranışını değiştirebilecek bir SQLite yükseltmesinden sonra, kendi kendini onarmanın yetişmesini beklemek yerine REINDEX EXPRESSIONS çalıştırın. Büyük tablolarda hızlıdır, hedeflidir ve her girdinin ifadenin bugün hesapladığı şeyle eşleştiğini doğrulamanın tek yoludur.

  • #sqlite
  • #databases
  • #data-integrity
  • #sql
  • #indexing