Sessizce Bekleyen Tehlike: Her Şey Yolunda Görünürken...
Sistem yöneticileri için felaket kurtarma (Disaster Recovery – DR) testleri genellikle rutin ve tahmin edilebilir süreçlerdir. En azından öyle sanıyor olabilirsiniz. Üretim (production) ortamınızın yedeğini aldınız, test sunucunuza aktardınız. Base backup sorunsuz şekilde açıldı, her şey yolunda gözüküyor. Sıra, yedek alındıktan sonraki işlemleri veritabanına işleyecek olan WAL (Write-Ahead Log) dosyalarının uygulanmasına (replay) geldi.
Logları izliyorsunuz; WAL dosyaları birer birer arşivden çekiliyor, işleniyor… Derken aniden her şey duruyor.
Başta bunun büyük transaction (işlem) bloğu olduğunu ve sistemin onu diske yazmakla meşgul olduğunu düşünebilirsiniz. Beş dakika geçer, on dakika geçer, yarım saat olur… Sunucunun kaynak kullanımına bakarsınız; işlemci (CPU) rahat, disk I/O neredeyse sıfır. Ancak kurtarma (restore) süreci bitmez, veritabanı bir türlü ayağa kalkıp “sistemi kullanıma açtım” mesajını (database system is ready to accept connections) vermez. İşlenmeyi bekleyen gigabaytlarca WAL dosyası kapıda bekler, ama içeride kimse onlara dokunmuyordur. İşin en sinir bozucu tarafı ise hata loglarının (error log) tertemiz olmasıdır. Hiçbir çökme, hiçbir hata mesajı yoktur; sadece sessizlik ve donup kalmış startup (başlatma) süreci vardır.

Asıl Sorun Kendisi: MultiXactOffsetSLRU
Madem loglar size bir şey söylemiyor, o halde işletim sistemi seviyesine inelim. Askıda kalan PostgreSQL startup sürecinin (PID) neyi beklediğini incelediğinizde şu manzarayla karşılaşabilirsiniz: Süreç bir futex_wait (işletim sistemi seviyesinde kilit bekleme) durumuna düşmüştür. PostgreSQL’in kendi iç izleme araçlarıyla (veya hot standby açıksa pg_stat_activity üzerinden) baktığınızda, takılı kaldığı bekleme olayını (wait event) görürsünüz:
LWLock: MultiXactOffsetSLRU
Sistem, MultiXact işlemi için kilit talep etmiş ama bu kilit sonsuz döngüde kilitlenip kalmıştır (Deadlock). Veri okunamıyor, yazılamıyor ve doğal olarak kalan WAL dosyaları işlenemiyordur.
Olayın kök nedenini araştırırken, PostgreSQL topluluğunun hata kayıtlarında (pgsql-bugs) gezinirseniz tam da bu senaryoyu anlatan Bug #19490 ile yüzleşebilirsiniz.
Peki bu kilitlenme neden durup dururken başınıza geldi? Cevap, masumane görünen “versiyon” farklılığında gizlidir. Örneğin üretim sunucunuz 16.8 sürümünde çalışırken, üzerine restore testini yaptığınız yedek sunucunuz yeni kurulduğu için 16.14 sürümüne sahip olabilir. “Nasıl olsa minor (alt) sürüm farkı, geriye dönük uyumludur” diye düşünebilirsiniz. Ancak PostgreSQL 16.12’de SimpleLruWriteAll() fonksiyonuna eklenen kod değişikliği, alt sürümler arası WAL replay işlemlerinde bu gizli deadlock hatasını tetiklemektedir.
Eğer siz de restore operasyonunun ortasında WAL dosyalarının aniden işlemeyi kestiği, sistemin sessizce donduğu sorunu yaşarsanız, yalnız değilsiniz. Gelin bu açmazdan nasıl kurtulabileceğinize ve veritabanını nasıl ayağa kaldırabileceğinize bakalım.

Geçici Çözüm Arayışı: Versiyon Düşürmek (Downgrade)
Sorunu tespit ettikten sonra ilk akla gelen, test sunucusundaki PostgreSQL versiyonunu production ile aynı seviyeye, yani 16.8’e (veya hatanın henüz olmadığı 16.11’e) çekmek olabilir. Veri dizinine (data directory) dokunmadan sadece binary dosyalarını düşürmek teorik olarak mümkündür. Ancak paket düşürmekle uğraşmak, işletim sistemi bağımlılıklarını çözmeye çalışmak isteyeceğiniz en son şeydir. Size çok daha temiz ve kalıcı çözüm lazımdır.
Kurtarıcı Süreç: PostgreSQL 16.15
Neyse ki PostgreSQL topluluğu bu hatanın (Bug #19490) farkına varmış ve müdahale etmiştir. 13 Ağustos 2026 tarihinde yayınlanan PostgreSQL 16.15 sürümü, tam da bu dertten muzdarip olanlar için çözüm olmuştur. Sürüm notları incelendiğinde, WAL replay (uygulama) sırasında SLRU kilitlerinde yaşanan o kördüğümün çözüldüğü görülmektedir.
Yapmanız gereken tek şey sunucuyu ileriye taşımaktır. Bu “minor” (alt) sürüm güncellemesi olduğu için veritabanı dosyalarıyla veya karmaşık göç senaryolarıyla uğraşmanıza gerek yoktur:
- Test sunucusundaki kilitlenmiş PostgreSQL servisini durdurun.
- İşletim sisteminizin paket yöneticisi (apt/yum vb.) üzerinden postgresql-16 paketini güncelleyerek 16.15 sürümüne çekin.
- Servisi yeniden başlatın.

Suskunluğun Bozulması ve Mutlu Son
PostgreSQL servisini başlattıktan sonra log dosyasını gözlemleyin. Ve o çözüm anı gelecektir… Saatlerdir dokunulmadan bekleyen gigabaytlarca WAL dosyası, saniyeler içinde işlenmeye başlanacaktır. pg_stat_slru sıfırlanacak ve bekleme olayları (wait events) tamamen normale dönecektir. Kilitlenme olmayacak, takılma yaşanmayacaktır. Sadece birkaç dakika içinde log dosyasında beklenen satırı göreceksiniz:
LOG: database system is ready to accept connections
Veritabanınız sağlıklı şekilde ayağa kalkacak, tam veri tutarlılığı (consistency) sağlanacak ve stresli başlayan restore testiniz başarıyla sonuçlanacaktır.
Çıkarılması Gereken Dersler (Best Practices)
Bu tarz restore testleri, veritabanı yönetimi hakkında altın değerinde birkaç kuralı hatırlatır:
- Minor Sürümleri Hafife Almayın: “16.x ile 16.y nasıl olsa aynıdır” demeyin. Veritabanı dünyasında küçük kod değişiklikleri, özellikle WAL replay ve SLRU gibi alt seviye çekirdek mekanizmalarda öngörülemeyen büyük etkilere yol açabilir.
- Versiyon Senkronizasyonu Şart: Restore testleri yaptığınız veya Felaket Kurtarma (DR) olarak beklettiğiniz sunucuların versiyonlarını, üretim (production) sunucularınızla birebir aynı minor versiyonda tutmaya özen gösterin.
- Güncel Kalın: Eğer versiyon farkı kaçınılmazsa veya yepyeni sunucu kuruyorsanız, her zaman PostgreSQL topluluğunun duyurduğu bilinen en son kararlı sürüme (bizim durumumuzda 16.15) geçin.
Eğer sizin de restore işleminiz sebepsiz yere donuyor ve loglar size hiçbir şey söylemiyorsa, belki de arka planda sessiz sedasız bekleyen MultiXactOffsetSLRU kilidi vardır. Çözüm çok uzakta değil; sunucunuzu 16.15’e güncelleyin ve arkanıza yaslanıp logların akışını izleyin.



