Найти в Дзене
Postgres DBA

"Тантор Лабс": Сводный отчет по производительности СУБД и инфраструктуры.

Версия PostgreSQL: 17.5 на x86_64-pc-linux-gnu (компилятор gcc 11.4.1)
Аппаратное обеспечение:
vda (70 GB) – системный раздел (/, /boot, /tmp, /opt, /home, /var)
vdb (30 GB) – смонтирован в /log (журналы PostgreSQL)
Оглавление

Сводный отчет по производительности СУБД и инфраструктуры

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

Версия PostgreSQL: 17.5 на x86_64-pc-linux-gnu (компилятор gcc 11.4.1)

Аппаратное обеспечение:

  • Виртуальная машина на гипервизоре KVM
  • Процессор: 8 виртуальных ядер Intel Xeon (Skylake, IBRS, без TSX)
  • Оперативная память: 7.50 GB
  • Дисковая подсистема (LVM):

vda (70 GB) – системный раздел (/, /boot, /tmp, /opt, /home, /var)

vdb (30 GB) – смонтирован в /log (журналы PostgreSQL)

vdc (50 GB) – смонтирован в /wal (WAL)

vdd (100 GB) – смонтирован в /data (табличные пространства)

Ключевые параметры PostgreSQL:

  • shared_buffers = 1779 MB
  • work_mem = 35 MB
  • maintenance_work_mem = 196 MB
  • effective_cache_size = 5081 MB
  • max_connections = 91
  • wal_buffers = 23 MB
  • max_wal_size = 2021 MB
  • checkpoint_timeout = 15 min
  • random_page_cost = 1.1, seq_page_cost = 1
  • effective_io_concurrency = 128
  • shared_preload_libraries = pg_stat_statements, pg_wait_sampling

· Настройки управления памятью ОС (vm):

  • dirty_background_ratio = 10%
  • dirty_ratio = 30%
  • dirty_expire_centisecs = 1000
  • dirty_writeback_centisecs = 500
  • swappiness = 1
  • vfs_cache_pressure = 100

Общий анализ операционной скорости и ожиданий СУБД

Анализ выполнялся за период 2026-03-05 18:09 – 2026-03-05 20:31 (2 часа 22 минуты).

Граничные значения операционной скорости (SPEED) и ожиданий СУБД (WAITINGS)

Операционная скорость (SPEED):

  • Минимум: 375 955
  • Медиана: 383 994
  • Максимум: 683 866

Суммарные ожидания (WAITINGS):

  • Минимум: 48 536
  • Медиана: 78 011
  • Максимум: 226 349

Анализ трендов операционной скорости и ожиданий

Тренд SPEED по времени:

  • Коэффициент детерминации R² = 0.77 (хорошее качество модели)
  • Угол наклона = +41.33 (положительный тренд, скорость растёт)
  • Интерпретация: модель объясняет 77% вариации, тренд достоверен.

Тренд WAITINGS по времени:

  • R² = 0.87 (очень высокое качество)
  • Угол наклона = +43.01 (ожидания растут ещё быстрее)

Регрессия SPEED от WAITINGS:

  • R² = 0.97 (исключительно сильная связь)
  • Угол наклона = +44.56
  • Вывод: рост ожиданий практически полностью объясняет рост операционной скорости (нагрузки).

1. СТАТИСТИЧЕСКИЙ АНАЛИЗ ОЖИДАНИЙ СУБД

Анализ проведён по типам событий ожидания (wait_event_type). Оценка выполнена по трём этапам: значимость корреляции, взвешенная корреляция ожиданий (ВКО), коэффициент детерминации R².

BufferPin, Extension: корреляция отсутствует или отрицательная.

IPC, Lock, LWLock, Timeout: корреляции значимые (0.96–0.97), но ВКО < 0.01 – игнорируются в текущем анализе.

IO (ожидания ввода-вывода):

  • Корреляция с общими ожиданиями: 1.0 (значимая)
  • ВКО = 1.0 – критическое значение, требует немедленного анализа
  • R² = 1.0 – модель идеально объясняет вариацию
  • Интегральный приоритет типа ожидания IO = 0.6271 (наибольший вклад в проблемы)

Итог по разделу "1. СТАТИСТИЧЕСКИЙ АНАЛИЗ ОЖИДАНИЙ СУБД"

  • Основной тип ожиданий, влияющий на производительность – IO.
  • Остальные типы (блокировки, LWLocks, IPC) имеют незначительный вклад.
  • Необходимо сконцентрироваться на анализе IO-запросов и оптимизации дисковых операций.

2. ТРЕНДОВЫЙ АНАЛИЗ ПРОИЗВОДИТЕЛЬНОСТИ vmstat

Оценены ключевые метрии vmstat.

procs r (процессы в очереди на выполнение):

  • R² = 0.74 (хорошая модель)
  • Наклон = +40.74 – негативный тренд (рост)
  • Коэффициент тренда = 30.21 – очень высокая скорость изменения (инцидент)
  • Рекомендация: проверить загрузку CPU, выявить процессы-потребители.

procs b (процессы в uninterruptible sleep, обычно ожидание IO):

  • R² = 0.87 (очень высокая)
  • Наклон = +42.95 – негативный тренд
  • Коэффициент тренда = 37.23 – очень высокая скорость изменения (инцидент)
  • Рекомендация: исследовать дисковую подсистему (iostat, iotop).

cpu wa (простой CPU в ожидании IO):

  • R² = 0.03 – модель непригодна, тренд незначим.

cpu id (простой CPU):

  • R² = 0.91 (очень высокая)
  • Наклон = –43.66 – сильный негативный тренд (падение)
  • Коэффициент тренда = 39.74 – очень высокая скорость изменения (инцидент)
  • Рекомендация: проверить, не связано ли с уменьшением полезной работы.

Итог по разделу "2. ТРЕНДОВЫЙ АНАЛИЗ ПРОИЗВОДИТЕЛЬНОСТИ vmstat"

  • Наблюдается стремительный рост числа процессов, ожидающих IO (procs b), и одновременное падение простоя CPU.
  • Это указывает на развивающийся узким местом ввода-вывода.
  • Ситуация требует немедленного вмешательства.

3. СТАТИСТИЧЕСКИЙ АНАЛИЗ ОЖИДАНИЙ СУБД и МЕТРИК vmstat

Общие индикаторы (проценты времени за период)

Свободная RAM < 5%: 100% времени – ALARM

iowait (wa) > 10%: 100% времени – ALARM

Процессы в uninterruptible sleep (b) превышают число ядер CPU: 100% времени – ALARM

Основные корреляции

IO и записанные блоки (bo): R = 0.849, R² = 0.72 – хорошая модель. Указывает на сброс «грязных» страниц (checkpointer, bgwriter).

IO и считанные блоки (bi): R = 0.554, R² = 0.31 – слабая связь.

Контекстные переключения (cs) с прерываниями (in), user time (us), system time (sy):

  • cs–in: R² = 0.99, cs–us: R² = 0.99, cs–sy: R² = 0.95 – очень высокие. Ядро тратит много времени на переключения и планирование.

Записанные блоки и bo: R² = 0.77 – подтверждает влияние записи на диск.

dirty pages размер (KB) и процессы b: R² = 0.98 – чрезвычайно сильная связь (ALARM). Рост dirty pages напрямую увеличивает число процессов, заблокированных в IO.

dirty pages и bo: R² = 0.74 – механизм обратной записи не успевает за генерацией грязных страниц.

dirty pages и system time (sy): R² = 0.95 – высокие накладные расходы ядра на управление памятью.

Shared Buffers hit ratio

· Минимум: 96.09%, медиана: 96.64%, максимум: 98.36% – приемлемо для OLAP-нагрузки, но не идеально.

Итог по разделу "3. СТАТИСТИЧЕСКИЙ АНАЛИЗ ОЖИДАНИЙ СУБД и МЕТРИК vmstat"

  • Система испытывает острый дефицит оперативной памяти (свободная RAM <5% всё время).
  • IO-ожидания (wa) постоянно превышают 10%.
  • Количество процессов, заблокированных в IO (b), стабильно выше числа ядер CPU.
  • Выявлена сильная связь между объёмом dirty pages и блокировками процессов, что указывает на неэффективную работу механизмов фоновой записи как на уровне ОС, так и на уровне PostgreSQL.
  • Контекстные переключения и системное время высоки, что говорит о значительных накладных расходах ядра.

4. ДИАГРАММЫ ПАРЕТО ПО WAIT_EVENT_TYPE и QUERYID

Анализ по queryid показал, что основная масса ожиданий IO приходится на один запрос.

Тип ожидания IO, интегральный приоритет = 0.6271

Основной запрос:

Query ID: 8275902800498673318

  • Текст: select scenario1()
  • Количество вызовов за период: 16 816 525
  • Суммарные ожидания: 12 059 950
  • Доля от всех ожиданий IO: 85.04%
  • База данных / роль: pgbench_db / expecto_user
  • События ожиданий: DataFileRead, DataFileWrite, SlruRead

Другие запросы (с меньшей активностью):

  • 8858888517606718968 – запрос к pg_catalog
  • 3895287528978123373 – select scenario2()
  • -90887298659241024 – select scenario3()

Итог по разделу "4. ДИАГРАММЫ ПАРЕТО ПО WAIT_EVENT_TYPE и QUERYID"

  • Подавляющая часть проблем с IO связана с единственным запросом select scenario1().
  • Оптимизация этого запроса или его доступа к данным может кардинально снизить нагрузку на диск.

Детальный анализ – граничные значения и корреляции

Ожидания СУБД

IO – единственный значимый тип ожиданий (ВКО = 1.0, R² = 1.0). Вклад в общую картину – 85% через один запрос.

· Остальные типы ожиданий (блокировки, LWLock) имеют корреляции, но их абсолютный вклад ничтожен.

Память и буферный кэш

  • Shared buffers hit ratio ~96.6% – приемлемо, но возможен рост при увеличении буферов.
  • Свободная RAM практически отсутствует – постоянный дефицит памяти.
  • dirty pages сильно коррелируют с sy и b – память под кэш записи становится узким местом.

Дисковая подсистема (I/O)

Сильные корреляции:

  • Записанные блоки ↔ bo (R² = 0.77) – активная запись на диск.
  • dirty pages ↔ bo (R² = 0.74) – накопление грязных страниц.
  • dirty pages ↔ b (R² = 0.98) – прямое влияние на блокировку процессов.

Слабые корреляции: чтение (bi) и IO (R² = 0.31) – чтение не является главной причиной ожиданий.

  • Диски под WAL (/wal) и данными (/data) физически разделены, но нагрузка на запись, вероятно, превышает их пропускную способность.

CPU и системные вызовы

  • Контекстные переключения (cs) тесно связаны с прерываниями, user и system time.
  • Высокое sy (system time) коррелирует с dirty pages – ядро тратит ресурсы на управление памятью.
  • Низкий id (простой CPU) на фоне высокого wa указывает, что CPU простаивает из-за ожидания IO, а не из-за отсутствия работы.

Блокировки и ожидания LWLock

  • Статистически незначимы (ВКО < 0.01), не являются проблемой в данном периоде.

Анализ запросов (queryid)

  • Основной вклад (85% ожиданий) – запрос select scenario1().
  • Необходимо проанализировать его план выполнения, индексы, объём обрабатываемых данных.

Ключевые проблемы

Проблемы СУБД

1. Доминирование IO-ожиданий, вызванное единственным запросом.

2. Неоптимальная работа с буферным кэшем – несмотря на hit ratio 96%, частые чтения с диска (DataFileRead) свидетельствуют о том, что часть данных не помещается в shared_buffers.

3. Высокая интенсивность записи (DataFileWrite, SlruWrite) – возможно, из-за неэффективных контрольных точек или агрессивной фоновой записи.

4. Отсутствие репликации (max_replication_slots = 0, hot_standby = off) – не используется, но это не проблема.

Проблемы инфраструктуры

1. Острая нехватка оперативной памяти – свободная RAM <5% всё время, что вынуждает систему интенсивно использовать dirty pages и увеличивает давление на IO.

2. Постоянно высокий iowait (wa >10%) и число процессов в uninterruptible sleep (b) превышает ядра CPU – дисковая подсистема не справляется с нагрузкой.

3. Некорректная настройка параметров dirty_* на уровне ОС:

  • dirty_background_ratio = 10% при дефиците памяти может приводить к накоплению dirty pages до 30% (dirty_ratio) и блокировкам.
  • Корреляции dirty pages с b и sy подтверждают это.

4. Высокие накладные расходы ядра (sy) из-за управления грязными страницами и частых контекстных переключений.

Рекомендации

Рекомендации по настройкам СУБД

1. Оптимизировать запрос select scenario1():

  • Проанализировать его план выполнения (EXPLAIN ANALYZE).
  • Убедиться в наличии индексов для фильтрации и сортировки.
  • Рассмотреть возможность партиционирования больших таблиц.
  • Если запрос выполняет агрегацию, проверить настройки work_mem для избежания сбросов на диск.

2. Увеличить shared_buffers (до 2–2.5 GB, учитывая 7.5 GB RAM), чтобы больше данных помещалось в кэш.

3. Настроить контрольные точки:

  • Увеличить max_wal_size (например, до 4–5 GB), чтобы сгладить пики записи.
  • Увеличить checkpoint_timeout (до 20–30 мин) и проверить checkpoint_completion_target (0.9).

4. Оптимизировать фоновую запись:

  • Увеличить bgwriter_delay (например, 100–150 мс) и bgwriter_lru_maxpages, чтобы сгладить сброс грязных страниц.

5. Включить мониторинг pg_stat_bgwriter для отслеживанияbuffers_checkpoint, buffers_clean, buffers_backend.

6. Проверить и настроить autovacuum – текущие параметры выглядят адекватно, но убедиться, что он не создаёт лишней нагрузки.

Рекомендации по настройкам операционной системы

1. Снизить пороги dirty-страниц:

  • Уменьшить vm.dirty_background_ratio до 2–3% (сейчас 10%).
  • Уменьшить vm.dirty_ratio до 10–15% (сейчас 30%).
  • Альтернативно: использовать абсолютные значения vm.dirty_background_bytes и vm.dirty_bytes в зависимости от скорости диска.

2. Увеличить частоту фоновой записи:

  • Уменьшить vm.dirty_writeback_centisecs до 200–300 (сейчас 500) для более частого пробуждения flusher-нитей.

3. Добавить оперативной памяти – текущий дефицит является фундаментальной проблемой. Рекомендуется минимум 16 GB.

4. Проанализировать дисковую подсистему:

  • Замерить фактическую производительность дисков (iostat, fio).
  • Рассмотреть использование более быстрых дисков (NVMe/SSD) для /data и /wal.
  • Убедиться, что контроллер и шина не перегружены.

5. Пересмотреть параметры планировщика – для виртуальной среды оставить планировщик по умолчанию или использовать none/noop.

6. Мониторить и ограничить, если возможно, количество одновременных сессий – при max_connections=91 и нехватке памяти может возникать thrashing.

Заключение

Система находится в состоянии серьёзного кризиса производительности, вызванного недостатком оперативной памяти и перегрузкой дисковой подсистемы. Основной вклад вносит один проблемный запрос, генерирующий огромное количество операций ввода-вывода. Тренды указывают на быстрое ухудшение ситуации.

Критические точки:

  • Постоянная нехватка RAM.
  • Iowait >10% и блокировки процессов (b) > числа ядер CPU.
  • Неэффективная работа механизмов dirty page writeback на уровне ОС.

Для стабилизации работы необходимо:

1. Немедленно увеличить объём оперативной памяти или, как временная мера, оптимизировать потребление памяти приложением.

2. Настроить параметры vm.dirty_ для уменьшения накопления грязных страниц.

3. Оптимизировать запрос scenario1() и, возможно, пересмотреть его логику.

4. Увеличить shared_buffers и сгладить контрольные точки в PostgreSQL.

После выполнения этих мер следует повторно провести анализ ожиданий и корреляций для оценки эффективности изменений.

На основании текущих настроек PostgreSQL и выявленных проблем (высокая интенсивность записи, накопление dirty pages, корреляция с блокировками процессов) предлагаются следующие конкретные изменения параметров фонового писателя:

bgwriter_delay – увеличить с 54 мс до 100 мс.

Обоснование: текущее значение (54 мс) заставляет фоновый писатель пробуждаться слишком часто, что увеличивает количество контекстных переключений и создаёт лишнюю нагрузку на CPU. Увеличение задержки до 100 мс снизит частоту пробуждений, при этом сохранив достаточную оперативность сброса грязных страниц. Это особенно важно в условиях дефицита памяти и высокой активности записи, когда частые пробуждения не успевают обработать накопившиеся страницы и лишь добавляют служебных расходов.

bgwriter_lru_maxpages – увеличить с 515 до 1000.

Обоснование: текущий лимит 515 страниц за один цикл может быть недостаточным, учитывая объём грязных страниц (медиана dirty pages ~7 МБ, что при размере страницы 8 КБ соответствует ~900 страницам). Увеличение до 1000 позволит за одно пробуждение сбрасывать больше страниц, сглаживая пиковые нагрузки и уменьшая вероятность того, что сброс будет отложен до контрольной точки или вынужденной записи серверными процессами. Это должно снизить количество ситуаций, когда процессы блокируются в ожидании записи (состояние b).

bgwriter_lru_multiplier – рекомендуется снизить с 7.0 до 4.0–5.0.

Обоснование: коэффициент 7.0 означает, что при оценке количества страниц, которые нужно держать чистыми, фоновый писатель будет стремиться освободить в 7 раз больше буферов, чем было использовано с момента последнего цикла. В условиях ограниченной памяти это может приводить к излишне агрессивной записи и даже преждевременному вытеснению страниц, которые могли бы ещё пригодиться. Умеренное снижение коэффициента (до 4–5) позволит более плавно управлять буферным пулом, не создавая избыточного давления на диск.

После изменения этих параметров необходимо контролировать эффективность через представление pg_stat_bgwriter:

  • buffers_clean – количество страниц, записанных фоновым писателем.
  • buffers_backend – страницы, записанные серверными процессами (желательно, чтобы их доля была минимальной).
  • buffers_checkpoint – страницы, записанные во время контрольных точек.

Снижение доли buffers_backend и сглаживание пиков записи будут свидетельствовать о правильности настройки.