Каждые 5 минут транзакции в PostgreSQL замирают на 3 - 7 секунд. Причина кроется в дефолтной конфигурации механизма checkpoint, который превращает фоновый сброс данных на диск в настоящий дисковый шторм.
По умолчанию параметр `max_wal_size` равен всего 1 GB, а `checkpoint_completion_target` выставлен в 0.5. Это значит, что при накоплении 1 GB WAL-файлов ядро базы данных обязано сбросить все грязные страницы в память за крайне короткий промежуток времени.
Когда `checkpoint_timeout` (по умолчанию 5 минут) или заполнение `max_wal_size` триггерят checkpoint, процесс `checkpointer` начинает агрессивно выплевывать из кеша операционной системы в файлы данных (файловую систему) гигабайты измененных блоков через `fsync`.
В этот момент производительность дисковой подсистемы утыкается в предельный IOPS или latency. `checkpoint_completion_target = 0.5` говорит серверу успеть записать все грязные страницы за первые 50% времени интервала checkpoint. Если у вас интенсивная запись, этот объем пролетает за секунды, перегружая кеш контроллера диска и очереди ядра Linux (`block layer`).
В результате Disk Queue Depth улетает в космос, латентность диска (await) подскакивает с долей миллисекунды до сотен миллисекунд, а новые транзакции блокируются на системных вызовах записи. Вы получаете классический микрофриз, когда мониторинг показывает просадку TPS до нуля, а CPU простаивает в ожидании диска (`I/O wait`).
Чтобы избавиться от этой боли, нужно размазать нагрузку во времени и дать ядру Linux возможность асинхронно сбрасывать страницы через `pdflush` или `writeback` потоки.
Первое действие - увеличиваем `max_wal_size` до 16 GB или даже 64 GB (если RAM позволяет). Это увеличит интервал между checkpoint-ами и позволит кешу эффективнее аггрегировать операции записи для одних и тех же блоков.
Второе действие - выставляем `checkpoint_completion_target = 0.9`. База данных будет равномерно распределять сброс грязных страниц на протяжении 90% времени до следующего чекипоинта, снижая пиковую нагрузку на накопители в 2 раза.
Третье действие - тюним ядро Linux. Параметр `vm.dirty_background_ratio` переводим с дефолтных 10% на 5% или задаем в мегабайтах через `vm.dirty_background_bytes`, чтобы ядро начинало фоновый сброс грязных страниц на диск задолго до того, как процесс упрется в жесткий лимит `vm.dirty_ratio`. Это сглаживает графики IOPS и полностью убирает пятисекундные лаги в продакшене.
- ftops.space | Run-As-Daemon Infrastructure
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | The insert benchmark on a small server : Postgres 12.22 through 18.3 | 0 | 11.9 | 29-03-2026 |
| 2 | Fixing Common PostgreSQL Performance Bottlenecks | 0 | 5.59 | 04-12-2020 |
| 3 | PostgreSQL Autovacuum Internals and Benchmark | 0 | 4.74 | 01-07-2026 |
| 4 | Linux наконец-то не тормозит или пятничный релакс | 0 | 13.18 | 07-08-2026 |
| 5 | Как отговорить себя от написания своей ФС | 0 | 11.64 | 09-08-2026 |
| 6 | Семь раз подумай, один раз пошардируй: как мы начали горизонтально масштабировать метаданные чатов Телемоста | 0 | 7 | 29-06-2026 |
| 7 | В systemd-journald спустя 6 лет признали проблему избыточной нагрузки на накопители | 0 | 14.65 | 14-08-2026 |
| 8 | [Перевод] Нетипичные оптимизации в PostgreSQL, или Креативное ускорение запросов | 0 | 8.21 | 02-03-2026 |
| 9 | Кэш результатов запросов в Postgres Pro: как ускорить часто выполняющиеся запросы и разгрузить базу | 0 | 7.15 | 15-05-2026 |