PostgreSQL WAL, fsync и p99 на NVMe: что ограничивает запись
Чтобы оценить PostgreSQL WAL, fsync и p99 на NVMe, смотреть нужно на время commit. На p99 влияют файловая система, метод синхронизации, защищённость кэша, RAID или виртуализация и профиль транзакций.
Какая операция WAL сильнее всего влияет на задержку commit?
При synchronous_commit=on задержку commit обычно определяет flush WAL на диск: PostgreSQL отвечает после локальной синхронизации. При синхронной репликации добавляется ожидание ответа standby, а блокировки, высокая загрузка CPU или сеть могут сильнее повлиять на результат и скрыть задержку накопителя.
От записи WAL до подтверждения клиенту
Задержка записи WAL PostgreSQL включает путь от WAL-буферов до диска: XLogFlush сбрасывает WAL до нужного LSN через ядро, файловую систему и контроллер. Изменённые страницы пишутся отдельно, поэтому связь с checkpoint проверяют по времени.
Какие гарантии должны оставаться одинаковыми в каждом тесте
Зафиксируйте synchronous_commit, fsync, full_page_writes, способ синхронизации, параметры монтирования и режим кэша. При fsync=off сбой повредит кластер. Сравнивайте p99 fsync на NVMe без смены гарантий.
Очереди, прошивка, температура и заполнение накопителя
Снимите nvme id-ctrl /dev/nvme0, nvme smart-log /dev/nvme0 и укажите тип подключения. Отчёт от 27 мая 2025 года: бенчмарк pg_test_fsync для PostgreSQL 16 показал 1643 мкс на fdatasync для Samsung 990 Pro с XFS и 24 мкс для Micron 7400 с PLP в другом стеке. Разница здесь между классами накопителей, а не между конкретными моделями.
Почему пиковые IOPS NVMe не предсказывают p99 fsync?
Пиковые IOPS достигаются при глубокой очереди, а синхронный WAL часто ждёт одиночный flush. Средняя пропускная способность скрывает редкие паузы кэша, прошивки или сборки мусора. При этом паспортный показатель помогает при первичном отборе, но не заменяет длительное измерение задержки fsync на том же стеке, где будет лежать pg_wal.
pg_test_fsync и fio при шаблоне, похожем на WAL
В той же файловой системе, что и pg_wal, запустите
pg_test_fsync -f /test/pgfs -s 30
затем fio на отдельном файле:
fio --name=wal --filename=/test/wal.fio --size=2G --rw=write --bs=8k --iodepth=1 --fdatasync=1 --runtime=300 --time_based --output-format=json+
Если при одинаковой нагрузке вместе растут задержка synchronous_commit и fio sync latency, проверяйте накопитель.
Как fsync проявляется в pgbench под управляемой нагрузкой
Создайте базу
pgbench -i -s 100 benc
и выполните по три 10-минутных прогона при N=1, 8 и 32:
pgbench -M prepared -c N -T 600 -l bench
По журналам рассчитайте p50, p95 и p99. Их рост вместе с задержкой fsync и очередью указывает на узкое место хранилища WAL.
Queue depth, await и редкие провалы NVMe
Параллельно снимайте iostat -x 1 и nvme smart-log. Рост await и aqu-sz вместе с пиками commit latency указывает на очередь. Но похожую картину даёт checkpoint, поэтому сопоставляйте метрики по времени и фиксируйте wal_sync_method.
Как правильно интерпретировать pg_test_fsync?
1. Сравнивайте методы на файловой системе будущего pg_wal.
2. Читайте полный вывод вместе с условиями теста.
3. Сверяйте результаты с pgbench и мониторингом: микротест не предсказывает p99 commit.
Что меняет профиль записи, а что меняет гарантию
При групповом commit один flush обслуживает несколько транзакций, поэтому throughput и queue depth меняются с конкуренцией. wal_sync_method выбирают по результатам теста. synchronous_commit=off грозит потерей подтверждённых транзакций: это другая гарантия сохранности, а не настройка производительности.
Как перевести измерения в требование к хранилищу
Например, SLO допускает до 1% транзакций дольше 10 мс и до 30 секунд непрерывного нарушения. Тест проводят при рабочем заполнении. После смены прошивки, файловой системы или хоста снова проверяют tail latency.
Хранилище выбирают по p99 commit при тех же гарантиях сохранности. PostgreSQL WAL, fsync и p99 на NVMe сопоставляют по времени: pg_test_fsync измеряет flush, pgbench его эффект, а iostat – состояние очереди.