Добавить в корзинуПозвонить
Найти в Дзене
Postgres DBA

4.Philosophical_instruction_BETA_v5.1

Периоды наблюдения:
Конфигурация стенда:
Ключевые изменения в P2 (по сравнению с P1):
Предоставленный отчёт содержит обработанные статистические данные и выводы, но для углублённой диагностики и подтверждения выдвинутых гипотез необходимы следующие данные (🟡/🔴 — в зависимости от вероятной ценности):
Оглавление

Общая информация

Периоды наблюдения:

  • Период 1 (P1): 2026-03-11 14:35 – 15:35 (базовый уровень)
  • Период 2 (P2): 2026-03-11 15:35 – 16:35 (инцидент производительности)

Конфигурация стенда:

  • PostgreSQL 15.13 на Linux x86_64.
  • Аппаратно: 192 логических ядра (Intel Xeon Platinum 8280L, 4 сокета), 1007 ГБ ОЗУ, NUMA 4 узла.
  • Ключевые настройки СУБД:
  • shared_buffers = 246 ГБ (🟢 соответствует ~24% ОЗУ)
  • effective_cache_size = 730 ГБ (🟢 адекватно объёму кэша ОС)
  • work_mem = 1 ГБ на операцию сортировки/хеша
  • maintenance_work_mem = 16 ГБ, autovacuum_work_mem = 2 ГБ
  • checkpoint_timeout = 15 мин, max_wal_size = 8 ГБ
  • max_parallel_workers_per_gather = 0 (🟡 параллелизм запросов отключён)
  • synchronous_commit = remote_write
  • Дисковая подсистема:
  • vdg – выделенное устройство под WAL
  • vdh, vdi, vdj, vdk – LVM-пул для данных (/data)
  • vde – /log, vdc – /backup (не анализировались)

Ключевые изменения в P2 (по сравнению с P1):

  • 🟢 Операционная скорость (SPEED) перешла от слабого роста к устойчивому падению (R²=0.94, наклон -44.09).
  • 🟢 Ожидания СУБД (WAITINGS) стали уверенно расти (R²=0.58, наклон +37.28).
  • 🟢 Обратная корреляция между скоростью и ожиданиями усилилась с умеренной (r=-0.55) до сильной (r=-0.77).
  • 🟢 Утилизация устройств данных (vdh–vdk) превысила 90%, очередь запросов (aqu_sz) выросла с ~2.0 до ~2.5.
  • 🟢 Объём записи на WAL-устройство (vdg) вырос вдвое (с 7.8 до 16.0 МБ/с медианно).
  • 🟢 Появились новые типы ожиданий: WALSync (IO) и блокировки tuple (Lock).

Ключевые проблемы СУБД и инфраструктуры

1. Дисковая подсистема данных достигла насыщения

  • 🟢 Утилизация устройств vdh–vdk в P2 стабильно >90% (ALARM по условиям отчёта). Медианный рост w/s на 118% и wMB/s на ≈100% привёл к выходу на плато производительности.
  • 🟢 Операционная скорость (SPEED) стала сильно коррелировать с объёмом записи на диски данных (r=0.73, R²=0.54). В P1 такая связь была слабой (r≈0.46). Это прямое свидетельство того, что пропускная способность дисковой подсистемы стала узким местом.
  • 🟡 Рост очереди запросов (aqu_sz с 2.0 до 2.5) при сохранении низких задержек (r_await, w_await <0.3 мс) указывает на высокую параллельную нагрузку, с которой устройства справляются, но их пропускная способность уже исчерпана.

2. Резкое увеличение нагрузки на WAL и появление ожиданий WALSync

  • 🟢 Запись на vdg выросла в 2 раза по объёму (медиана wMB/s: 7.75 → 16.0) и на 85% по операциям (w/s: 373 → 689).
  • 🟢 В P2 появились ожидания WALSync, составляющие 11% от всех ожиданий IO. Они отсутствовали в P1.
  • 🟡 Утилизация vdg осталась низкой (медиана 10%), что говорит о достаточной производительности устройства, но возросший объём записи увеличивает латентность синхронизации WAL, особенно при synchronous_commit = remote_write.

3. Критическая конкуренция за легковесные блокировки (LWLock)

  • 🟢 В P1 99% вариации общих ожиданий объяснялось LWLock (R²=0.99). В P2 объясняющая сила снизилась до 55%, но LWLock сохранил критический уровень взвешенной корреляции (ВКО=0.30).
  • 🟢 Основные события внутри LWLock:
  • BufferMapping (~30%) – конкуренция за доступ к буферному кэшу. Вероятная причина: высокая частота обращений к одним и тем же страницам данных или недостаточное количество буферных разделов (lwlock_shared_limit не задан).
  • WALWrite (~26%) – конкуренция при записи WAL, коррелирует с возросшей нагрузкой на vdg.
  • pgpro_stats (~18%) – ожидания внутри расширения сбора статистики.

4. Аномальная активность расширений (Extension) в P2

  • 🟢 По интегральному приоритету тип ожиданий Extension вышел на первое место в P2 (0.6625 против 0.37 у LWLock). В P1 значимой корреляции с общими ожиданиями не было.
  • 🟢 Ожидания Extension стали очень сильно коррелировать с user time CPU (r=0.91, R²=0.82) и с прерываниями (r=0.83, R²=0.68). Это указывает на интенсивное выполнение кода расширений в user space, вероятно, с большим количеством системных вызовов.
  • 🟢 Проблемный запрос -5038981907002478858 генерирует 33.7% всех ожиданий Extension (в P1 было 8.5%) и 32.2% всех ожиданий LWLock (было 6.1%). Его доля в общей нагрузке резко возросла.

5. Рост конкуренции за строки (блокировки tuple)

  • 🟢 В P2 появились блокировки tuple, отсутствовавшие в P1, которые составили 20.4% от всех ожиданий Lock. Основной тип Lock по-прежнему transactionid (79%).
  • 🟡 Это свидетельствует о возросшей конкуренции на уровне строк в транзакциях (UPDATE/DELETE или INSERT с конфликтами уникальности). Топ-запросы демонстрируют ненулевую долю tuple-ожиданий.

6. Признаки роста общей загрузки CPU при неполной диагностике

  • 🟢 В P2 тренд cpu idle перешёл к устойчивому падению (R²=0.79, наклон -41.71). Медианный idle снизился с 69% до 72%? (в отчёте противоречие: медиана idle выросла на 3 п.п., но тренд отрицательный). 🟡 Требуется проверка исходных рядов для точной интерпретации.
  • 🟡 Рост iowait с 2% до 3% лишь частично объясняет снижение idle. Недостаточно данных для разбивки us/sy/wa во времени. Возможно увеличение steal (гипервизор) или рост нагрузки на user/system, не отражённое в граничных значениях.

7. Память: свободной ОЗУ <5%, но без подкачки

  • 🟢 В обоих периодах 100% времени free RAM < 5% (≈13 ГБ). Swap не используется.
  • 🟡 Это типично для heavily loaded PostgreSQL при активном файловом кэше (≈720 ГБ). Риск заключается в возможном вытеснении страниц shared_buffers или кэша ОС при пиковых аллокациях памяти процессами (например, при большом количестве сессий с высоким work_mem). Данных о количестве сессий нет.

Рекомендации по оптимизации СУБД и инфраструктуры

⚠️ Все рекомендации даны на основе предоставленного отчёта и носят статус 🟡 (вероятно полезны) или 🔴 (требуют дополнительной диагностики и тестирования в конкретной среде). Окончательные решения должны приниматься после проверки гипотез.

СУБД

1. Исследовать и оптимизировать запрос -5038981907002478858 (🔴 приоритет)

  • Почему: Запрос стал основным генератором ожиданий Extension и LWLock в P2.
  • Действия:
  • Получить план выполнения (EXPLAIN (ANALYZE, BUFFERS, TIMING)).
  • Проверить, какие расширения вызываются в запросе. Оценить их необходимость и накладные расходы.
  • Рассмотреть возможность рефакторинга запроса, добавления индексов или изменения логики для снижения частоты вызовов расширений.
  • Ожидаемый эффект: Снижение нагрузки на Extension и, как следствие, уменьшение конкуренции за CPU и LWLock.

2. Проанализировать и, возможно, снизить конкуренцию за LWLock BufferMapping (🟡)

  • Почему: LWLock BufferMapping доминирует среди легковесных блокировок (30%).
  • Действия:
  • Проверить статистику pg_stat_bgwriter на предмет buffers_alloc и buffers_backend_fsync.
  • Оценить равномерность доступа к страницам. Высокая конкуренция может быть следствием «горячих» блоков данных.
  • Рассмотреть увеличение shared_buffers (текущие 246 ГБ при кэше ОС 720 ГБ) — потенциально может снизить частоту обращений к кэшу ОС, но требует тестирования.
  • Изучить возможность увеличения числа буферных разделов через параметр lwlock_shared_limit (только после анализа текущего распределения блокировок).
  • Ожидаемый эффект: Снижение LWLock ожиданий, улучшение пропускной способности при работе с буферным кэшем.

3. Оптимизировать работу с WAL для уменьшения ожиданий WALSync (🟡)

  • Почему: Удвоение записи WAL и появление ожиданий синхронизации.
  • Действия:
  • Проанализировать причины роста записи WAL: возможно, увеличилось число транзакций или объём изменяемых данных. Использовать pg_stat_statements для поиска запросов с высоким wal_bytes.
  • Проверить настройки wal_writer_delay (по умолчанию 200 мс) и wal_writer_flush_after (по умолчанию 1 МБ). Адаптация под возросшую нагрузку может сгладить пики.
  • Рассмотреть группировку мелких транзакций на стороне приложения.
  • Ожидаемый эффект: Снижение латентности синхронизации WAL, уменьшение влияния на WALSync.

4. Рассмотреть включение параллелизма запросов (🟡)

  • Почему: max_parallel_workers_per_gather = 0 полностью отключает параллельное выполнение. При наличии 192 ядер и сканировании больших таблиц это может приводить к неэффективному использованию CPU.
  • Действия:
  • Включить параллелизм с осторожностью: установить max_parallel_workers_per_gather = 2 или 4, max_parallel_workers и max_worker_processes адекватно.
  • Отслеживать влияние на cpu us/sy и iowait.
  • Ожидаемый эффект: Потенциальное ускорение аналитических запросов, снижение времени выполнения, но может увеличить нагрузку на CPU и I/O.

5. Проверить накладные расходы расширения pgpro_stats (🟡)

  • Почему: Ожидания pgpro_stats составляют 18% от всех LWLock. Возможно, сбор детальной статистики создаёт избыточную нагрузку.
  • Действия:
  • Оценить частоту сбора и уровень детализации. При необходимости снизить.
  • Временно отключить для проверки влияния на LWLock и CPU (в тестовой среде).
  • Ожидаемый эффект: Снижение LWLock, освобождение ресурсов CPU.

6. Проанализировать причину появления блокировок tuple (🟡)

  • Почему: Новый тип блокировок в P2 указывает на конкуренцию за строки.
  • Действия:
  • Использовать представление pg_stat_user_tables для поиска таблиц с высоким числом n_tup_upd, n_tup_del.
  • Проверить наличие необходимых индексов на столбцах, участвующих в условиях WHERE для UPDATE/DELETE. Отсутствие индекса может приводить к блокировке большего числа строк, чем необходимо.
  • Анализировать логи на предмет deadlock'ов или длительных транзакций.
  • Ожидаемый эффект: Снижение конкуренции за строки, уменьшение Lock-ожиданий.

Инфраструктура

7. Расширение пропускной способности дисковой подсистемы данных (🔴 приоритет)

  • Почему: Устройства данных достигли утилизации >90% и стали узким местом.
  • Действия:
  • Профилировать ввод-вывод на уровне ОС (iostat -x 1, pidstat -d) для подтверждения, что именно запросы PostgreSQL создают нагрузку.
  • Оценить возможность добавления более производительных дисков (NVMe) или увеличения числа устройств в LVM-пуле.
  • Проверить, оптимально ли настроен effective_io_concurrency = 300. При высоких очередях на NVMe может потребоваться корректировка.
  • Ожидаемый эффект: Устранение узкого места, возможность обслуживать возросшую нагрузку записи без деградации скорости.

8. Мониторинг WAL-устройства и возможное ускорение (🟡)

  • Почему: Нагрузка на vdg выросла вдвое, появились ожидания WALSync.
  • Действия:
  • Убедиться, что vdg не используется другими процессами.
  • Мониторить w_await на vdg; если задержки растут, рассмотреть более быстрое устройство или отдельный том с высокими IOPS.
  • Ожидаемый эффект: Снижение влияния записи WAL на общую производительность.

9. Контроль использования памяти (🟡)

  • Почему: Свободной ОЗУ <5%, хотя подкачки нет. Риск вытеснения страниц при пиковых нагрузках.
  • Действия:
  • Настроить мониторинг memory_free и memory_cache с алертами при резком падении кэша.
  • Оценить количество одновременных сессий. Если оно велико, возможно избыточное потребление памяти из-за work_mem = 1 ГБ. Рассмотреть снижение work_mem для массовых сессий или установку лимитов на уровне пула соединений.
  • Ожидаемый эффект: Предотвращение вытеснения страниц shared_buffers, сохранение стабильности кэша.

10. Детальное профилирование CPU (🟡)

  • Почему: Устойчивое снижение cpu idle не полностью объясняется ростом iowait.
  • Действия:
  • Использовать mpstat -P ALL для анализа загрузки по ядрам.
  • Проверить steal в виртуализированной среде (KVM). Рост steal может имитировать увеличение iowait или system.
  • Применить perf top для выявления hot-функций в ядре или PostgreSQL.
  • Ожидаемый эффект: Выявление скрытых причин роста загрузки CPU.

Необходимая дополнительная информация для продолжения анализа

Предоставленный отчёт содержит обработанные статистические данные и выводы, но для углублённой диагностики и подтверждения выдвинутых гипотез необходимы следующие данные (🟡/🔴 — в зависимости от вероятной ценности):

Критически важные (без них анализ неполон):

  • 🔴 Тексты и планы выполнения топ-запросов (особенно -5038981907002478858 и -4280293605113329019) с EXPLAIN (ANALYZE, BUFFERS, TIMING, VERBOSE).
  • 🔴 Логи PostgreSQL за периоды P1 и P2, содержащие сообщения об ошибках, deadlock'ах, checkpoint'ах, autovacuum.
  • 🔴 Детальная статистика по таблицам и индексам из pg_stat_user_tables, pg_stat_user_indexes за указанные периоды.
  • 🔴 Данные о количестве активных сессий и их состояниях (pg_stat_activity) во времени.

Важные для уточнения гипотез:

  • 🟡 Исходные временные ряды метрик (вместо агрегированных граничных значений и медиан) для:
  • CPU us, sy, wa, id, st (mpstat)
  • vmstat (procs, memory, swap, io, system, cpu) с минутным разрешением
  • iostat -x по всем устройствам с минутным разрешением
  • 🟡 Статистика pg_stat_bgwriter для анализа эффективности буферного кэша и контрольных точек.
  • 🟡 Информация о расширениях (какие установлены, их версии, конфигурация pgpro_stats).
  • 🟡 Данные о настройках ОС (планировщик ввода-вывода, параметры ядра vm.dirty_*, vm.vfs_cache_pressure).
  • 🟡 Профиль нагрузки на диск с помощью pidstat -d или iotop для идентификации процессов-генераторов I/O.

Желательные для полной картины:

  • 🟡 Результаты трассировки проблемного запроса с auto_explain.log_analyze = on и auto_explain.log_min_duration = 0 (на короткий промежуток).
  • 🟡 Дамп pg_locks в моменты пиковых ожиданий Lock/LWLock.
  • 🟡 Метрики NUMA (numastat) для выявления возможного дисбаланса доступа к памяти.

Ограничение анализа:

Без перечисленных данных любые рекомендации по изменению параметров конфигурации PostgreSQL (shared_buffers, work_mem, lwlock_shared_limit и др.) являются спекулятивными (🔴) и должны проверяться в тестовой среде. Текущий анализ основан исключительно на агрегированных отчётах, которые не позволяют однозначно установить причинно-следственные связи на уровне отдельных запросов и системных вызовов.