Aurora RDS'de bir race condition keşfedilme vakası
(hightouch.com)- AWS Aurora RDS'de ortaya çıkan race condition bug'ı deneysel olarak doğrulandı ve AWS'den nedenine ilişkin teyit alındı
- Hightouch, olay işleme sistemini ölçeklerken Aurora'nın failover (yük devretme) sürecinde yazma instance'ı geçişinin başarısız olduğunu fark etti
- Log analizi sonucunda, iki instance'ın aynı anda yazma işlemi yaptığı ve bunun depolama katmanında çakışma ile süreç sonlanmasına yol açtığı doğrulandı
- AWS, iç sinyal işleme sorunu nedeniyle önceki writer'ın düşürülmesi tamamlanmadan yeni writer'ın terfi ettirildiğini resmi olarak doğruladı
- Bu vaka, büyük ölçekli dağıtık sistemlerde eşzamanlılık kontrolünün önemini ve failover sırasında yazmayı durdurma prosedürünün gerekliliğini vurguluyor
Arka plan
- 20 Ekim 2025'te AWS
us-east-1bölgesinde, DNS yönetim sistemindeki bir race condition bug'ı nedeniyle kesinti yaşandı - Hightouch bu nedenle olay işleme backlog'unun hızla arttığını ve sistem sınırına ulaştığını gördü
- İş hacmini karşılamak için 23 Ekim'de Aurora RDS instance yükseltmesi gerçekleştirildi ve bu süreçte yeni bir race condition bug'ı keşfedildi
Hightouch olay sistemi mimarisi
- Olay toplama ve iletiminden sorumlu sistem Kubernetes, Kafka ve Postgres(Aurora) bileşenlerinden oluşuyor
- Postgres, batch metadata queue olarak kullanılıyor ve saniyede 500 bin olayı 1 saniye içinde işliyor
- Aurora PostgreSQL, yalnızca yazma yapan (primary) instance, salt okunur (replica) instance ve paylaşımlı depolama katmanından oluşuyor
Yükseltme planı
- Okuma instance'ı ekleme → mevcut reader'ı yükseltip failover önceliği verme → failover çalıştırma → mevcut writer'ı yükseltme → geçici reader'ı kaldırma
- Bu prosedür AWS belgelerinde belirtilen yöntemdi ve staging ortamında yük testiyle doğrulanmış bir prosedürdü
Yükseltme denemesi ve sorunun ortaya çıkışı
- 23 Ekim 16:39 EDT'de failover çalıştırıldıktan sonra mevcut writer'ın yeniden primary olarak geri dönmesi olayı yaşandı
- İki denemede de aynı sonuç görüldü ve bazı servislerde yazılamama hatası (
DatabaseError: cannot execute UPDATE in a read-only transaction) oluştu - Log analizi, iki instance'ın aynı anda yazma işlemi yaparken depolama çakışması nedeniyle sonlandığını gösteren kayıtları ortaya koydu
Race condition'ın nedeni
- Aurora'nın failover sürecindeki 3. adım (mevcut writer'ın düşürülmesi) ile 4. adım (yeni writer'ın terfi ettirilmesi) arasında race condition oluştu
- Bunun sonucunda iki instance aynı anda yazma yetkisine sahip oldu ve çakışma yaşandı
- Yazma trafiği kaldırılmış halde yeniden denendiğinde failover normal şekilde tamamlandı ve race condition hipotezi doğrulandı
AWS'nin doğrulaması ve yanıtı
- AWS, iç inceleme sonrasında nedenin writer düşürme sinyalinin işlenmesindeki hata olduğunu ve bunun Hightouch'un yapılandırması veya trafik deseniyle ilgili olmadığını doğruladı
- Düzeltmenin yol haritasına alındığı ve geçici önlem olarak failover sırasında yazmanın durdurulmasının önerildiği belirtildi
Nihai önlemler
- Hightouch küme yükseltmesini tamamladı ve
- kasıtlı failover öncesi yazmayı durdurma prosedürü ekledi
- writer rolü değişimini izleyen gözlemlemeyi güçlendirdi
- operasyon kılavuzunu (playbook) güncelledi
Başlıca dersler
- Migrasyon sırasında beklenmedik durum geçişlerine karşı kurtarma hazırlığı gerekli
- Gözlemlenebilirlik (observability), sorun tespitinin anahtarı
- Dağıtık sistem bileşenleri arasındaki etkinin en aza indirildiği tasarımın önemi büyük
- Test ortamı ile gerçek üretim ortamı arasındaki farkın farkında olunmalı
Orijinal metinde ek bilgi yok
1 yorum
Hacker News yorumu
Bu yazıya bakınca, uygulama manuel failover sırasında da normalde olduğu gibi yazma trafiğini sürdürmeye çalışırsa her zaman başarısız olacakmış gibi görünüyor
Ama aklıma birkaç soru geliyor. Diğer Aurora kullanıcıları neden bu sorunu sürekli yaşamıyor, AWS’nin bundan habersiz olması mümkün mü, biliyorsa neden bunu P0 seviyesinde acil bir sorun olarak ele almıyor merak ediyorum
Belki de işin içinde devam eden transaction durumu veya timeout gibi ince koşullar vardır
SELECT ... FOR UPDATEifadesinin sessizce başarısız olduğu ve transaction’ın autocommit moduna geçtiği bir bug yaşamıştım. Kimse ilgilenmediği için tek başıma konuşup durmuştum, birkaç ay sonra başka biri de aynı sorunu yaşadığını söyleyerek bana ulaştı. Sonunda düzeltildi ama ben çoktan ilgiyi kaybetmiştimİlgili bağlantı: Stack Overflow sorusu
Aurora PostgreSQL’de birkaç kez beklenmedik davranışlar gördüm
Özellikle Zero Downtime Patching (ZDP) sırasında session durumunun yanlış korunması yüzünden, basit sorgular bile
statement_timeoutsüresinden çok daha erken iptal oluyorduBenim tahminim, istemci yeniden bağlandığında Aurora’nın önceki session’ın eski timer durumunu aynen devraldığı ve sorgunun bu yüzden hemen iptal edildiği yönünde
Biz de yazma trafiğinin çok yüksek olduğu bir ortamda düzenli olarak failover yapıyoruz ama AWS JDBC wrapper kullanarak bunu otomatik bir süreçle istikrarlı biçimde işletiyoruz
Aurora’nın bu kadar temel bir invariant’ı koruyacağına güvenip para ödüyorsunuz; buna rağmen böyle bir sorun çıkması şaşırtıcı
Log’lara ve AWS’nin açıklamasına bakınca, orijinal yazının yazarının hipotezi yanlış gibi görünüyor
Promotion başarısız olduktan sonra harici bir gözetim süreci cluster durumundaki tutarsızlığı algılayıp zorla sonlandırma (
kill -9) yapmış gibi görünüyor. Storage alt sistemiyle ilgili mesajlar da bundan sonra ortaya çıkmışAurora ile RDS Postgres’in performans karşılaştırmasını sormak istiyorum.
Multi-AZ ya da hızlı failover gerekmiyorsa, RDS üzerinde gp3 64k IOPS yapılandırmasıyla daha iyi performans almak mümkün mü? Aurora özellikle insert performansında yavaş ve maliyeti yüksek görünüyor. Benchmark’lar da RDS ayarlarını açıkça belirtmediği için güven vermiyor
Ayrıca IOPS’u doğrudan provision etmek gerekmiyor ve yaklaşık 80k IOPS sağlıyor.
I/O ücretlendirmesinde de iki model var; pay-per-IO düşük yük ortamları için, sabit ücret modu ise IO’su yüksek iş yükleri için daha avantajlı.
Bu arada Serverless neredeyse her zaman ekonomik değildi. Yalnızca kısa süreli zirve yükleri varsa işe yarıyor
AWS mühendislerinin sözünü ettiği “lego blok modeli” burada net biçimde görülüyor
Storage katmanını tamamen bağımsız tasarladıkları için, üst servisler başarısız olsa bile veri tutarlılığı korunmuş. Bence bu AWS mühendisliğinin iyi bir örneği
AWS’nin “failover sırasında yazmayı durdurun” tavsiyesinde bulunduğu söyleniyor; ilgili vaka numarasını paylaşmanız mümkün mü merak ediyorum
Bunu yaşayan tek kişinin ben olmadığını görmek sevindirici
Aurora’nın compute-storage ayrımı mimarisi ilginç
MSSQL’deki Hyperscale de benzer bir yapıya sahip ve Azure servisleri içinde gerçekten kullanmaya değer bulduğum neredeyse tek ürün bu