PostgreSQL "could not resize shared memory segment" — Bellek Nerede Bitiyor?
Docker'da /dev/shm 64 MB sınırı, parallel query kaynaklı shared memory hatası, work_mem hesabı ve doğru düzeltme sırası.
Operasyonel Doğrulama & Güvenilirlik Standardı
Hata mesajı semptomdur, kök neden değildir. Sunucuyu yeniden başlatmadan veya rastgele ayar değiştirmeden önce aşağıdaki "Nedeni ayırt eden tek sorgu"yu çalıştırarak gerçek senaryoyu netleştirin.
▸Belirti
ERROR: could not resize shared memory segment "/PostgreSQL.24167" to
1048576 bytes: No space left on deviceMesaj "no space left on device" der ve insanı disk arızalarına yönlendirir. Oysa burada dolan şey disk değil, paylaşımlı bellek (`/dev/shm`). Bu hata özellikle konteyner ortamlarında patlar: Docker varsayılan olarak /dev/shm için 64 MB ayırır ve paralel sorgular bu alanı hızla tüketir.
Hatanın ikinci varyantı:
ERROR: out of memory
DETAIL: Failed on request of size 1048576.Bu ise palloc başarısız olduğunda görülür — yani süreç gerçekten RAM bulamıyordur. İki mesajı karıştırmamak gerekir: birincisi paylaşımlı bellek (/dev/shm), ikincisi süreç sanal belleğidir.
▸Nedeni ayırt eden kontrol
Konteyner içinde şunu çalıştırın:
df -h /dev/shmÇıktı 64M ise tanı kesindir.
▸Adım adım çözüm
1. Konteyner `/dev/shm` payını yükseltin (asıl düzeltme).
docker run --shm-size=1g ...docker-compose.yml karşılığı:
services:
postgres:
image: postgres:17
shm_size: 1gbBu ayar, sorgu planını bozmadan ve performansı düşürmeden sorunu kökten çözer. İlk adım bu olmalıdır.
2. Paralel sorguyu geçici olarak sınırlayın (acil ilk yardım).
SET max_parallel_workers_per_gather = 0;Bu komut hatayı derhal keser ama paralel sorgunun getirdiği hızı kaybedersiniz. Kalıcı çözüm değil, müdahale aracıdır.
3. `work_mem`'i doğru hesaplayın. Buradaki klasik hata, work_mem'i "bağlantı başına bellek" sanmaktır. work_mem operatör başına geçerlidir: 3 sıralama içeren bir sorgu, 3 × work_mem kullanabilir.
uygun work_mem ≈ (RAM − shared_buffers) / (max_connections × 3)Örnek: 32 GB RAM, 8 GB shared_buffers, 200 bağlantı → (32 − 8) / (200 × 3) ≈ 40 MB. Global work_mem'i 256 MB yapmak, 200 bağlantıda teorik 150 GB'lık talep yaratır ve Linux OOM Killer'ı devreye sokar.
4. Raporlama sorguları için oturum bazlı yükseltin. Global ayarı büyütmek yerine oturumda geçici artırın:
SET work_mem = '256MB';
-- ağır rapor sorgusu
RESET work_mem;5. `out of memory` varyantında Linux overcommit kontrolü.
free -m
cat /proc/sys/vm/overcommit_memoryovercommit_memory = 2 (katı mod), PostgreSQL'in bellek taleplerini beklenmedik biçimde reddedebilir.
▸Bunu bir daha yaşamamak için
Konteynerde çalışan her PostgreSQL için /dev/shm boyutunu dağıtım şablonlarınıza (Terraform / Helm / Compose) zorunlu kılın. work_mem'i asla "büyük olsun hızlı olsun" mantığıyla ayarlamayın.
- •İlgili Derin Mimari: PostgreSQL Shared Buffers ve Linux Page Cache
- •İlgili Hata: FATAL: sorry, too many clients already
Diğer Veritabanı Hata Teşhisleri
Kriz anında başvurabileceğiniz diğer doğrulanmış hata rehberleri.
PostgreSQL too many clients already Hatası: 6 Adımda Çözüm
FATAL: sorry, too many clients already hatasının üç nedeni, nedeni ayırt eden tek sorgu ve max_connections ile PgBouncer üzerinden kalıcı çözümü.
PostgreSQL password authentication failed Hatası: Neden ve Çözüm
psql password authentication failed hatasının dört nedeni: yanlış şifre, md5/SCRAM uyuşmazlığı, pg_hba.conf sırası ve yanlış cluster. Adım adım teşhis.
PostgreSQL connection refused: 8 Adımda Kesin Teşhis
Connection refused, timeout ve "no pg_hba.conf entry" arasındaki fark; listen_addresses, port, firewall ve Docker port yayınlama kontrolleri.