Каждые 5 минут транзакции в PostgreSQL замирают на 3-7 секунд. Разбор кривого механизма сброса WAL на диск.
В высоконагруженных системах с интенсивным IO наступает момент, когда p99 латентность запросов улетает в космос, а мониторинг дисковой подсистемы фиксирует дикий пик write activity. Причина кроется в дефолтных настройках PostgreSQL, а именно в механизме контрольных точек - checkpoints. Когда параметр max_wal_size выставлен в консервативные 1GB, база данных буквально захлебывается в грязных страницах - dirty pages.
Как это работает под капотом. PostgreSQL накапливает изменения в оперативной памяти в буферном пуле - shared_buffers. Фоновый процесс bgwriter старается сбрасывать их на диск плавно, но при дефолтном ограничении WAL в 1GB или агрессивном темпе транзакций порог срабатывания чекпоинта достигается слишком быстро. Ядро начинает экстренный сброс всех измененных страниц через системный вызов sync или fsync.
Главная беда кроется в параметре checkpoint_completion_target. По умолчанию он равен 0.5. Это значит, что PostgreSQL пытается сбросить весь накопленный объем dirty pages за половину времени между чекпоинтами. Если у вас интенсивная запись и чекпоинты происходят каждые 10 секунд, вся очередь накопившихся за это время грязных страниц выливается на дисковый массив лавинообразно. Диски упираются в 100% iowait, kernel page cache забивается, а все бэкенды блокируются в ожидании освобождения буферов. Мы получаем те самые микрофризы на 3-7 секунд, когда база кажется мертвой.
Лечим тюнингом параметров в postgresql.conf. Первое - увеличиваем пространство для маневра. Поднимаем max_wal_size до 16GB или 32GB, а min_wal_size до 2GB. Это растянет интервал между чекпоинтами и даст ядру Linux больше времени на фоновый сброс. Второе - выкручиваем checkpoint_completion_target в 0.9. Теперь PostgreSQL будет размазывать сброс грязных страниц на 90% времени интервала чекпоинта, снижая мгновенную нагрузку на дисковый контроллер в почти два раза.
Не забываем про уровень ядра Linux. Дефолтный планировщик ввода-вывода и параметры грязной памяти могут усугубить ситуацию. Выставляем vm.dirty_background_ratio в значения от 5 до 10, а vm.dirty_ratio до 20-30, чтобы Linux начинал фоновый сброс page cache на накопители заблаговременно, не дожидаясь блокировки процессов. Для NVMe массивов используем планировщик none или mq-deadline с увеличенной глубиной очереди.
Инфраструктурный аудит и калькулятор TCO кластера: @Personnel_run_bot (/tma)
База знаний и разборы: ftops.space
- ftops.space | Run-As-Daemon Infrastructure
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | Каждые 5 минут транзакции в PostgreSQL замирают на 3-7 секунд. ... | 0 | 9.79 | 30-09-2026 |
| 2 | Каждые 5 минут транзакции в PostgreSQL замирают на 3 - ... | -1 | 11.86 | 28-09-2026 |
| 3 | Каждые пять минут высоконагруженная база данных в PostgreSQL словно проваливается ... | 1 | 8.42 | 29-09-2026 |
| 4 | Каждые пять минут нагруженный PostgreSQL кластер словно падает в обморок ... | 0 | 7.98 | 28-09-2026 |
| 5 | Каждые 5 минут транзакции в PostgreSQL замирают на 3-7 секунд. ... | 0 | 8.8 | 29-09-2026 |
| 6 | Каждые 5 минут транзакции в PostgreSQL замирают на 3-7 секунд. ... | 0 | 11.43 | 28-09-2026 |
| 7 | Каждые пять минут нагруженный PostgreSQL кластер словно падает в обморок ... | 0 | 8.03 | 27-09-2026 |
| 8 | База данных захлебывается в дисковом I/O wait, хотя на сервере ... | 0 | 8.6 | 26-09-2026 |
| 9 | У вас 64 ядра и 256 ГБ памяти, но Nginx ... | 0 | 14.42 | 29-09-2026 |