Database Engineering

MVCC Derinlemesine: Hayali Okumaları Çözmek

Çok Sürümlü Eşzamanlık Kontrolü (MVCC), modern işlem veritabanlarının omurgasıdır. Okuyucuların yazıcıları engellemesini ve bunun tersini önlemede başarılı olsa da, hayali okumalar ve yazma kayması gibi ince eşzamanlık anomalileri de ortaya çıkar. Yüksek eşzamanlı uygulamalar geliştiren mühendisler için standart SQL izolasyon seviyeleri ile dağıtık uygulamalar arasındaki nüansları anlamak hayati önem taşır. Bu yazıda, PostgreSQL ve CockroachDB'de bu olgular incelenmektedir.

Anomalileri Anlamak

Bir Hayali Okuma (Phantom Read), bir işlemin aralık koşulu içeren bir sorguyu yeniden çalıştırdığında ve başka bir onaylanmış işlem tarafından eklenen satırları bulduğunda gerçekleşir. Tekrarlanabilir olmayan bir okumadan (mevcut bir satırın değiştiği durum) farklı olarak, hayali okuma yeni satırların "hiçbir yerden" ortaya çıkmasını içerir. Yazma Kayması (Write Skew) sıklıkla yanlış anlaşılır. İki işlemin örtüşen satır kümelerini okumasına, bu okumalara dayanarak karar vermesine ve ardından bu satırların ayrık alt kümelerini güncellemesine neden olduğunda ortaya çıkar. Son durum, işlemler sıralanmış olsaydı tespit edilecek olan bir kısıtlamayı ihlal eder. Klasik örnekler arasında aynı günde en fazla iki kişinin çalışabileceği vardiya planlaması veya toplam bakiyenin pozitif kalması gereken hesaplar arası para transferi yer alır.

PostgreSQL: Aralık Kilidi Çözümü

PostgreSQL, Serileştirilebilir Anlık Görüntü İzolasyonu (SSI) uygular. Varsayılan olarak Okunabilir Onaylanmış (Read Committed) modunda çalışır ancak serileştirilebilirlik için güçlü bir yaklaşım sunar. MySQL'in aksine, PostgreSQL aralık kilitleri (indeks aralıkları üzerindeki kilitler) kullanmaz. Bunun yerine, okuma-yazma çakışmalarını tespit eder. İki işlem aynı anahtarı okur ve bunlardan biri aynı kümede farklı bir anahtara yazar ise, PostgreSQL bir serileştirme hatası yükseltir. Bu, uygulamanın işlemi yeniden denemesini zorlar. Bu, gerçek bir "kilit tabanlı" önleme yöntemi olmasa da, ara sıra yeniden deneme maliyeti pahasına serileştirilebilirliği garanti eder.

-- Örnek: PostgreSQL'de serileştirme hatası tespiti
BEGIN;
SELECT count(*) FROM orders WHERE status = 'pending';
-- İşlem A bir satırı günceller
-- İşlem B de okur ve günceller
-- PostgreSQL şunu yükseltebilir: serialization_failure
COMMIT;
Tam serileştirme olmadan hayali okumaları azaltmak için geliştiriciler genellikle SELECT ... FOR UPDATE kullanır; bu, döndürülen belirli satırları kilitler. Ancak, bu koşulla eşleşen gelecekteki satırları kilitlemez, bu da uygulama düzeyinde mantık veya daha yüksek izolasyon seviyeleri ile birleştirilmedikçe hayali okumaların mümkün olmasına neden olur.

CockroachDB: Dağıtık Serileştirme

CockroachDB, güçlü tutarlılık için sıfırdan dağıtık kümeler üzerinde çalışacak şekilde tasarlanmıştır. Varsayılan olarak doğrusallaştırılabilir bir tutarlılık modeli kullanır. Bu, farklı bölgelerdeki okumaların bile en son yazmayı döndürdüğü anlamına gelir. Hayali okumalar ve yazma kayması için CockroachDB, serileştirilebilirliği PostgreSQL'den farklı şekilde yönetir. Olayları sıralamak için hibrit mantıksal bir saat kullanır. Bir işlem, serileştirilebilirliği ihlal eden potansiyel bir anomali tespit ederse, işlemi hemen sonlandırır. PostgreSQL'in commit aşamasında gerçekleşen yeniden deneme mekanizmasının aksine, CockroachDB dağıtık yapısı nedeniyle yürütme sırasında çakışmaları tespit edebilir.

-- CockroachDB serileştirilebilir örnek
BEGIN;
-- Bakiyeyi oku
SELECT balance FROM accounts WHERE id = 1;
-- Hesap 2'ye yaz
UPDATE accounts SET balance = balance - 100 WHERE id = 2;
COMMIT;
-- Başka bir işlem eşzamanlı olarak hesap 1'i değiştirdiyse,
-- CockroachDB bu işlemi yeniden denenebilir bir hata ile sonlandırır.

Pratik Stratejiler

1. Uygulama Yeniden Denemeleri: Her iki veritabanı için de serileştirilebilir işlemleri üstel geri çekilme ile bir yeniden deneme döngüsüne sarmak esastır. 2. İyimser Kilitleme: Çakışmaları erken tespit etmek için sürüm sütunları kullanın. 3. Normalizasyon Dışı (Denormalization): Bazen kısıtlamaları uygulama katmanına taşımak veya matikleştirilmiş görünümler (materialized views) kullanmak kilit rekabetini azaltabilir.

Sonuç

Hayali okumaları ve yazma kaymasını çözmek, bir zihniyet değişikliği gerektirir. Artık sadece SQL yazmıyorsunuz; eşzamanlılık için tasarım yapıyorsunuz. PostgreSQL, SSI ve yeniden denemelerle esneklik sunarken, CockroachDB otomatik çakışma tespiti ile güçlü tutarlılık sağlar. İş mantığınızın gerektirdiği kesin doğruluk ile performans arasında denge kuran izolasyon seviyesini seçin.
Share: