Veritabanı sistemlerinde çoklu versiyonlu eşzamanlılık denetimi (MVCC), aynı veriye aynı anda yapılan okuma ve yazma işlemlerini güvenli bir şekilde yönetmenin temel yollarından biri. Ancak NornicDB ekibi, MVCC katmanını geliştirirken beklenmedik bir sorunla karşılaştı: işlemlerin sıralanmasında kullanılan Unix saati, aslında monoton değildi. Bu durum, veri tutarlılığını tehdit eden nadir ancak ciddi hataların kaynağıydı.
MVCC’nin Temelinde Yatan Sorun: Zamanın Doğruluğu
NornicDB, her işlem sonucu için (CommitTimestamp, CommitSequence) adlı bir ikili kullanıyor. CommitTimestamp, time.Now().UnixNano() fonksiyonundan alınan Unix zamanı iken, CommitSequence ise atomik olarak artırılan bir uint64 sayacıydı. MVCC, verilerin versiyonlarını sıralarken ilk olarak CommitSequence değerini kullanıyordu. Ancak bu yaklaşımın arkasındaki nedenler, sistemin performansı ve güvenilirliğiyle doğrudan ilgiliydi.
Ekibin karşılaştığı ilk sorun, duvar saatinin monoton olmamasıydı. Linux sistemlerinde CLOCK_REALTIME temelli saatler, aşağıdaki nedenlerle geriye doğru adımlayabilir:
- NTP düzeltmeleri: Saat, sistem saatini senkronize etmek için saniyenin binde biri kadar yavaşlatılabilir veya hızlandırılabilir.
- Zaman adımları: Saat, sistem saatinden çok uzaklaşırsa aniden ileri veya geriye atabilir.
- Sanal makine senkronizasyonu: Konteyner veya sanal makine ortamlarında, ana bilgisayarın saati değiştikçe konuk sisteminki de anında uyum sağlar.
- Çekirdekten kaynaklanan gecikmeler:
clock_gettimefonksiyonu, farklı çekirdeklerde çalışan iş parçacıkları arasında nanosaniye düzeyinde farklılıklar yaratabilir.
Bu durum, örneğin bir işlem sırasında saat geriye doğru adımladığı için, aslında aynı anda yapılan okuma ve yazma işlemlerinin yanlışlıkla çakışma olarak algılanmasına yol açabiliyordu.
Hızlı Sorgulama Motoru, Saat Çözünürlüğünü Aşındırıyor
NornicDB’nin sorgulama motoru, özellikle basit sorgular için oldukça hızlı çalışıyor. Örneğin, MATCH (n) RETURN n şeklindeki bir sorgunun parse edilmesi ve doğrulanması sadece 39 nanosaniye sürüyor. Bu, saniyede 25 milyon sorgunun tek bir iş parçacığıyla işlenebilmesi anlamına geliyor. Karşılaştırma yapmak gerekirse, ANTLR gibi popüler bir sorgulama motoru aynı iş için 120 kat daha yavaş çalışıyor ve her parse işlemi için bellekte bellek ayırması gerekiyor.
Bu performans avantajı, aslında saat sorununun temel nedenlerinden biriydi. Çünkü sorgulama motorunun hızı, komutların saniyede milyonlarca kez işlenmesine olanak sağlıyor. Bu da, Unix saatinin nanosaniye çözünürlüğünün bile yetersiz kalmasına yol açıyordu. Örneğin, saniyede 1 milyon işlem gerçekleştiğinde, her işlem arasındaki zaman farkı 1 nanosaniyenin altında kalabiliyordu. Bu da, saatlerin aynı anda atanmasına ve dolayısıyla sıralama hatalarına neden olabiliyordu.
Monoton Sayaç: Saatin Yerini Alabilecek Bir Çözüm
NornicDB ekibi, bu sorunu çözmek için atomik olarak artırılan global bir monoton sayaç kullanmaya karar verdi. Bu sayaç, her yeni işlem için verilen bir sıra numarasıydı ve sistemin çalışma süresi boyunca asla azalmıyordu. Bu yaklaşımın avantajları şunlardı:
- Tüm sistem boyunca tekdüze sıra numaraları: Sayaç, sistemdeki tüm işlemler arasında tutarlı bir sıralama sağlıyordu.
- 584 yıllık ömür: Saniyede 1 milyar işlem gerçekleştirildiğinde bile, sayacın taşması için geçmesi gereken süre yaklaşık 584 yıl.
- İşletim sistemi müdahalesine karşı dayanıklılık: Sayaç, sadece sistemdeki işlem sayısına bağlıydı ve dışarıdan yapılacak müdahalelerden etkilenmiyordu.
Bu sayaç, MVCC’nin versiyon sıralamasında kullanılırken, CommitSequence ilk olarak karşılaştırılıyor, ardından CommitTimestamp değerine bakılıyordu. Bu şekilde, saatlerin geriye doğru adımladığı durumlarda bile doğru sıralama sağlanabiliyordu.
Gerçek Dünya Testlerinde Gözlemlenen Hatalar
Ekip, bu değişiklikten önce nadir olarak ortaya çıkan bir hata ile karşılaşmıştı. TestExecuteCypher_SetInvalidatesManagedEmbeddings adlı testte, aslında ikinci bir yazıcı işlemi olmadığı halde, sistem yanlışlıkla bir çakışma algılayarak testi başarısız kılıyordu. Bu durum, sistemdeki saatlerin geriye doğru adımlaması nedeniyle gerçekleşmişti.
Test senaryosu kısaca şöyleydi:
- Birinci işlem, veritabanına bir kayıt ekliyor ve
CommitTimestampolarak1_700_000_000_000_000_100değerini atıyor. - Sistem, birkaç mikro saniye içinde NTP düzeltmesi nedeniyle saati geriye doğru adımlıyor.
- İkinci bir işlem, yeni bir okuma işlemi başlatıyor ve
CommitTimestampolarak1_700_000_000_000_000_050değerini alıyor. - MVCC, ikinci işlemin okuduğu kayıtla ilk işlemdeki kayıt arasında bir çakışma algılıyor, çünkü
1_700_000_000_000_000_100 > 1_700_000_000_000_000_050olarak değerlendiriliyor.
Bu senaryo, aslında hiçbir çakışma olmamasına rağmen sistemin hata vermesine neden oluyordu. Monoton sayaç kullanımı, bu tür hataların önüne geçmeyi sağladı.
MVCC’nin Geleceği: Performans ve Doğruluğun Dengesi
NornicDB’nin bu değişikliği uygulaması, sadece hata sayısını azaltmakla kalmadı, aynı zamanda sistemin genel güvenilirliğini de artırdı. Performans açısından bakıldığında, monoton sayaç kullanımı ek bir maliyet getirmiyor çünkü sayaç, atomik olarak artırılıyor ve bellek üzerinde çok az yer kaplıyor.
Gelecekte, NornicDB’nin MVCC katmanının daha da geliştirilmesi planlanıyor. Bu kapsamda, sorgulama motorunun performansının artırılması ve çoklu düğüm senaryolarında tutarlılığın sağlanması hedefleniyor. Bu sayede, sistemin hem hızlı hem de güvenilir kalması amaçlanıyor.
Sonuç olarak, NornicDB’nin hikayesi, yüksek performanslı sistemlerde saatlerin doğruluğunun sorgulanması gerektiğinin önemli bir örneği. Monoton sayaçlar, bu tür sistemlerde güvenilirliği artırmak için basit ancak etkili bir çözüm sunuyor.
Yapay zeka özeti
NornicDB, MVCC sıralamasını Unix saati yerine monoton sayaç kullanarak nasıl daha güvenilir hale getirdi? Performans ve doğruluk arasındaki hassas dengeyi keşfedin.