DBAtlas · Атлас эксплуатации баз данных

Раздувание журнала транзакций / undo

Симптом

Файл журнала транзакций или область undo/redo быстро растёт; 'log full', 'ORA-01555 snapshot too old', 'unable to extend undo'.

1. Найдите открытую транзакцию, раздувающую журнал

Журнал/undo нельзя очистить, пока не завершится самая старая активная транзакция. Одна длинная открытая транзакция может удерживать весь журнал.

Oracle

SELECT s.sid, s.username, t.start_time, t.used_ublk FROM v$transaction t JOIN v$session s ON t.ses_addr=s.saddr ORDER BY t.start_time;

PostgreSQL

SELECT pid, state, xact_start, now()-xact_start age, query FROM pg_stat_activity WHERE xact_start IS NOT NULL ORDER BY xact_start;

MySQL

SELECT trx_id, trx_started, trx_mysql_thread_id FROM information_schema.innodb_trx ORDER BY trx_started;

SQL Server

DBCC OPENTRAN;

2. Поймите первопричину, специфичную для СУБД

MSSQL: в модели восстановления FULL журнал растёт бесконечно, если не делаются бэкапы журнала. Oracle: ORA-01555 = недостаточные undo retention/размер + длинный запрос. PG: если replication slot не продвигается, WAL накапливается; длинная транзакция блокирует VACUUM.

3. Правильное действие для журнала MSSQL

Сделайте бэкап журнала (BACKUP LOG) — это делает журнал повторно используемым. Если модель восстановления действительно должна быть SIMPLE, измените её. Затем при необходимости (и только при необходимости) сожмите журнал.

SQL Server

BACKUP LOG [DB] TO DISK='C:\backup\DB_log.trn';
-- Then, if needed: DBCC SHRINKFILE (N'DB_log', 512);

4. Проверка PG WAL / replication slot

Непродвигающийся (неактивный) replication slot вызывает накопление WAL. Перед удалением проверьте владельца слота (slot_type, database, plugin): это может быть временно отключившийся standby или логический подписчик/CDC (например, Debezium). При удалении слота подключённый standby придётся пересоздать, а сторону подписчика/CDC — пересинхронизировать. Удаляйте его, только если он действительно не используется; для долговременной защиты задайте верхнюю границу через max_slot_wal_keep_size (PG13+).

PostgreSQL

SELECT slot_name, active, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) retained FROM pg_replication_slots ORDER BY 3 DESC;
-- If unneeded: SELECT pg_drop_replication_slot('slot_name');

5. Настройте undo/retention и предотвратите повторение

Oracle: увеличьте табличное пространство UNDO, задайте undo_retention с учётом длинных запросов (или RETENTION GUARANTEE). Не допускайте длинных открытых транзакций в приложении. Контролируйте выполнение задания бэкапа журнала.

Открыть в DBAtlas →