Что это значит

В PostgreSQL у каждой транзакции номер, и номера идут по кругу. Чтобы старые строки не перепутались с новыми, их периодически «замораживает» vacuum. Если заморозка долго не проходит, счётчик подходит к пределу. Сначала база пишет в журнал предупреждения must be vacuumed within N transactions, а у самого края перестаёт принимать запись совсем. Для Directum RX это полная остановка работы.

До такого доходит, когда autovacuum не успевает или ему мешают: долгие транзакции, забытые слоты репликации, подготовленные транзакции, выключенный autovacuum на больших таблицах.

Как проверить

  1. Насколько близко к пределу:
select datname, age(datfrozenxid) from pg_database order by 2 desc;

Тревожно от 1 миллиарда, предел около 2 миллиардов. 2. Что мешает заморозке: старые транзакции в pg_stat_activity, неактивные слоты в pg_replication_slots, записи в pg_prepared_xacts.

Что сделать

  1. Убрать то, что мешает: завершить долгие транзакции, удалить ненужные слоты репликации.
  2. Запустить заморозку для самых «старых» таблиц: vacuum (freeze, verbose) <таблица>;
  3. Если база уже не принимает запись, следовать указаниям в тексте ошибки. В свежих версиях достаточно vacuum под суперпользователем, однопользовательский режим не нужен. Это долгая операция, на неё нужно окно.
  4. Поставить алерт на age(datfrozenxid) с порогом задолго до предела.