30 puan yazan darjeeling 20 일 전 | 4 yorum | WhatsApp'ta paylaş

ultrathink.art, yapay zeka ajanları tarafından otonom olarak işletilen bir e-ticaret mağazasıdır. Ürün tasarımından sipariş işlemeye, blog yazımına kadar her şeyi yapay zeka üstlenir. Bu yazı, o mağazayı gerçek Stripe ödemelerini de işleyen bir prodüksiyon ortamında SQLite ile çalıştırırken edinilen deneyimleri anlatıyor.


Yapılandırma: 4 dosya, 1 volume

Prodüksiyon ortamında toplam 4 SQLite veritabanı çalıştırılıyor: primary (siparişler·ürünler·kullanıcılar), cache (Rails cache), queue (arka plan işleri), cable (Action Cable). Bunların tamamı tek bir Docker volume içinde saklanıyor.

Rails 8, SQLite'ı birinci sınıf bir seçenek haline getirdi ve bunun karşılığında dağıtımın sadeleşmesi, connection pool yönetimine gerek kalmaması ve ayrı bir DB sunucusu gerektirmemesi gibi avantajlar gerçekten hissedildi.


WAL modunun eşzamanlılığı mümkün kılma mantığı

SQLite'ın varsayılan journal modu, yazma sırasında tüm DB'yi kilitler; bu da eşzamanlı isteğin fazla olduğu web uygulamaları için uygun değildir. WAL (Write-Ahead Logging) modunda ise yazmalar ayrı bir -wal dosyasına eklenir ve okumalar ana dosyayı kullanmaya devam eder; böylece çok sayıda okuma ile tek bir yazma aynı anda mümkün olur. Rails 8, SQLite için WAL modunu varsayılan olarak etkinleştirir.


Olay: 2 sipariş kayboldu

4 Şubat'ta, 2 saat içinde main'e 11 commit pushlandı. Her push ile Kamal'ın blue-green dağıtımı çalıştı ve eski container ile yeni container'ın aynı WAL dosyasını aynı anda açtığı bir çakışma aralığı oluştu. 11 dağıtım üst üste binerken, A container'ı draining durumundayken B başladı; B tamamen hazır olmadan C'nin dağıtımı da başladı.

16 ve 17 numaralı siparişlerin Stripe ödemeleri başarılı oldu ve müşterilerin hesaplarından para da çekildi, ancak DB'de hiçbir kayıt kalmadı. sqlite_sequence ile kontrol edildiğinde auto-increment sayacı 17'yi gösteriyordu ama gerçekte yalnızca 15 satır vardı.


Çözüm: dağıtım hızını yavaşlatın

Çözüm teknik değil, prosedüreldi. İlgili değişiklikleri gruplayarak dağıtmak ve peş peşe hızlı push'lardan kaçınmak kuralı, yapay zeka ajanlarının uyması için bir yönetişim dosyası olan CLAUDE.md içine açıkça yazıldı.

Bu, SQLite'ın değil dağıtım pipeline'ının problemidir. PostgreSQL, TCP socket üzerinden bağlandığı için yeni container'lar da aynı DB sunucusuna bağlanır ve yazma sırasını DB engine yönetir. SQLite ise paylaşılan Docker volume üzerindeki dosya sistemi kilitlerine dayanır; container'lar çakıştığında bu bozulur.


sqlite_sequence: adli analiz aracı olarak kullanmak

sqlite_sequence tablosu, SQLite içindeki en az değer verilen debug araçlarından biridir. Daha sonra silinmiş satırlar olsa bile, geçmişte atanan en yüksek auto-increment değerini hatırlar. Mevcut satır sayısı ile sequence değeri beklenmedik şekilde açılıyorsa, bu bir yerde satırların yanlış silindiğine dair işarettir.


Kimsenin anlatmadığı tuzaklar

PostgreSQL geliştiricilerinin alışkanlıkla kullandığı ILIKE, SQLite'ta syntax error üretir. Bunun yerine LOWER(name) LIKE kullanılmalıdır. json_extract, değer sayısal olarak saklandıysa integer döndürür ve string karşılaştırmalarında sessizce başarısız olur. kamal app exec, her seferinde yeni bir container oluşturur; 2GB RAM'li bir sunucuda bunu aynı anda iki kez çalıştırırsanız OOM killer web sürecini öldürür.


Yeniden seçim yapsam yine SQLite kullanır mıydım?

Evet. Tek sunucuda makul yazma yükleri için SQLite, altyapı karmaşıklığını baştan sona ortadan kaldırır. Yedekleme için de yalnızca sqlite3 .backup komutu yeterlidir (WAL modu ve eşzamanlı yazmaları güvenle ele alır). Günün birinde yatay ölçekleme ya da gerçek çoklu writer eşzamanlılığı gerekirse, o zaman PostgreSQL'e migration yapılabilir. Rails bu geçişi kolaylaştırıyor.


Orijinal kaynak: ultrathink.art Blog, 2026.04.03

4 yorum

 
click 18 일 전

Altyapı karmaşıklığı sorunu ne kadar olsa da, e-ticaret sitesi gibi eşzamanlı yazmanın çok gerekli olduğu yerlerde en baştan sqlite kullanmamak daha iyi bir tercih olmaz mı?
Üstelik Docker ile kurulmuş bir yapıysa postgresql kurulumunun altyapı karmaşıklığı da o kadar yüksek olmazdı diye düşünüyorum.
rails ile yapıldığı için ekosistemin sqlite kullanan tarafa çerçevelenmiş olması ve bunun iyi bir seçenekmiş gibi yönlendirilmiş olduğu izlenimine kapılıyorum.
Sipariş kaybı gibi ciddi bir hata yaşanmışken, pg gibi eşzamanlı yazma sorunları olmayan bir veritabanı kullanmak yerine, e-ticaret sitesi gibi eşzamanlı yazmanın çok gerekli olduğu bir yerde en baştan sqlite kullanmamak daha iyi bir tercih olmaz mı?
rails ile yapıldığı için ekosistemin sqlite kullanan tarafa çerçevelenmiş olması ve bunun iyi bir seçenekmiş gibi yönlendirilmiş olduğu düşüncesine kapılıyorum.
Sipariş kaybı gibi ciddi bir hata meydana gelmiş ve bunun kökten çözümü pg gibi eşzamanlı yazma için uygun bir veritabanı kullanmakken,
teknik olarak sqlite tercih ediliyor diye bunu kullanmaya devam edeceğini savunmak bana bir mühendis olarak güven veren bir söylem gibi gelmiyor.
İhtiyaç yokken k8s kurup replica 1 olan bir HPA yapılandırması yapmak ve gayet iyi çalışan bir monoliti MSA'ya çevirmek şeklindeki CV odaklı geliştirmenin ters versiyonu gibi hissettiriyor.

 
okxrr 18 일 전

Sorun, konteyneri ayağa kaldırırken volume ayarının yanlış yapılması; eşzamanlı yazmanın desteklenmemesi değil. Yazıyı tekrar okursanız, eşzamanlı yazma sorununun busy timeout ile yeterince karşılandığı belirtiliyor. Volume ayarı ise
ipc=host ile çözülebilir.

Postgres sonuçta işletilmek zorunda; SQLite ise uygulama ikilisini nereye olursa olsun dağıtmanızla çalışır.

Sayısız işletim deneyimi ve başarısızlık biriktikçe SQLite popülerleşmeye başlıyor;
eşzamanlı yazmanın da yazıda açıkça söylendiği gibi hiç sorun olmadığı belirtiliyor.

 
darjeeling 18 일 전

Aslında sadece çeşitli ayarlar yapmak yetiyor ama sonuçta deneyim gerekiyor, haha. Neyse, ben böyle yazıları seviyorum.

 
darjeeling 18 일 전

Evet, aynen öyle; bu yüzden de böyle yazıların ara sıra paylaşılması daha da güzel olur.