Postgres XID wraparound / autovacuum krizi
Belirti
'database is not accepting commands to avoid wraparound data loss'; autovacuum yetişemiyor, datfrozenxid yaşlanıyor.
1. Aciliyeti anla
PostgreSQL transaction ID'si 32 bittir; tükenmeye yaklaşınca veri kaybını önlemek için sunucu YAZMAYI durdurur. Bu kritik ve zamana karşı bir durumdur. İyi haber: çözülebilir, panik değil disiplin gerekir.
2. Ne kadar yakınsın ölç
Her veritabanının en eski donmamış XID yaşını çıkar; autovacuum_freeze_max_age'e (varsayılan 200M) yakınlık tehlikeyi gösterir.
PostgreSQL
SELECT datname, age(datfrozenxid) AS xid_age
FROM pg_database ORDER BY xid_age DESC;3. En yaşlı tabloları bul
Sorun genelde birkaç büyük/sık yazılan tablodan gelir; en yaşlı relfrozenxid'lere odaklan.
PostgreSQL
SELECT relname, age(relfrozenxid) AS xid_age
FROM pg_class WHERE relkind IN ('r','m','t')
ORDER BY xid_age DESC LIMIT 20;4. VACUUM'u engelleyenleri kaldır
Uzun açık transaction'lar, terk edilmiş replication slot'ları ve prepared transaction'lar temizlemeyi (freeze) engeller. Bunları bul ve çöz — yoksa VACUUM ne kadar çalışsa da ilerlemez.
PostgreSQL
SELECT pid, now()-xact_start AS age, state FROM pg_stat_activity WHERE xact_start IS NOT NULL ORDER BY age DESC;
SELECT slot_name, active FROM pg_replication_slots WHERE NOT active;
SELECT * FROM pg_prepared_xacts;5. Agresif FREEZE çalıştır
Engeller kalktıktan sonra en yaşlı tablolardan başlayarak donmayı zorla. Sunucu yeni transaction ID atamayı durdurmuş olsa bile tek-kullanıcı moduna (postgres --single) geçme: güncel PostgreSQL belgeleri bunun artık gerekmediğini ve kaçınılması gerektiğini belirtir. Normal modda superuser olarak bağlanıp VACUUM çalıştırmak yeterlidir; PG14+ sürümlerde wraparound yaklaşınca VACUUM'un failsafe mekanizması devreye girer.
PostgreSQL
VACUUM (FREEZE, VERBOSE) yasli_tablo;
-- Tüm veritabanı: vacuumdb --all --freeze --jobs=46. Kalıcı: autovacuum'u güçlendir ve izle
autovacuum_vacuum_cost_limit'i artır, autovacuum_naptime'ı düşür, çok yazılan tablolara özel storage parametreleri ver. age(datfrozenxid) için alarm kur; bu krizi bir daha yaşama.