Bu kazancın belirli bir maliyeti vardır: işlem modu, bir istekten diğerine istikrarlı bir Postgres bağlantısı varsayan her şeyi sessizce keser. Oturum SET'i, LISTEN/NOTIFY, danışma kilitleri, işlemde hayatta kalan imleçler, hazırlanmış ifadeler olarak adlandırılmıştır. Bu makale mekanizmanın ayrıntılarını verir, bu sınırları kesin belirtileriyle birlikte listeler ve ardından üretimdeki bir arka ucun (bizimki, doğrudan deposunda doğrulanır) onu tuzağa düşmeden nasıl yapılandırdığını gösterir. Burada belirtilen performans rakamlarının ardındaki ölçüm yöntemi için kıyaslama metodolojimizebakın.
Temeller
- İşlem modu: sunucu bağlantısı, istemcinin bağlantısı kesildiğinde değil, her işlemin sonunda kesilir. Bu, kısa REST API türü bağlantıları paylaşmak için en etkili moddur.
- Yapısı gereği aşağıdakilerle uyumlu değildir: oturum SET/RESET, LISTEN/NOTIFY, oturum danışma kilitleri, WHOLD imleçleri, bir istekten diğerine yeniden kullanılan geçici tablolar.
- Uygulamadaki en yaygın tuzak: Birkaç sürücünün (sqlx, asyncpg, JDBC pgjdbc sürücüsü) varsayılan olarak etkinleştirdiği, adlandırılmış hazırlanmış ifadeler, farklı bir sunucu bağlantısında yeniden oynatılabilir ve yük altında
prepared statement does not existgibi bir hatayı tetikleyebilir. - Sürüm 1.21'den bu yana PgBouncer, işlem modunda (sunucu bağlantısı aracılığıyla LRU önbelleği) protokolle hazırlanmış ifadeleri takip edebilir. Bu, uygulamanızın her istekte
search_pathdeğişmesi durumunda istemci tarafı önbelleğinin devre dışı bırakılmasını engellemez. - Aurabase koduyla doğrulandı: kiracı havuzları
statement_cache_capacity(0)vepool_mode=transaction'de PgBouncer ile çalışır, PostgREST ise LISTEN/NOTIFY aracılığıyla şemasının yeniden yüklenmesi için gönüllü olarak doğrudan bağlantıda kalır.
PgBouncer'ın 3 havuzlama modu
PgBouncer, yalnızca Postgres sunucu bağlantısının ortak havuza dönmesi durumunda farklılık gösteren üç mod sunar. Resmi belgelerde bunlara session, transaction ve statement adı verilmektedir (pgbouncer.org/features.html, “Havuzlandırma modları” bölümü, 24 Ağustos 2026'da erişilmiştir).
| Moda | Sunucu bağlantısı gevşek | Oturum uyumluluğu |
|---|---|---|
| oturum (varsayılan) | İstemci bağlantısı kesildiğinde | Toplam: AYARLA, DİNLE, imleçler, her şey canlı gibi çalışıyor |
| işlem | Her işlem sonunda (COMMIT/ROLLBACK) | Kısmi: yalnızca işlemde yerel kalanlar |
| beyan | Her bireysel istekten sonra | Minimal: açık çoklu sorgu işlemleri yasaktır |
Oturum modu, ölçeklenebilirlik açısından en izin veren ancak en az etkili olanıdır: Postgres bağlantısı, iki istek arasında hiçbir şey yapmasa bile, bağlı kaldığı sürece istemci için ayrılmış olarak kalır. İfade modu çok özel durumlar (salt okunur proxy, durum kontrolleri) için ayrılmıştır ve hatta klasik açık işlemleri bile keser. İşlem modu, bir REST API için pratikte hakim olan uzlaşmadır: her HTTP isteği genellikle tek bir kısa Postgres işlemine karşılık gelir.
İşlem modu nasıl çalışır, bağlantıdan bağlantıya
İşlem modunda, PgBouncer yalnızca istemci bir işlem açtığında istemciye bir sunucu bağlantısı ekler ve COMMIT veya ROLLBACK sonrasında onu havuza döndürür. İki işlem arasında aynı istemci kendisini tamamen farklı bir sunucu bağlantısına yeniden atanmış halde bulabilir.
Somut olarak, default_pool_size 20 ile PgBouncer, herhangi bir zamanda yalnızca birkaç işlemi devam eden yüzlerce eşzamanlı müşteriyi absorbe edebilir. Yüksek trafiğe sahip ancak kısa işlemlere sahip bir REST API için işlem modunu haklı çıkaran da bu orandır: nadir kaynak (sunucu tarafında hafızası pahalı olan bir Postgres bağlantısı) yalnızca kesinlikle gerekli olan süre boyunca kullanılır.
Bu son yorum ana fikri özetliyor: işlem modu çalışıyor çünkü "uygulama oturumum" ile "Postgres bağlantım" arasındaki bağlantıyı kasıtlı olarak kesiyor. Bu bağlantıya dayanan her şey bozulur. Bir sonraki bölüm tam olarak ne olduğunu listeliyor.
İşlem havuzu modunda neler bozulur?
Resmi PgBouncer belgeleri, bir sunucu bağlantısı aynı istemciden gelen iki istek arasında geri dönüştürülebildiğinde anlamını yitiren PostgreSQL özelliklerini açıkça listelemektedir.
| Etkilenen işlevsellik | Neden kırılıyor | Tipik semptom |
|---|---|---|
| SET / SET OTURUMU | Ayar, hemen geri dönüştürülebilecek bir bağlantı için geçerlidir. | Bir parametre iki istek arasında rastgele unutulmuş gibi görünüyor |
| DİNLE / BİLDİR | Bildirimleri almak için kalıcı bir bağlantı olduğunu varsayar | Müşteriye hiçbir zaman bildirimde bulunulmaz veya yalnızca aralıklı olarak |
| Oturum danışma kilitleri | Kilit mantıksal istemci tarafından değil sunucu bağlantısı tarafından tutulur | Bir kilit beklenen tamamlanmadan önce açılır veya hiç açılmaz |
| HOLD kaydırıcıları İLE | Onu açan işlemin ötesinde hayatta kalmalı | sonraki yinelemede "imleç mevcut değil" hatası |
| Geçici tablolar | İşlemle değil Postgres oturumuyla ilgili | Bir sonraki sorguda tablo "kayboluyor" |
| Adı geçen açıklamalar hazırlandı | Belirli bir sunucu bağlantısında hazırlandı, başka bir sunucuda yeniden oynatıldı | Yük altında "hazırlanmış ifade ... mevcut değil" |
Bu sınırlamaların çoğu, tek bir bağlantının genellikle tüm trafiğe hizmet verdiği yerel geliştirmede kendini göstermez. Birkaç istemci havuzu paylaştığında ve bir sunucu bağlantısı aynı mantıksal istemciden gelen iki istek arasında gerçekten el değiştirdiğinde, gerçek yük altında görünürler. Bir duman testi bunları neredeyse hiçbir zaman ortaya çıkarmaz.
Hazırlanan ifadeler: En çok yanlış anlaşılan sınır
Çoğu modern Postgres sürücüsü, uygulama kodu açıkça talep etmeden, varsayılan olarak protokol tarafında adlandırılmış istekler hazırlar. Bu tuzağı öngörmeyi zorlaştıran da tam olarak budur.
Protokol tarafından hazırlanan bir ifade, Parsezamanında belirli bir sunucu bağlantısında adlandırılır ve önbelleğe alınır. İşlem modunda, bu bağlantı aynı mantıksal istemciden gelen iki istek arasında başka bir istemciye yeniden atanabilir. Sürücü daha sonra aynı ifade adını hiç hazırlanmadığı bir bağlantıda yeniden oynatırsa Postgres, bir sqlx istemcisi için genellikle prepared statement "sqlx_s_N" does not exist gibi açık bir hatayla yanıt verir. Davranış kesintilidir: her çağrıda tekrarlanabilen deterministik bir hataya değil, bağlantıların yük altında nasıl performans gösterdiğine bağlıdır.
İstemci tarafı düzeltmesi, dile bakılmaksızın aynıdır: işlem modunda bir havuzlayıcıdan geçen herhangi bir havuz için adlandırılmış hazırlanmış ifadelerin önbelleğini devre dışı bırakın veya adsız sorguları zorlayın. Sqlx'li Rust'ta bağlantı seçeneklerinde statement_cache_capacity(0) üzerinden geçer.
Sürüm 1.21'den bu yana PgBouncer, sunucu tarafındaki sorunun bir kısmını hafifletiyor: protokolle hazırlanmış ifadeleri işlem modunda takip edebilir ve bunları, boyutu max_prepared_statementsaracılığıyla ayarlanan bağlantı başına bir LRU önbelleğiyle, atanmış bağlantıda anında hazırlayabilir. Bu, kaçırılanların sayısını azaltır, ancak search_path'nin bir istekten diğerine değiştiği çok kiracılı bir havuzdaki istemci önbelleğini devre dışı bırakmaktan sizi muaf tutmaz: önbelleğe alınmış bir plan, çözümlenen tablonun dahili tanımlayıcısını (OID) Parsezamanında dondurur ve bunu başka bir şema altında yeniden oynatmak, basit bir hata yerine yanlış kiracıdan veri döndürebilir.
Aurabase PgBouncer'ı işlem modunda nasıl yapılandırır?
Aurabase deposu, PgBouncer'ı paylaşılan veri düzleminin (deploy/helm/aurabase/templates/infra/pgbouncer.yaml) önünde pool_mode=transaction olarak ve bir kiracının her ayrılmış Postgres örneğinin (deploy/cnpg/tenant-pooler.yaml) önünde aynı şekilde yapılandırılmış bir Pooler CNPG'yi dağıtır. Her iki yol da yukarıda açıklanan aynı disiplini uygular.
Kaynak kodu, bu seçimin yalnızca kararlılık nedenini değil, belirli bir güvenlik nedenini de belgeliyor. Kiracılar arasında paylaşılan Postgres havuzları, yeniden kullanılan bağlantılarda proje başına farklı bir search_path konumlandırır. Önbelleğe alınmış hazırlanmış bir ifade, çözümlenen tablonun OID'sini Parsezamanında dondurur; aynı bağlantıdaki başka bir kiracı için yeniden oynatmak, sorguyu yalnızca bir uygulama hatası değil, bir izolasyon atlaması olan ilk kiracının şemasına karşı çalıştırır. Bu nedenle statement_cache_capacity(0), işlem modunda bir CNPG Havuzlayıcıdan geçen özel örnekler de dahil olmak üzere istisnasız olarak uygulanır.
İkinci oturum hijyen önlemi: her bağlantı havuza geri döndüğünde, bir kanca DISCARD ALL komutunu çalıştırır (ayarların sıfırlanması, sunucu tarafında hazırlanmış ifadelerin yerinin değiştirilmesi, öneri kilitlerinin serbest bırakılması, imleçlerin ve geçici tabloların temizlenmesi). Bu kanca olmadan, önceki bir isteğin oluşturduğu oturum kalıntısı, aynı geri dönüştürülmüş bağlantıyı yeniden kullanan farklı bir kiracının sonraki isteğinde sızabilir.
İstisna kabul edildi: Özel PostgREST bulut sunucuları, havuzlayıcıdan geçmeden birincil sunucuyla doğrudan bağlantıda kalır. PostgREST şemasının yeniden yüklenmesi, kalıcı bir bağlantıyı, tam olarak işlem modunun bozduğu işlevselliği varsayan LISTEN/NOTIFY'ye dayanır (ayrıntı zaten Aurabase'deki PostgREST uyumluluğu hakkındaki makalemizde belgelenmiştir). İstek başına RLS ayarları açık bir işlem içinde SET LOCAL'ye iletilir; bu, herhangi bir COMMIT'de sunucu bağlantılarını değiştirebilen bir havuzla uyumlu kalmanın tek yoludur (çok kiracılı RLS izolasyonuhakkındaki makalemize bakın).
Uygulamanızı bozmadan işlem modunu etkinleştirin
Doğrudan Postgres bağlantısından işlem modunda PgBouncer'a geçiş yapan tüm arka uçlar için geçerli olan kısa bir kontrol listesi.
- Uygulama kodunu denetleyin. İşlem dışı
SET,LISTEN/NOTIFY, oturum danışma kilitlerini,WITH HOLDimleçlerini ve sorgular arasında yeniden kullanılan geçici tabloları arayın. - Oturum SET'lerini açık bir işlem içindeki YEREL SET'lerle değiştirin. Bu, bağlantı geri dönüşümünden düzgün şekilde kurtulan tek ayardır, çünkü bir sonraki bağlantıda sızıntı yapmak yerine COMMIT/ROLLBACK'te temizlenir.
- Havuzunuz havuzlayıcıdan geçiyorsa ve şema veya rol bir istekten diğerine değişiyorsa, sürücü tarafında hazırlanan ifadeler önbelleğini devre dışı bırakın. Performans maliyeti gerçektir ancak ölçülebilirdir ve kiracılar arasındaki sızıntı riskinden çok daha düşüktür.
- Gerçekten oturum moduna ihtiyaç duyan bağlantıları (geçişler, yönetici komut dosyaları, LISTEN/NOTIFY'ye bağlı olan herhangi bir şey), diğer tüm trafik için işlem modundan vazgeçmek yerine doğrudan havuzlayıcı olmayan bir bağlantıya ayırın.
default_pool_sizevemax_client_connboyutu Postgres'in gerçekmax_connectionsdeğerine göredir, başka bir projeden kopyalanan rastgele bir rakamla değil.- Sadece duman testi değil, gerçek yük altında test yapın. Hazırlanan ifade hataları ve oturum ayarları sızıntıları neredeyse hiçbir zaman tek bir yerel bağlantıda görünmez.
- Üretimdeyken PgBouncer yönetim konsolundan
SHOW POOLSveSHOW STATSizleyin ve havuz doygunluğunu istemci tarafında görünür hale gelmeden önce tespit edin.
Her zaman oturum yerine işlem modunu mu seçmelisiniz?
Hayır, ancak REST API'lerin büyük çoğunluğu için doğru varsayılan seçimdir. Oturum modu, hızlı bir şekilde yeniden düzenleyemeyeceğiniz oturum işlevlerine büyük ölçüde bağımlı olan eski bir uygulama için veya havuz kazancının geçiş çabasını telafi etmediği düşük trafik için tercih edilmeye devam eder.
PgBouncer da bu havuzlama modelinin tek uygulaması değil: Supavisor (Supabase) ve PgCat, yük dağıtımı ve kümeleme konusunda farklı ödünleşimlere sahip iki yeni alternatiftir. Topolojinize bağlı olarak üçü arasında seçim yapmak için ayrıntılı karşılaştırmamıza bakın, PgBouncer vs Supavisor vs PgCat.
SSS
Üretimde işlem modu etkinleştirildiğinde en sık karşılaşılan sorular.