dataiotech Labs
Runbook #2
postgresql
AvailabilitySEV1 · KRİTİK KESİNTİ15-30 dakika / 15-30 minssuperuser / postgres / rds_superuser

PostgreSQL Transaction ID Wraparound Acil Durumu: Dondurma (Freeze) Planı

XID yaşı kritik seviyeye ulaştığında veritabanını yazmaya kapanmaktan kurtaran adımları verir. Engelleyicileri temizler ve VACUUM FREEZE'i doğru sırayla çalıştırır.

Operasyonel Güvenlik ve Risk Uyarısı

Bu runbook müdahale adımları içerir; birçok adım yazma etkilidir (KILL, terminate, DROP, RESIZE). Önce test ortamında deneyin, üretimde adımları sırayla ve doğrulayarak uygulayın.

🟢 Salt Okunur (Read-Only)·🟡 Geri Alınabilir (Reversible)·🔴 Yüksek Etkili / Geri Alınamaz (High Impact)

1. Belirti / Symptom

- M5: `age(datfrozenxid)` 1,5 milyarın üzerinde ve artıyor.

- Log: `WARNING: database "x" must be vacuumed within N transactions`.

- Son aşama: `ERROR: database is not accepting commands that assign new transaction IDs to avoid wraparound data loss`.

2. Etki / Impact

Sınıra yaklaşıldığında PostgreSQL **yazmaları reddeder** (veritabanı fiilen salt okunur olur). Kurtarma, veritabanı kapalıyken tek kullanıcı modunda VACUUM gerektirebilir ve uzun kesinti yaratır.

3. Teşhis / Diagnosis

🟢 Salt Okunur1. Hangi veritabanı ve tablolar eski (S7):
sql
SELECT datname, age(datfrozenxid) AS xid_age FROM pg_database ORDER BY 2 DESC;
-- Sorunlu veritabanına bağlanıp:
SELECT c.oid::regclass AS table_name, age(c.relfrozenxid) AS xid_age,
       pg_size_pretty(pg_total_relation_size(c.oid)) AS size
FROM pg_class c WHERE c.relkind IN ('r','m','t')
ORDER BY age(c.relfrozenxid) DESC LIMIT 15;
🟢 Salt Okunur2. **Vacuum'u engelleyenleri** bulun. En eski XID'i tutan her şey freeze'i engeller:
sql
-- Uzun transaction'lar
SELECT pid, usename, state, now()-xact_start AS age, backend_xmin
FROM pg_stat_activity WHERE backend_xmin IS NOT NULL ORDER BY age(backend_xmin) DESC LIMIT 5;
-- Unutulmuş prepared transaction'lar
SELECT gid, prepared, owner, database FROM pg_prepared_xacts ORDER BY prepared;
-- Replikasyon slotları (S13)
SELECT slot_name, active, xmin, catalog_xmin FROM pg_replication_slots;
-- Standby'lardan gelen feedback
SELECT pid, application_name, backend_xmin FROM pg_stat_replication;
🟢 Salt Okunur3. Autovacuum çalışıyor mu (S19)? `pg_stat_progress_vacuum` içinde anti-wraparound vacuum görünüyorsa dokunmayın, bitmesini bekleyin.

4. Müdahale / Response

🔴 YÜKSEK RİSK / GERİ ALINAMAZ1. **Engelleyicileri kaldırın:**

- Uzun/idle transaction: `pg_terminate_backend(pid)`.

- Unutulmuş prepared transaction: `COMMIT PREPARED 'gid';` veya `ROLLBACK PREPARED 'gid';` (sahibine danışın).

- Terk edilmiş replikasyon slotu: `SELECT pg_drop_replication_slot('slot_adi');`.

🟡 Geri Alınabilir2. En eski ve **küçük** tablolardan başlayarak elle dondurun (hızlı kazanım, en büyük tablo en sona):
sql
VACUUM (FREEZE, VERBOSE) kucuk_eski_tablo;
-- PG 12+, acil durumda indeks temizliğini atlayıp hızlandırmak için:
VACUUM (FREEZE, INDEX_CLEANUP OFF, VERBOSE) buyuk_tablo;
🟡 Geri Alınabilir3. Paralel çalıştırın (farklı oturumlarda farklı tablolar), disk I/O sınırını göz önünde bulundurun. Gerekirse geçici olarak:
sql
ALTER SYSTEM SET vacuum_cost_delay = 0;
SELECT pg_reload_conf();
🔴 YÜKSEK RİSK / GERİ ALINAMAZ4. Veritabanı yazmayı tamamen reddediyorsa: PostgreSQL'i durdurun ve **tek kullanıcı modunda** vacuum çalıştırın:
bash
postgres --single -D /var/lib/postgresql/data <veritabani_adi>
backend> VACUUM FREEZE;

Bu mod kesinti gerektirir; yedeğiniz olduğundan emin olun.

5. **Kalıcı çözüm:** Büyük ve hızlı değişen tablolar için tablo bazında `autovacuum_freeze_max_age` ve `autovacuum_vacuum_cost_limit` ayarlayın. PG 14+ `vacuum_failsafe_age` ile failsafe modu devreye girer. M5 için %50'de uyarı kurun.

5. Doğrulama / Verification

- `age(datfrozenxid)` 500 milyonun altına indi (veya düşme eğiliminde ve engelleyici yok).

- Yazmalar normal, log'da wraparound uyarısı yok.

- Autovacuum'un en büyük tablolarda yeniden çalıştığı `pg_stat_user_tables.last_autovacuum` ile görülüyor.

6. Geri Alma / Rollback

- `VACUUM FREEZE` geri alınmaz ama zararsızdır (yalnızca kaynak tüketir).

- `vacuum_cost_delay` ayarını işiniz bitince eski değerine çevirin: `ALTER SYSTEM RESET vacuum_cost_delay;`.

- Prepared transaction ve slot silme geri alınamaz.

Mühendislik Triadı: Doğrudan Teşhis Scriptleri

Bu runbook kriz müdahalesinde darboğazı tespit etmek için önerilen hazır SQL / Shell scriptleri:

Tüm Scriptler (100)
#3 · SQLMaintenance

PostgreSQL Dead Tuple, Bloat ve Autovacuum Durumu Kontrolü

Tablo bazında dead tuple oranını ve son vacuum/analyze zamanlarını gösterir. Autovacuum ayarının yetersiz kaldığı tabloları tespit etmenizi sağlar.

#7 · SQLMonitoring

PostgreSQL Transaction ID Wraparound Riski Kontrolü

Veritabanı bazında XID yaşını ve wraparound sınırına yüzde kaç yaklaşıldığını gösterir. Kritik bir kesintiyi önceden yakalamak için alarm kaynağıdır.

#13 · SQLReplication

PostgreSQL Replikasyon Slotları ve Biriken WAL

Aktif olmayan slotları ve tuttukları WAL miktarını gösterir. Terk edilmiş bir slotun diski doldurmasını önlemek için kritiktir.

#19 · SQLMaintenance

PostgreSQL Çalışan VACUUM İşlemlerinin İlerlemesi

Şu anda çalışan vacuum işlemlerinin hangi fazda olduğunu ve yüzde kaçının tamamlandığını gösterir. Uzun süren bir vacuum'un ne zaman biteceğini tahmin etmeye yarar.

Tetikleyen Alarmlar ve Metrikler
M5PostgreSQL Transaction ID YaşıPostgreSQL

Diğer POSTGRESQL Runbook'ları