DBAtlas · Veritabanı operasyon atlası

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=4

6. 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.

DBAtlas'ta aç →