Ulaşım
- Adres:Batıkent Mh. 8910 Sk. 6. Etap 1H No: 18 Yeni Toki Eyyübiye / Şanlıurfa (Yeni Alım Satım Karşısı)
- Telefon:0 (545) 528 88 93
- eMail: info@alestaweb.com
PostgreSQL veritabanınızda "The connection pool has been exhausted" veya "FATAL: sorry, too many clients already" hatası mı alıyorsunuz? Alesta Web olarak bu rehberde connection pool sorunlarını nasıl teşhis edip çözeceğinizi (how to fix) adım adım anlatacağız. Production ortamlarında bu hata kritik olabilir!
Veritabanı bağlantısı oluşturmak pahalı bir işlemdir. Her istek için yeni bağlantı açmak yerine, önceden oluşturulmuş bağlantıları havuzda tutup yeniden kullanmak çok daha verimlidir. İşte bu mekanizmaya Connection Pooling denir.
Alesta Web olarak yüksek trafikli projelerde connection pool yönetiminin ne kadar kritik olduğunu biliyoruz. Yanlış yapılandırma, uygulamanızı tamamen çökertebilir!
# Npgsql (C#/.NET)
NpgsqlException: The connection pool has been exhausted,
either raise 'Max Pool Size' (currently 100) or 'Timeout' (currently 15 seconds)
# PostgreSQL Native
FATAL: sorry, too many clients already
# Connection Timeout
Exception: Timeout expired. The timeout period elapsed prior to obtaining
a connection from the pool.
PostgreSQL varsayılan olarak maksimum 100 bağlantıya izin verir (max_connections). Her backend process bellek tüketir, bu yüzden sınırsız bağlantı açamazsınız.
Alesta Web deneyimlerimize göre connection pool exhausted hatasının başlıca nedenleri:
// C# - Bağlantı kapatılmamış!
public void GetData()
{
var conn = new NpgsqlConnection(connectionString);
conn.Open();
var cmd = new NpgsqlCommand("SELECT * FROM users", conn);
var reader = cmd.ExecuteReader();
// ... işlemler
// ❌ conn.Close() veya using yok - LEAK!
}
// Python - Bağlantı kapatılmamış!
def get_data():
conn = psycopg2.connect(DATABASE_URL)
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
# ❌ conn.close() yok - LEAK!
return cursor.fetchall()
Yavaş sorgular bağlantıyı uzun süre meşgul tutar ve havuz tükenir.
Trafik artarken pool size sabit kalırsa, bağlantı açılamaz.
Çok kısa timeout değerleri, yoğun anlarda hatalara neden olur.
Kullanılmayan bağlantılar havuzda yer kaplar ve diğer istekleri bloklar.
Connection leak production ortamında en tehlikeli sorunlardan biridir. Başlangıçta fark edilmez, ancak zamanla bağlantılar tükenir ve uygulama çöker!
Alesta Web olarak sorunun kaynağını bulmak için şu adımları izliyoruz:
-- Toplam aktif bağlantı sayısı
SELECT count(*) FROM pg_stat_activity;
-- Veritabanına göre bağlantılar
SELECT datname, count(*)
FROM pg_stat_activity
GROUP BY datname
ORDER BY count(*) DESC;
-- State'e göre bağlantılar
SELECT state, count(*)
FROM pg_stat_activity
GROUP BY state;
-- Detaylı bağlantı bilgisi
SELECT
pid,
usename,
application_name,
client_addr,
state,
query_start,
NOW() - query_start AS query_duration,
LEFT(query, 50) AS query_preview
FROM pg_stat_activity
WHERE state != 'idle'
ORDER BY query_start;
-- max_connections değeri
SHOW max_connections;
-- Tüm connection ayarları
SELECT name, setting, unit, context
FROM pg_settings
WHERE name LIKE '%connection%'
OR name LIKE '%pool%';
-- Kalan bağlantı kapasitesi
SELECT
max_conn.setting::int AS max_connections,
used_conn.count AS current_connections,
max_conn.setting::int - used_conn.count AS available
FROM
(SELECT setting FROM pg_settings WHERE name = 'max_connections') max_conn,
(SELECT count(*) FROM pg_stat_activity) used_conn;
-- 30 saniyeden uzun süren sorgular
SELECT
pid,
NOW() - query_start AS duration,
query,
state
FROM pg_stat_activity
WHERE (NOW() - query_start) > INTERVAL '30 seconds'
AND state != 'idle';
-- Blocking sorgular
SELECT
blocked.pid AS blocked_pid,
blocked.query AS blocked_query,
blocking.pid AS blocking_pid,
blocking.query AS blocking_query
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_stat_activity blocked ON blocked.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks
ON blocking_locks.locktype = blocked_locks.locktype
AND blocking_locks.relation = blocked_locks.relation
JOIN pg_stat_activity blocking ON blocking.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted
AND blocked_locks.pid != blocking_locks.pid;
// C# - Using statement ile otomatik dispose
public async Task<List<User>> GetUsersAsync()
{
await using var conn = new NpgsqlConnection(connectionString);
await conn.OpenAsync();
await using var cmd = new NpgsqlCommand("SELECT * FROM users", conn);
await using var reader = await cmd.ExecuteReaderAsync();
var users = new List<User>();
while (await reader.ReadAsync())
{
users.Add(new User { Id = reader.GetInt32(0) });
}
return users;
} // ✅ Otomatik olarak kapatılır
# Python - Context manager ile
def get_users():
with psycopg2.connect(DATABASE_URL) as conn:
with conn.cursor() as cursor:
cursor.execute("SELECT * FROM users")
return cursor.fetchall()
# ✅ Otomatik olarak kapatılır
# Node.js - Pool ile
const { Pool } = require('pg');
const pool = new Pool({ max: 20 });
async function getUsers() {
const client = await pool.connect();
try {
const result = await client.query('SELECT * FROM users');
return result.rows;
} finally {
client.release(); // ✅ Pool'a geri ver
}
}
# /etc/postgresql/15/main/postgresql.conf
# Varsayılan: 100
max_connections = 200
# Shared buffers da artırılmalı (bağlantı başına ~1MB)
shared_buffers = 512MB
# Restart gerekli
sudo systemctl restart postgresql
# Veya reload ile (bazı ayarlar için)
SELECT pg_reload_conf();
max_connections artırmak kısa vadeli çözümdür. Her bağlantı bellek tüketir. 500+ bağlantı için mutlaka connection pooler (PgBouncer) kullanın!
# C# / Npgsql
Host=localhost;Database=mydb;Username=user;Password=pass;
Maximum Pool Size=100;Minimum Pool Size=10;Connection Idle Lifetime=300;
Connection Pruning Interval=10;Timeout=30
# Node.js / pg
const pool = new Pool({
host: 'localhost',
database: 'mydb',
max: 20, // Maximum pool size
idleTimeoutMillis: 30000, // Idle timeout
connectionTimeoutMillis: 5000 // Connection timeout
});
# Python / SQLAlchemy
engine = create_engine(
'postgresql://user:pass@localhost/mydb',
pool_size=20,
max_overflow=10,
pool_timeout=30,
pool_recycle=1800
)
-- 10 dakikadan uzun idle bağlantıları sonlandır
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
AND query_start < NOW() - INTERVAL '10 minutes'
AND pid != pg_backend_pid();
-- Otomatik temizlik için postgresql.conf
idle_in_transaction_session_timeout = '5min'
idle_session_timeout = '10min' -- PostgreSQL 14+
Yüksek trafikli uygulamalar için PgBouncer veya PgPool-II kullanmanızı şiddetle tavsiye ediyoruz. Alesta Web olarak tüm production projelerimizde PgBouncer kullanıyoruz.
# Kurulum
sudo apt update
sudo apt install pgbouncer
# Konfigürasyon dosyası
sudo nano /etc/pgbouncer/pgbouncer.ini
[databases]
mydb = host=127.0.0.1 port=5432 dbname=mydb
[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
# Pool mode: session, transaction, statement
pool_mode = transaction
# Pool ayarları
default_pool_size = 20
max_client_conn = 1000
max_db_connections = 50
# Timeouts
server_idle_timeout = 600
query_timeout = 120
# Logging
log_connections = 1
log_disconnections = 1
# Kullanıcı hash'i oluştur
psql -U postgres -c "SELECT concat('\"', usename, '\" \"', passwd, '\"') FROM pg_shadow;"
# /etc/pgbouncer/userlist.txt
"myuser" "md5hashburaya"
# Servisi başlat
sudo systemctl enable pgbouncer
sudo systemctl start pgbouncer
# Uygulama artık 6432 portuna bağlanacak
postgresql://myuser:pass@localhost:6432/mydb
Alesta Web olarak PostgreSQL bağlantı yönetimi için şu kurallara uyuyoruz:
-- Her 5 dakikada çalıştır
SELECT
NOW() AS check_time,
(SELECT count(*) FROM pg_stat_activity) AS total_connections,
(SELECT count(*) FROM pg_stat_activity WHERE state = 'active') AS active,
(SELECT count(*) FROM pg_stat_activity WHERE state = 'idle') AS idle,
(SELECT count(*) FROM pg_stat_activity
WHERE state = 'idle in transaction') AS idle_in_tx,
(SELECT setting::int FROM pg_settings
WHERE name = 'max_connections') AS max_conn;
Alesta Web olarak tüm çözümleri production ortamlarında test ettik.
Artık PostgreSQL connection pool exhausted hatası (bağlantı havuzu tükendi) sizin için sorun olmaktan çıktı! Alesta Web olarak PgBouncer kurulumu ve doğru pool yönetimi ile veritabanı performansınızı maksimize edebilirsiniz.
Hızlı Özet / Quick Summary:
Faydalı Linkler / Useful Links:
© 2026 AlestaWeb - Tüm hakları saklıdır.