Серия «СУБД PostgreSQL»

1

PG_EXPECTO: правда о vm.swappiness и производительности PostgreSQL под нагрузкой

Серия СУБД PostgreSQL

Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).

Нейросеть советует, эксперимент доказывает: не всё, что логично — правильно

Нейросеть советует, эксперимент доказывает: не всё, что логично — правильно

Продолжение статьи :

PG_EXPECTO 5.1: Влияние vm.swappiness=1 на производительность PostgreSQL

Стандартные рекомендации по влиянию параметра vm.swappiness на производительность СУБД PostgreSQL

Для OLAP-нагрузок в PostgreSQL рекомендуется установить vm.swappiness=1, чтобы минимизировать обращения к медленному диску и обеспечить стабильную производительность при обработке больших данных. Это заставит ядро использовать своп только в крайнем случае, сохраняя рабочие данные в оперативной памяти.

1. Текущая конфигурация памяти:

  • RAM: 8 GB

  • shared_buffers: 4 GB (50% от RAM - правильно настроено)

  • work_mem: 32 MB (адекватно для 22 сессий)

  • Остаётся для ОС: ~3.5-4 GB (учитывая кэш файловой системы)

2. Рекомендация: swappiness = 1 (лучший выбор)

Почему именно 1:

  • PostgreSQL интенсивно использует файловый кэш - для SELECT-нагрузки это критично

  • shared_buffers уже содержит "горячие" данные в управляемой памяти

  • Низкое значение предотвращает вытеснение кэша страниц ОС в своп

  • При нехватке памяти PostgreSQL сам управляет своими буферами через shared_buffers

Экспериментальная проверка влияния vm.swappiness=1 на производительность СУБД

Операционная скорость

Изменение операционной скорости СУБД в ходе нагрузочного тестирования

Изменение операционной скорости СУБД в ходе нагрузочного тестирования

Среднее уменьшение операционной скорости в Эксперименте-2 (vm.swappiness = 1) составило 14.37%⚠️

Анализ причин снижения производительности СУБД PostgreSQL после применения vm.swappiness = 1

Рекомендация vm.swappiness=1 для PostgreSQL, которую часто дают нейросети и многие руководства, основана на общей логике: «меньше свопа — меньше обращений к диску — выше производительность». Однако эксперимент, описанный в статье «PG_EXPECTO 5.1: Влияние vm.swappiness=1 на производительность PostgreSQL», показывает, что в конкретных условиях эта настройка не дала ожидаемого эффекта. Вот ключевые причины, почему это произошло.

🔍 Суть эксперимента

  • Конфигурация: PostgreSQL 17, 8 ядер CPU, 8 ГБ RAM, shared_buffers=4 ГБ, нагрузка OLAP (аналитические запросы с большим объёмом чтения).

  • Сравнение: Производительность при vm.swappiness=10 и vm.swappiness=1.

  • Ожидание: Снижение своппинга должно уменьшить дисковый ввод-вывод и ускорить работу.

📊 Результаты

Диск - «узкое место»

Нагрузка на диск (/data) достигала 100% в обоих экспериментах.
Высокая очередь запросов (aqu_sz) и время ожидания CPU для IO (cpu_wa >50%) указывали на то, что производительность упиралась в диск, а не в память.

Система избегала своппинга

Даже при swappiness=10 ядро Linux предпочитало вытеснять файловый кэш, а не отправлять данные в своп. Поэтому изменение параметра почти не повлияло на поведение подсистемы памяти.

Минимальное влияние на метрики vmstat

Разница между swappiness=10 и swappiness=1 оказалась статистически незначимой: не было существенных изменений в IOPS или пропускной способности.
Небольшие улучшения (например, снижение w_await и глубины очереди) не решили основную проблему — перегруженность диска.

Общий результат

Проведенные эксперименты не подтвердили ожидаемого положительного влияния снижения параметра vm.swappiness на производительность PostgreSQL при интенсивной нагрузке с дефицитом оперативной памяти. Ключевым узким местом в обоих экспериментах стала производительность дисковой подсистемы.

🤔 Почему рекомендация нейросетей не подтвердилась?

Обобщённый характер рекомендаций

Нейросети (и многие руководства) опираются на общие принципы: «для OLAP-нагрузок снизьте swappiness, чтобы удержать данные в RAM». Однако они не учитывают конкретную конфигурацию и узкие места системы.

Условия эксперимента

Дисковая подсистема была перегружена (100% utilization), поэтому даже полное отключение свопа не могло улучшить общую производительность.
Нехватка RAM (8 ГБ при shared_buffers=4 ГБ) приводила к вытеснению файлового кэша, а не к активному своппингу. Из-за этого изменение swappiness практически не меняло картину.

Контекстная зависимость

Эффект от vm.swappiness проявляется только когда система активно использует своп. Если же система избегает своппинга (как в эксперименте) или узким местом является диск, то настройка не даёт заметного выигрыша.

💡 Практические выводы

Не доверяйте слепо общим рекомендациям (в том числе от нейросетей)

Проверяйте их в своей среде.

Диагностируйте узкие места перед тонкой настройкой

Мониторьте iostat, vmstat, pg_stat_activity.
Смотрите на %util, await, cpu_wa, aqu_sz.

Если диск перегружен, сначала оптимизируйте его

  • Используйте более быстрые диски (SSD/NVMe).

  • Необходима настройка effective_io_concurrency, random_page_cost.

  • Рассмотрите увеличение RAM для уменьшения нагрузки на диск.

vm.swappiness стоит снижать только когда

  • Наблюдается активный своппинг (si, so в vmstat).

  • Дисковая подсистема не является узким местом.

  • PostgreSQL работает с большим объёмом данных, которые должны оставаться в RAM.

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

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

Наклон линии регрессии скорости отрицательный в обоих случаях, но в Эксперименте-2 он круче (-26.99 против -23.65), что указывает на более быстрое снижение производительности.

Ожидания СУБД (WAITINGS)

Общий объем ожиданий и их рост во времени практически идентичны в обоих экспериментах (угол наклона ~43.6).
В обоих случаях ожидания почти полностью (коэффициент корреляции ~1.0) состоят из ожиданий ввода-вывода (IO).
Ключевое отличие: в Эксперименте-2 появилась умеренная корреляция ожиданий с IPC (0.86) и LWLock (0.86), которые в первом эксперименте были незначимы.

Типы ожиданий (Wait Events):

Основное событие ожидания в обоих случаях — DataFileRead (более 90% всех ожиданий типа IO).
В Эксперименте-2 дополнительно зафиксированы ожидания типов IPC (BufferIo) и LWLock (XidGen, BufferContent), что отсутствовало в первом эксперименте.

Подробный сравнительный анализ метрик vmstat и выводы по метрикам

procs_r (процессы в run queue)

Одинаково низкие значения (1-3) в обоих экспериментах. Очередь на выполнение не является проблемой.

procs_b (процессы в uninterruptible sleep)

Явная проблема в обоих случаях. Количество процессов, заблокированных в ожидании IO, стабильно растет на протяжении всего теста.
В Эксперименте-1 значение выросло с 5 до 16.
В Эксперименте-2 значение выросло с 5 до 14.
Более 40% наблюдений в обоих тестах — количество заблокированных процессов превышает число ядер CPU (8), что подтверждает серьезные проблемы с подсистемой IO.

memory_swpd (используемый объем свопа)

Эксперимент-1: Незначительный рост с ~220 до ~224 МБ.
Эксперимент-2: Заметный рост с ~205 до ~217 МБ. Хотя объем мал, тенденция к увеличению при swappiness=1 присутствует.

swap_si / swap_so (свопин/аут)

В обоих экспериментах равен 0. Активный свопинг не наблюдался.

memory_free (свободная RAM)

Критически низкий показатель в обоих экспериментах (~130 МБ из 7.5 ГБ, что составляет менее 2%).
100% наблюдений — свободной памяти менее 5%. Система работает на пределе доступной оперативной памяти.

memory_buff / memory_cache (буферы и кеш)

Стабильно высокие значения (кеш ~7 ГБ) в обоих тестах. ОС активно использует свободную память для кеширования дисковых операций, что является нормальным поведением.

io_bi / io_bo (блоки ввода/вывода)

Чрезвычайно высокие значения в обоих экспериментах (bi: с ~26k до ~32k; bo: с ~17k до ~20k).
Наблюдается очень сильная корреляция (>0.87) этих показателей с ожиданиями IO в СУБД. Это подтверждает, что СУБД является основным источником нагрузки на дисковую подсистему.

system_in / system_cs (прерывания / переключения контекста)

Значения стабильны и сопоставимы в обоих тестах. Существенных аномалий не выявлено.

cpu_us / cpu_sy / cpu_id / cpu_wa (распределение времени CPU)

  • cpu_wa (время ожидания IO): Основная проблема. В обоих экспериментах занимает 50-70% времени CPU, что указывает на то, что процессор простаивает в ожидании операций дискового ввода-вывода.

  • cpu_id (время простоя): Снижается с ~33% в начале до ~10-13% в конце тестов, так как процессор все больше времени ждет IO.

  • cpu_us / cpu_sy (пользовательское/системное время): Остаются стабильно низкими (11-12% / 4-5%), что означает отсутствие нагрузки на вычислительные ресурсы со стороны приложения или ядра ОС. CPU не является узким местом.

Ключевые отличия метрик vmstat, влияющих на итоговую производительность СУБД

Динамика memory_swpd

При vm.swappiness=1 наблюдается более выраженный рост использования области свопа (с 205 до 217 МБ), в то время как при значении 10 рост был минимальным (с 220 до 224 МБ). Это указывает на то, что даже при низком значении параметра система под давлением нехватки памяти была вынуждена начать использовать своп.

Уровень procs_b

В конце теста при swappiness=10 было зафиксировано 16 заблокированных процессов, а при swappiness=1 — 14. Хотя разница невелика, в сочетании с другими метриками это указывает на схожую, но несколько менее выраженную пиковую нагрузку на IO во втором эксперименте.

Анализ причин снижения производительности при vm.swappiness=1

Основная (общая) причина

В обоих экспериментах основная причина снижения производительности — критическая нехватка оперативной памяти для рабочего набора данных СУБД. Это приводит к:
Чрезмерной нагрузке на дисковую подсистему (очень высокие io_bi/io_bo, cpu_wa >50%).
Росту числа процессов, заблокированных на операциях ввода-вывода (procs_b).
Прямой зависимости скорости работы СУБД от скорости чтения с диска (корреляция speed и shared_blks_read >0.97).

Специфическое влияние vm.swappiness=1

Установка параметра в 1 должна минимизировать использование свопа. Однако при тотальной нехватке памяти система все равно была вынуждена начать использовать swpd, хотя и менее активно, чем при значении 10.


Более важное следствие: Жесткая политика удержания данных в RAM при ее катастрофической нехватке привела к усилению конкуренции за ресурсы памяти между процессами СУБД. Это выразилось в появлении в Эксперименте-2 дополнительных ожиданий, связанных с легковесными блокировками (LWLock) и межпроцессным взаимодействием (IPC), которые отсутствовали в первом тесте.
Данные блокировки являются внутренними для PostgreSQL и возникают при конкуренции за доступ к разделам общей памяти. Их появление свидетельствует о том, что нехватка памяти начала негативно влиять не только на IO, но и на внутреннюю координацию процессов СУБД.


Итог

При vm.swappiness=1 на фоне той же фундаментальной проблемы (нехватка RAM → лавина IO) дополнительно возникла внутренняя contention (конкуренция) в СУБД из-за борьбы за scarce (дефицитную) оперативную память. Это привело к более быстрому и глубокому падению операционной скорости (SPEED) по сравнению с Экспериментом-1, где система могла немного "разгрузить" RAM в своп, потенциально смягчая пиковое давление на shared buffers и внутренние структуры PostgreSQL.

⚖️ Почему swappiness=10 работал лучше

Более сбалансированный подход

При swappiness=10 система могла немного своппингуть неактивные фоновые процессы
Это сохраняло больше файлового кэша для активных операций PostgreSQL

Оптимизация под конкретную нагрузку

OLAP-запросы (70% SELECT) требуют много последовательных чтений
Файловый кэш ОС критически важен для повторных чтений одних и тех же данных
Сохранение этого кэша дало больше преимуществ, чем экономия на своппинге

📈 Основной итог экспериментов:

Нет универсальных настроек

То, что работает для OLTP, может вредить OLAP

Важен контекст bottlenecks:

Если узкое место - диск (как в эксперименте), сохраняйте кэш любой ценой
Если узкое место - память, можно снижать swappiness

Мониторинг обязателен

Без метрик vmstat и iostat нельзя понять реальный эффект

Послесловие

Главный вывод этого исследования прост: не существует универсальных настроек. Производительность PostgreSQL зависит от конкретной конфигурации, нагрузки и узких мест системы. Прежде чем применять рекомендации, проведите тесты в своей среде и опирайтесь на метрики, а не на советы из чатов.

Показать полностью 1
1

PG_EXPECTO 5.1: Влияние vm.swappiness=1 на производительность PostgreSQL

Серия СУБД PostgreSQL

Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).

Миф о swappiness: когда рекомендация не работает на практике.

Миф о swappiness: когда рекомендация не работает на практике.

Настоящее исследование посвящено экспериментальной проверке общепринятой рекомендации по снижению параметра vm.swappiness для серверов PostgreSQL . В ходе нагрузочного тестирования на синтетической рабочей нагрузке, имитирующей аналитические запросы, было оценено влияние значений vm.swappiness = 10 и vm.swappiness = 1 на производительность СУБД и инфраструктуры. Результаты выявили неожиданные закономерности, ставящие под сомнение универсальность данной рекомендации.

В статье представлены результаты нагрузочного тестирования PostgreSQL на синтетической рабочей нагрузке, имитирующей аналитические запросы (OLAP). Цель исследования: определить - как снижение параметра vm.swappiness влияет на взаимодействие СУБД с подсистемой ввода-вывода Linux.

Теоретическая часть

🎯 Влияние vm.swappiness на OLAP в PostgreSQL

Высокое значение (например, 60 по умолчанию):

  • Эффект: Ядро активно выгружает данные в своп, даже если физическая память не исчерпана.

  • Влияние на OLAP: Это может привести к "трешингу" (thrashing) — постоянному обмену данными между RAM и диском. Для OLAP-запросов, которые сканируют огромные наборы данных, это означает катастрофическое падение производительности, так как система тратит время на ввод-вывод, а не на обработку.

Низкое значение (например, 1-10):

  • Эффект: Ядро свопирует данные, только когда свободной оперативной памяти практически не осталось. Кэш PostgreSQL (например, shared_buffers) и данные для больших запросов с большей вероятностью останутся в быстрой RAM.

  • Влияние на OLAP: Это обеспечивает стабильность для длительных аналитических операций, минимизируя риск внезапных задержек из-за подкачки с диска. Однако слишком низкое значение (0) может привести к неожиданному завершению процесса (OOM Kill) при резком росте нагрузки.

⚙️ Рекомендации по настройке для OLAP

Для серверов PostgreSQL, ориентированных на OLAP-нагрузку, общепринятая рекомендация — снизить значение vm.swappiness.

  • Базовое значение: Установите vm.swappiness=1 для минимального использования свопа, но не полного его отключения.

  • Альтернатива: В некоторых продакшен-сценариях, особенно на системах с большим объемом RAM, используют значение vm.swappiness=10 как баланс между стабильностью и гибкостью.

  • Важное предупреждение: Значение 0 использовать не рекомендуется, так как это может дестабилизировать систему и спровоцировать агрессивное действие OOM Killer (механизма, который завершает процессы при нехватке памяти).

📝 Как применить настройку

Настройка производится через файл /etc/sysctl.conf (для постоянного изменения) или через интерфейс sysctl.

  1. Проверьте текущее значение: cat /proc/sys/vm/swappiness

  2. Измените значение (временно, до перезагрузки): sudo sysctl -w vm.swappiness=1

  3. Сделайте изменение постоянным. Добавьте или измените строку в файле /etc/sysctl.conf vm.swappiness=1

  4. После сохранения файла примените изменения: sudo sysctl -p /etc/sysctl.conf

🔍 Дополнительные соображения для OLAP

Настройка vm.swappiness — лишь одна часть оптимизации памяти для OLAP. Не менее важны:

  • Достаточный объем RAM: Ключевой фактор для OLAP. Данные должны помещаться в оперативную память для максимальной скорости.

  • Параметры PostgreSQL: Увеличьте shared_buffers (до 25-40% от RAM) для кэширования данных и work_mem для сложных сортировок и агрегаций.

  • Мониторинг: Следите за метриками swap in/out (например, через vmstat 1) и кэш-попаданий в PostgreSQL, чтобы убедиться в эффективности настроек.

💎 Итог

Для OLAP-нагрузок в PostgreSQL рекомендуется установить vm.swappiness=1, чтобы минимизировать обращения к медленному диску и обеспечить стабильную производительность при обработке больших данных. Это заставит ядро использовать своп только в крайнем случае, сохраняя рабочие данные в оперативной памяти.

Практическая часть: Экспериментальная проверка влияния vm.swappiness=1

Важное изменение в версии 5.1⚠️

Изменены тестовые сценарии scenario-2 и scenario-3.

Веса тестовых сценариев и параметры нагрузочного тестирования

# Веса сценариев по умолчанию

scenario1 = 0.7

scenario2 = 0.2

scenario3 = 0.1

Измененные параметры операционной системы ⚠️

1️⃣Общие параметры производительности

vm.dirty_ratio = 10

vm.dirty_background_ratio = 5

2️⃣Параметры IO-планировщика

[mq-deadline] kyber bfq none

3️⃣Настройки кэширования и буферизации

vm.vfs_cache_pressure = 50

4️⃣Оптимизация параметров файловой системы

/dev/mapper/vg_data-LG_data on /data type ext4 (rw,noatime,nodiratime)

5️⃣Изменение размера буферов для операций с блочными устройствами

read_ahead_kb = 256

Нагрузка на СУБД в ходе экспериментов

Изменение vm.swappiness

Текущее значение

# cat /proc/sys/vm/swappiness

10

Изменение значения

# sysctl -w vm.swappiness=1

vm.swappiness = 1

# vi /etc/sysctl.conf

vm.swappiness = 1

# sysctl -p /etc/sysctl.conf

vm.swappiness = 1

Контроль изменения

# cat /proc/sys/vm/swappiness

1

Эксперимент-1 ( vm.swappiness = 10 )

Эксперимент-2 (vm.swappiness = 1)

Корреляционный анализ производительности и ожиданий СУБД

Операционная скорость

Изменение операционной скорости СУБД в ходе нагрузочного тестирования

Изменение операционной скорости СУБД в ходе нагрузочного тестирования

Среднее уменьшение операционной скорости в Эксперименте-2 (vm.swappiness = 1) составило 14.37%

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

Изменение ожиданий СУБД в ходе нагрузочного тестирования

Изменение ожиданий СУБД в ходе нагрузочного тестирования

Среднее увеличение ожиданий в Эксперименте-2 (vm.swappiness = 1) составило 1.03%

Производительность подсистемы IO

Важно - главный предварительный итог

Изменение параметра vm.swappiness = 1 практически не оказывает влияния на метрики производительности подсистемы IO.

IOPS (Производительность IO)

Изменение производительности IO(IOPS) в ходе нагрузочного тестирования

Изменение производительности IO(IOPS) в ходе нагрузочного тестирования

Среднее уменьшение производительности IO в Эксперименте-2 (vm.swappiness = 1) составило 1.96%

MB/s (Пропускная способность IO)

Изменение пропускной способности IO(MB/s) в ходе нагрузочного тестирования

Изменение пропускной способности IO(MB/s) в ходе нагрузочного тестирования

Среднее уменьшение пропускной способности IO в Эксперименте-2 (vm.swappiness = 1) составило 7.16%

Сравнительный анализ производительности и ожиданий СУБД и метрик vmstat

Сравнительный отчет по результатам экспериментов с vm.swappiness

Цель анализа: Оценка влияния параметра vm.swappiness на производительность СУБД PostgreSQL и инфраструктуры при заданной нагрузке.

Контекст:

  • Эксперимент 1: vm.swappiness = 10

  • Эксперимент 2: vm.swappiness = 1

  • Характер нагрузки: Интенсивное чтение данных (OLAP-сценарий). Преобладают операции DataFileRead.

  • Конфигурация СУБД: Направлена на агрессивную автоочистку (autovacuum), высокий effective_io_concurrency, раздельные диски для данных и WAL.

  • Инфраструктура: 8 CPU, ~7.5 GB RAM, дисковая подсистема LVM.

Сравнение ключевых метрик производительности СУБД

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

  • Эксперимент 1: Начальная скорость выше (~611 850). Наблюдается выраженный отрицательный тренд (угол наклона -23.65). Скорость снижается на ~26% к концу теста.

  • Эксперимент 2: Начальная скорость ниже (~500 504). Отрицательный тренд также присутствует (угол наклона -26.99), но абсолютное падение скорости меньше (~7%).

  • Вывод: В условиях эксперимента снижение swappiness не привело к улучшению максимальной пропускной способности, однако общее относительное падение производительности под нагрузкой было менее выраженным.

Ожидания СУБД (WAITINGS):

  • Оба эксперимента демонстрируют:
    Сильный и стабильный рост ожиданий во времени (R² ~0.91, угол наклона ~43.6).
    Практически полную корреляцию общих ожиданий с ожиданиями типа IO (WAITINGS - IO = 1.000).
    80% и более всех ожиданий приходятся на операцию DataFileRead.

  • Ключевое различие:
    Эксперимент 1: Ожидания коррелируют с IPC (межпроцессное взаимодействие) и LOCK отрицательно или слабо.
    Эксперимент 2: Появилась заметная положительная корреляция ожиданий с IPC (0.86) и LWLOCK (0.86), что указывает на возросшую конкуренцию за легковесные блокировки и буферы в памяти.

Сравнение метрик инфраструктуры (vmstat) и их корреляция с СУБД

Загрузка CPU и очередь процессов:

  • Оба эксперимента:
    Нагрузка на CPU (us + sy) не является проблемой (низкие значения, нет превышения 80%).
    Очередь исполняемых процессов (procs_r) не превышает количество ядер CPU.
    Высокий процент времени ожидания ввода-вывода (cpu_wa): 50-71% в Эксперименте 1, 51-69% в Эксперименте 2.

  • Различия: Существенных различий в метриках CPU между экспериментами не выявлено.

Дисковый ввод-вывод (IO):

  • Оба эксперимента показывают идентичные проблемы:
    ALARM: Очень высокая корреляция ожиданий СУБД типа IO с cpu_wa (~0.94) и procs_b (~0.98). Это указывает, что процессы СУБД массово переходят в состояние непрерываемого сна (D) из-за ожидания ответа от диска.
    ALARM: Количество процессов в состоянии D (procs_b) стабильно растет и в пике превышает количество ядер CPU в 2 раза.
    ALARM: Соотношение читаемых блоков к записываемым высокое (>2.7), что подтверждает read-intensive (OLAP) характер нагрузки.
    ALARM: Прямая сильная корреляция операционной скорости СУБД с количеством прочитанных с диска блоков (~0.97). Производительность напрямую упирается в скорость чтения с диска.

  • Вывод: Параметр swappiness не оказал влияния на профиль и тяжесть проблем с дисковым IO. Система упирается в пределы производительности дисковой подсистемы.

Память (RAM):

  • Общая картина в обоих экспериментах:
    ALARM: Свободная оперативная память (memory_free) практически отсутствует (<5% на протяжении >50% наблюдений).
    OK: Своппинг (swap_si, swap_so) не использовался, несмотря на нехватку свободной RAM.
    Значительный объем памяти используется для кэша файловой системы (memory_cache >7 GB).

  • Ключевой вывод: Даже при swappiness=10 система не прибегала к своппингу. Нехватка свободной RAM, по всей видимости, компенсировалась активным вытеснением файлового кэша, что усугубляло проблему с дисковым IO, заставляя чаще читать данные с диска.

Итоговый вывод о влиянии vm.swappiness

Для данной конкретной конфигурации (8 CPU, 7.5 GB RAM) и предоставленного характера нагрузки (интенсивное чтение, вызывающее дефицит свободной оперативной памяти):

  1. Отсутствие влияния на своппинг: Изменение параметра vm.swappiness с 10 на 1 не привело к качественному изменению поведения системы. В обоих случаях система предпочла не использовать раздел подкачки, даже в условиях хронической нехватки свободной оперативной памяти.

  2. Несущественное влияние на производительность СУБД: Не было зафиксировано значимого улучшения или ухудшения итоговой операционной скорости (SPEED) СУБД. Основная проблема производительности в обоих экспериментах была одинакова и заключалась в дисковом вводе-выводе, который стал узким местом.

  3. Изменение профиля конкуренции: Снижение swappiness до 1 привело к появлению статистически значимой корреляции ожиданий СУБД с IPC и LWLOCK. Это косвенно свидетельствует о том, что при более жестком ограничении на использование свопа процессы СУБД активнее конкурировали за структуры данных в оперативной памяти (буферы, легковесные блокировки), однако это не стало новым узким местом по сравнению с дисковым IO.

Общий вывод:

В рамках проведенных экспериментов с интенсивной нагрузкой, вызывающей дефицит оперативной памяти, параметр vm.swappiness не оказал решающего влияния на общую производительность системы и СУБД PostgreSQL. Основным лимитирующим фактором в обоих случаях была производительность дисковой подсистемы. Система в обоих конфигурациях избегала своппинга, выбирая стратегию вытеснения файлового кэша, что лишь усиливало нагрузку на диски. Изменения в поведении СУБД были минимальны и не повлияли на ключевую проблему производительности.

Анализ производительности IO для файловой системы /data

Сравнительный отчет по производительности подсистемы IO для файловой системы /data

Общая характеристика системы

  • Аппаратная конфигурация:
    CPU: 8 ядер (x86_64)
    RAM: 7.5 GB
    Диск для /data: vdd → vg_data-LG_data (99 GB LVM)

Критические проблемы производительности по файловой системе /data

  • Загрузка диска (utilization): 100% в 100% наблюдений в обоих экспериментах

  • Очередь запросов (aqu_sz): постоянно превышает 1 (100% наблюдений)

  • Ожидание CPU для IO (cpu_wa): стабильно >50% (в 100% наблюдений)

  • Процессы в состоянии ожидания IO (proc_b): регулярно превышают количество ядер CPU (25-50% наблюдений)

  • Соотношение чтения/записи: ~2.9:1 (OLAP-сценарий)

Анализ корреляций и паттернов нагрузки по файловой системе /data

  • Высокая корреляция cpu_wa и util: 0.94 (Эксп.1) и 0.87 (Эксп.2) — процессы ждут диск

  • Отрицательная корреляция cache с операциями чтения/записи: эффективное использование кэша

  • Высокая корреляция скорости операций с shared_blks_read: 0.97 — производительность напрямую зависит от чтения с диска

  • Слабые/отрицательные корреляции с IOPS и MB/s: производительность не ограничена пропускной способностью или IOPS

Диагностика узких мест IO по файловой системе /data

Сравнение метрик между экспериментами:

  • r_await(ms):
    Эксп.1: 1-5 мс (MIN: 1.47, MAX: 5.12)
    Эксп.2: 1-6 мс (MIN: 1.47, MAX: 5.68)
    Изменение: незначительное увеличение максимума во втором эксперименте

  • w_await(ms):
    Эксп.1: 1-15 мс (MIN: 1.63, MAX: 14.91)
    Эксп.2: 1-5 мс (MIN: 1.63, MAX: 4.49)
    Изменение: значительное улучшение во втором эксперименте

  • aqu_sz (глубина очереди):
    Эксп.1: 6-38 (MIN: 6.07, MAX: 38.36)
    Эксп.2: 6-30 (MIN: 6.07, MAX: 29.88)
    Изменение: снижение максимальной глубины очереди

  • proc_b (процессы в uninterruptible sleep):
    Оба эксперимента: регулярно превышают количество ядер CPU
    Эксп.1: 42.99% наблюдений с превышением
    Эксп.2: 42.73% наблюдений с превышением
    Изменение: минимальное улучшение

  • cpu_wa(%) (время ожидания CPU для IO):
    Эксп.1: 50-71%
    Эксп.2: 51-69%
    Изменение: незначительное снижение диапазона

  • Корреляция speed с IOPS:
    Эксп.1: -0.7012 (отрицательная)
    Эксп.2: -0.7442 (отрицательная)
    Изменение: усиление отрицательной корреляции

  • Корреляция speed с пропускной способностью (MB/s):
    Эксп.1: -0.8707 (отрицательная)
    Эксп.2: -0.7820 (отрицательная)
    Изменение: ослабление отрицательной корреляции

Вывод по диагностике узких мест IO:

  • Диск /data является узким местом в обоих экспериментах

  • Высокая загрузка диска (100%) приводит к образованию очереди запросов

  • Процессы проводят значительное время в ожидании IO (cpu_wa >50%)

  • Характер нагрузки: OLAP с преобладанием операций чтения

  • Проблема не в пропускной способности диска или IOPS

Итоговый вывод о влиянии параметра vm.swappiness

  • Минимальное влияние на ключевые метрики: изменение vm.swappiness с 10 на 1 не привело к существенному изменению производительности подсистемы IO

  • Незначительные улучшения во втором эксперименте:
    Снижение максимального времени ожидания записи (w_await)
    Уменьшение максимальной глубины очереди запросов (aqu_sz)
    Небольшое снижение времени ожидания CPU для IO (cpu_wa)

  • Проблема перегруженности диска сохраняется: в обоих экспериментах наблюдается 100% загрузка диска и высокая очередь запросов

  • Характер нагрузки определяет производительность: сценарий с высоким соотношением чтения/записи создает устойчивую нагрузку на диск, которая не может быть компенсирована настройками swappiness в данных условиях

  • Результат согласуется с анализом корреляций: в обоих экспериментах выявлено, что узкое место не в IOPS или пропускной способности, а в самой загрузке диска, что делает изменение vm.swappiness неэффективным для решения основной проблемы

Итог

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

Основные выводы:

  • Изменение параметра не привело к качественному изменению поведения подсистемы памяти: система в обоих случаях избегала своппинга, предпочитая вытеснять файловый кэш.

  • Не было зафиксировано значимого улучшения или ухудшения итоговой операционной скорости СУБД. Ключевым узким местом в обоих экспериментах стала производительность дисковой подсистемы.

  • Снижение vm.swappiness до 1 привело лишь к косвенному изменению профиля конкуренции за ресурсы в памяти, но это не повлияло на общую картину производительности, ограниченную вводом-выводом.

  • Для подсистемы IO изменение параметра также не оказало существенного влияния: проблема 100% загрузки диска и высокой очереди запросов сохранилась при обоих значениях.

Общий вывод:

В условиях конкретной тестовой конфигурации (интенсивное чтение, нехватка RAM, ограниченная дисковая производительность) рекомендация по снижению vm.swappiness для оптимизации нагрузки в PostgreSQL не нашла экспериментального подтверждения. Производительность системы определялась другими факторами.

Показать полностью 8
2

Эксперимент pg_expecto 5.1: как параметр shared_buffers перераспределяет узкие места системы

Серия СУБД PostgreSQL

Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).

Баланс: память против ввода-вывода

Баланс: память против ввода-вывода

От дисковых ожиданий к кэшированию: как shared_buffers меняет игру.

Данный отчёт суммирует результаты сравнительного нагрузочного тестирования СУБД PostgreSQL с использованием комплекса pg_expecto 5.1. Целью экспериментов была объективная оценка влияния ключевого параметра памяти — shared_buffers — на производительность базы данных и метрики инфраструктуры, в первую очередь подсистемы ввода-вывода. Тестирование имитировало смешанную OLAP-нагрузку с преобладанием операций чтения на идентичных конфигурациях, где единственной переменной был размер буферного кэша (1 ГБ в первом эксперименте и 4 ГБ во втором).

Задача

Провести сравнительный анализ влияния размера shared_buffers на производительность СУБД PostgreSQL и подсистемы IO для версии pg_expecto 5.1.

Важное изменение в версии 5.1⚠️

Изменены тестовые сценарии scenario-2(INSERT) и scenario-3(UPDATE).

Веса тестовых сценариев и параметры нагрузочного тестирования

# Веса сценариев по умолчанию

scenario1 = 0.7

scenario2 = 0.2

scenario3 = 0.1

Измененные параметры операционной системы для оптимизации⚠️

1️⃣Общие параметры производительности

vm.dirty_ratio = 10

vm.dirty_background_ratio = 5

2️⃣Параметры IO-планировщика

[mq-deadline] kyber bfq none

3️⃣Настройки кэширования и буферизации

vm.vfs_cache_pressure = 50

4️⃣Оптимизация параметров файловой системы

/dev/mapper/vg_data-LG_data on /data type ext4 (rw,noatime,nodiratime)

5️⃣Изменение размера буферов для операций с блочными устройствами

read_ahead_kb = 256

Нагрузка на СУБД в ходе экспериментов

Корреляционный анализ производительности и ожиданий СУБД

Операционная скорость

Изменение операционной скорости СУБД в ходе нагрузочного тестирования

Изменение операционной скорости СУБД в ходе нагрузочного тестирования

Среднее увеличение операционной скорости в Эксперименте-2 (shared_buffers=4GB) составило 70.76%

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

Изменение ожиданий СУБД в ходе нагрузочного тестирования

Изменение ожиданий СУБД в ходе нагрузочного тестирования

Среднее уменьшение ожиданий в Эксперименте-2 (shared_buffers=4GB) составило 12.97%

Производительность подсистемы IO

IOPS (Производительность IO)

Изменение производительности IO(IOPS) в ходе нагрузочного тестирования

Изменение производительности IO(IOPS) в ходе нагрузочного тестирования

Среднее увеличение производительности IO в Эксперименте-2 (shared_buffers=4GB) составило 4.28%

MB/s (Пропуская способность IO)

Изменение пропуской способности IO(MB/s) в ходе нагрузочного тестирования

Изменение пропуской способности IO(MB/s) в ходе нагрузочного тестирования

Среднее уменьшение пропускной способности IO в Эксперименте-2 (shared_buffers=4GB) составило 5.23%

Итоговый вывод о влиянии shared_buffers

Для производительности СУБД:

  • Увеличение shared_buffers с 1GB до 4GB привело к значительному росту операционной скорости (до +63.4% в пике)

  • Минимальная производительность улучшилась на 39.5%

  • Изменилась динамика производительности: с положительного тренда на отрицательный при увеличении нагрузки

  • Преобразовало зависимость между скоростью и ожиданиями с прямой на обратную

Для инфраструктуры:

  • Снизило процент времени, когда процессы в состоянии D превышали количество ядер CPU (с 56.48% до 42.99%)

  • Не устранило проблему высокой корреляции между ожиданиями IO и метриками wa/b

  • Не повлияло на использование оперативной памяти (в обоих случаях активно используется)

Для характера нагрузки (OLAP-сценарий):

  • Уменьшило общее количество операций чтения с диска на 11.6%

  • Изменило распределение ожиданий между основными запросами

  • Преобразовало зависимость производительности от операций записи с прямой на обратную

Общий эффект

Параметр shared_buffers = 4GB показал существенно лучшие результаты для данной конфигурации и характера нагрузки, позволив эффективнее кэшировать данные в памяти и снизив зависимость производительности от операций ввода-вывода, что особенно критично для OLAP-сценариев с преобладанием операций чтения.

Увеличение параметра shared_buffers с 1 ГБ до 4 ГБ привело к значительному качественному изменению в поведении системы под нагрузкой.

  • Для СУБД: Производительность (операционная скорость) выросла на 39.5–63.4%, а зависимость между скоростью и ожиданиями ввода-вывода трансформировалась с прямой на обратную. Количество обращений к диску для чтения сократилось на 11.6%.

  • Для инфраструктуры: Нагрузка на подсистему ввода-вывода осталась критически высокой, однако уменьшилось количество процессов, блокированных в ожидании диска, и улучшилось среднее время отклика на операции чтения (r_await).

  • Общий эффект: Более крупный буферный кэш эффективнее обслуживал OLAP-составляющую нагрузки, кэшируя данные и снижая давление на диск. Это сместило узкие места системы: если при shared_buffers=1GB производительность жёстко зависела от характеристик диска (IOPS и пропускной способности), то при shared_buffers=4GB эта зависимость ослабла, хотя диск по-прежнему оставался полностью загруженным.

Показать полностью 8
1

Контроль vs. Автоматизация: как меняются роли DBA и разработчиков с приходом нейросетей

Серия СУБД PostgreSQL
Мощный инструмент в руках того, кто знает архитектуру.

Мощный инструмент в руках того, кто знает архитектуру.

Предисловие

Нейросети стремительно входят в повседневную практику разработчиков и администраторов баз данных, обещая революцию в оптимизации и автоматизации. Но насколько можно доверять их рекомендациям в сложных, высоконагруженных системах? На основе актуальных экспериментов 2025-2026 годов мы разбираем, как ИИ меняет работу с PostgreSQL, где он действительно полезен, а где его «категоричные» советы приводят к падению производительности на сотни процентов. Это не статья о страхах, а руководство по эффективному и безопасному использованию нового инструментария.

Нейросети по-разному меняют работу разработчиков и администраторов PostgreSQL, создавая как возможности, так и риски.

🎯 Сравнение ключевых изменений

Для администраторов PostgreSQL

  • Автоматизация: Ассистенты в платформах (Tantor) помогают с мониторингом, алертами и профилированием запросов. ИИ может предлагать настройки, но в актуальных экспериментах (2025 г.) нейросети давали опасные рекомендации по оптимизации, снижая производительность до 288% из-за игнорирования динамической нагрузки.

  • Новые возможности: Ассистенты помогают интерпретировать планы запросов и ошибки, а модули автоматической анонимизации данных упрощают работу.

  • Риски и ограничения: В ядре PostgreSQL (на 2026 г.) отсутствуют встроенные адаптивные оптимизаторы на нейросетях. Есть только GEQO (генетический алгоритм). Рекомендации нейросетей могут быть неверны, особенно в условиях высокой параллельной нагрузки и конкуренции за ресурсы, требуя обязательной ручной верификации.

  • Изменение навыков: Навыки глубокого анализа планов запросов, системного мониторинга и понимания конкуренции за ресурсы становятся критически важными.

Для разработчиков

  • Автоматизация: Нейросети могут ускорять написание рутинных SQL-запросов и генерировать код по описанию.

  • Новые возможности: Появляется возможность разрабатывать расширения PostgreSQL для прямой интеграции машинного обучения (например, для классификации изображений), создавать системы, где нейросеть обучается на данных из БД.

  • Риски и ограничения: Сгенерированный ИИ код и архитектурные решения могут быть неоптимальными или небезопасными, требуют тщательной проверки.

  • Изменение навыков: Растет спрос на навыки интеграции ML/ИИ с СУБД, работы с векторными данными и специализированными индексами, проектирования гибридных систем.

💡 Основные выводы

  • Администратор остается контролером: Нейросети становятся мощными, но требующими строгого контроля инструментами. Роль эксперта, который ставит задачу, верифицирует результат и принимает ответственные решения, усиливается.

  • Разработчик становится интегратором: ИИ открывает новые горизонты для создания умных приложений и интеграции с базами данных, смещая фокус с рутинного кодинга на проектирование сложных систем.

  • Общая черта: Для обеих профессий критически важными остаются фундаментальные знания архитектуры PostgreSQL, принципов работы с данными и умение критически оценивать рекомендации любых автоматизированных систем.

В экспериментах нейросети выдавали категоричные рекомендации по оптимизации PostgreSQL, но в условиях высокой параллельной нагрузки (от 15 до 22 одновременных сессий) эти советы приводили к деградации производительности.

Основная причина ошибок — неспособность нейросетей моделировать динамическое поведение СУБД.

🧪 Детальный разбор ключевых кейсов

Вот два основных эксперимента, демонстрирующих системные ошибки нейросетей.

Кейс 1: JOIN против коррелированного подзапроса

  • Рекомендация нейросети: Единогласно советовали использовать JOIN, утверждая, что коррелированные подзапросы — плохая практика при высокой конкуренции.

  • Результат теста: Запрос с коррелированным подзапросом оказался в среднем на 288% быстрее, чем версия с JOIN.

  • Причина ошибки: Нейросеть проанализировала только план запроса для одной сессии. Она не учла, что при 20 параллельных соединениях:
    20 сессий × JOIN = 20 полных сканирований (Seq Scan) одной и той же таблицы orders, что вызывает острую конкуренцию (contention) за доступ к буферному кэшу и диску.
    20 сессий × Подзапрос = 500 точечных обращений к индексу (Bitmap Index Scan), что равномерно распределяет нагрузку.

Кейс 2: Index Only Scan против Bitmap Index Scan

  • Рекомендация нейросети: Рекомендовали создать покрывающий индекс для перехода на Index Only Scan, прогнозируя оптимальную производительность.

  • Результат теста: Результат был неоднозначным. Под нагрузкой до 15 сессий производительность с покрывающим индексом была ниже на 7%. Преимущество в 22% появлялось только при дальнейшем росте нагрузки.

  • Причина ошибки: Нейросеть основывалась на статической модели, игнорируя динамику работы СУБД:
    Игнорирование конкуренции за индекс: При высокой параллельности Index Only Scan сталкивается с блокировками страниц индекса (B-дерева), чего не происходит при Bitmap Index Scan.
    Неучет эффекта кэширования: Модель не смогла предсказать, что данные для Seq Scan могут полностью помещаться в оперативной памяти (shared_buffers), сводя на нет его главный недостаток — физический ввод-вывод.

🔍 Системные ограничения нейросетей

Эти кейсы выявили фундаментальные пробелы в подходе нейросетей к оптимизации баз данных:

  • Статичность моделей: Нейросети анализируют моментальный снимок системы, не учитывая временные аспекты (прогрев БД, изменение нагрузки).

  • Непонимание конкуренции за ресурсы: Модели не способны адекватно предсказать поведение системы при одновременном доступе множества процессов к одним данным (lock contention).

  • Опора на общие эвристики: Вместо анализа конкретных планов выполнения и метрик, нейросети часто выдают универсальные советы вроде «JOIN всегда эффективнее».

💎 Практические выводы для администраторов и разработчиков

  1. Обязательная верификация: Любую рекомендацию по оптимизации (от нейросети или человека) необходимо проверять нагрузочным тестированием, максимально приближенным к боевым условиям.

  2. Критическое мышление важнее совета: Глубокое понимание архитектуры PostgreSQL (планы запросов, блокировки, работа с памятью) становится ценнее, чем умение сформулировать запрос к ИИ.

  3. Нейросеть — помощник, а не замена: Нейросети полезны для первичного анализа или генерации шаблонного кода, но не могут заменить экспертизу и системное мышление инженера.

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

Итог

Нейросети становятся мощными ассистентами, беря на себя рутину и открывая новые горизонты для интеграции машинного обучения с СУБД. Однако эксперименты доказывают их ключевое системное ограничение: неспособность адекватно моделировать динамику работы PostgreSQL под конкурентной нагрузкой, что приводит к опасным рекомендациям по оптимизации.

Это усиливает, а не отменяет роль эксперта.

Администратор становится главным контролером и верификатором, чьи глубокие знания архитектуры СУБД критически важны.

Разработчик превращается в интегратора сложных гибридных систем. Для обоих навык критического мышления и фундаментальное понимание работы PostgreSQL остаются безальтернативной основой для принятия решений.

Показать полностью
3

PG_EXPECTO : тонкая настройка RAM и ядра для PostgreSQL

Серия СУБД PostgreSQL

Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).

От стабильности к скорости: каждый байт на счету

От стабильности к скорости: каждый байт на счету

Настройка параметров памяти и ядра — критически важный этап развёртывания PostgreSQL в продуктивной среде. Неправильные значения могут привести не только к снижению производительности, но и к невозможности запуска СУБД или аварийным завершениям под нагрузкой. В этом материале систематизированы параметры от критически важных до оптимизационных, а также приведена методика расчёта ключевых настроек PostgreSQL.

Влияние параметров настройки RAM на производительность PostgreSQL

🥇 Критическая важность (влияние на запуск и стабильность)

Эти параметры — обязательный минимум. При неверной настройке PostgreSQL либо не запустится, либо будет аварийно завершаться под нагрузкой.

1. Параметры разделяемой памяти (Shared Memory)
Используются для общего буферного кэша (shared_buffers) и взаимодействия процессов.

  • kernel.shmmax: Максимальный размер одного сегмента разделяемой памяти. Должен быть не меньше значения shared_buffers в Postgres.

  • kernel.shmall: Общий объем разделяемой памяти в системе. Должен быть достаточным для всех сегментов.

  • Последствия ошибки: FATAL: could not create shared memory segment — сервер не запустится.

2. Параметры семафоров (Semaphores)
Координируют доступ множества процессов PostgreSQL к общим ресурсам и блокировкам.

  • kernel.sem: Комплексный параметр, определяющий лимиты семафоров. Ключевые значения:
    SEMMNS: Общее количество семафоров в системе.
    SEMMNI: Максимальное количество наборов семафоров.

  • Как рассчитать: Требуемое количество зависит от max_connections, max_worker_processes и других параметров. Узнать его можно командой postgres -D $PGDATA -C num_os_semaphores.

  • Последствия ошибки: No space left on device при вызове semget, отказ в новых подключениях, блокировки.

🥈 Высокая важность (влияние на отзывчивость и пропускную способность)

Неправильная настройка этих параметров не помешает запуску, но вызовет серьезные проблемы с производительностью.

3. vm.swappiness (склонность к свопингу)
Определяет, как часто ядро будет перемещать страницы памяти из ОЗУ на диск (своп). Для сервера БД это почти всегда вредно.

  • Рекомендация: Установить значение 1 (минимальная склонность к свопу) вместо стандартных 60. Это резервирует свопинг для крайних случаев, удерживая рабочую нагрузку Postgres в оперативной памяти.

4. Параметры "грязных" страниц (vm.dirty_*)
Контролируют, как часто измененные (грязные) данные в памяти записываются на диск.

  • vm.dirty_background_ratio: Процент памяти, при заполнении которым фоновые процессы начинают асинхронную запись на диск. Рекомендуется 5%.

  • vm.dirty_ratio: Процент памяти, при достижении которого новые операции будут блокироваться до освобождения места синхронной записью. Рекомендуется 10%.

  • Зачем настраивать: Сглаживает пики ввода-вывода, предотвращая внезапные блокировки всех процессов при заполнении буферов.

🥉 Средняя важность (оптимизация для конкретных сценариев и нагрузок)

Эти настройки дают измеримый прирост в определенных условиях.

5. Большие страницы (Huge Pages)
Уменьшают накладные расходы ядра на управление памятью (TLB-кешем), что может ускорить работу с большим объемом shared_buffers.

  • Как включить:
    Рассчитать необходимое количество страниц, исходя из потребляемой памяти процессом Postgres.
    Установить vm.nr_hugepages через sysctl.
    В postgresql.conf задать huge_pages = on (или try).

  • Важно: Может затруднить выделение памяти при недостатке огромных страниц. Требует предварительного планирования.

6. Политика overcommit памяти (vm.overcommit_*)
Определяет, насколько агрессивно ядро будет выделять память по запросам процессов.

  • vm.overcommit_memory: Для рабочих нагрузок с высокой параллельностью (например, как в Greenplum на базе Postgres) часто рекомендуется значение 2, которое строже проверяет доступную память.

  • vm.overcommit_ratio: Процент физической RAM, доступной для overcommit. Рассчитывается индивидуально.

  • Внимание: Настройка этих параметров требует глубокого понимания нагрузки и доступных ресурсов (RAM + swap). Неправильные значения приведут к Out of Memory и убийству процессов.

💎 Резюме и рекомендации по настройке

  1. Проверка текущих значений: sysctl -a | grep -i <параметр> и ipcs -l.

  2. Настройка параметров:
    Для применения до перезагрузки: sudo sysctl -w <параметр>=<значение>.
    Для постоянного изменения: /etc/sysctl.conf.

  3. Последовательность настройки: Начните с критически важных параметров (shmmax, shmall, sem), затем перейдите к параметрам производительности (swappiness, dirty_*). Большие страницы и overcommit настраивайте только при наличии конкретной необходимости и понимания поведения вашей системы.

  4. Перезагрузка или рестарт служб: Большинство изменений требует перезагрузки сервера или, как минимум, перезапуска PostgreSQL для применения.

Настройка параметров ядра — фундамент. Для дальнейшей оптимизации обратите внимание на внутренние параметры памяти самого PostgreSQL, такие как shared_buffers, work_mem и effective_cache_size.

Общая методика расчета значений shared_buffers и work_mem

Для расчета shared_buffers и work_mem в PostgreSQL универсальной формулы нет. Оптимальные значения зависят от типа нагрузки (OLTP, OLAP, смешанная), количества подключений и доступной RAM. Методика состоит из стартовых расчетов и последующей тонкой настройки на основе мониторинга.

1. Общие принципы и баланс памяти

  • Общее правило: Общий объем памяти, выделяемый PostgreSQL (shared_buffers + work_mem * max_connections + прочие буферы), не должен превышать 90% от доступной оперативной памяти. Оставшиеся 10-15% необходимы для операционной системы, дискового кэша и других процессов.

  • Приоритет для OLTP (много одновременных коротких транзакций, чтение/запись): акцент на shared_buffers.

  • Приоритет для OLAP (сложные аналитические запросы, большие сортировки, агрегации): акцент на work_mem.

2. Методика расчета shared_buffers

Это главный кэш данных PostgreSQL для буферов таблиц и индексов.

  • Стартовое значение (общее правило): 25% от объема доступной RAM.
    Для сервера с 64 ГБ RAM: 64 ГБ * 0.25 = 16 ГБ.
    Максимальный практический предел: 40% от RAM (для очень больших машин). Установка выше 8-10 ГБ редко дает линейный прирост производительности, так как ОС эффективно использует оставшуюся память для дискового кэша (Page Cache).

  • Уточнение в зависимости от нагрузки:
    OLTP (высокий параллелизм, частое чтение): Можно поднять до 30-35% от RAM.
    OLAP (большие последовательные сканирования): Оставить около 15-20% от RAM. Большие последовательные чтения часто минуют shared_buffers, эффективнее полагаться на кэш ОС.
    Смешанная нагрузка: Начать с 25% и корректировать по мониторингу.

3. Методика расчета work_mem

Эта память выделяется на операцию (сортировка, хэш-соединение, агрегация) в рамках одного запроса. Один сложный запрос может использовать work_mem многократно.

  • Ключевое ограничение: work_mem * max_connections — это потенциальный пиковый расход, а не гарантированное выделение. Расчет должен быть консервативным.

  • Стартовая формула: work_mem = (Доступная RAM для Postgres - shared_buffers) / (max_connections * 2)
    Доступная RAM для Postgres: Например, 90% от общего объема RAM.
    Делитель на 2-4: Предполагает, что не все подключения одновременно выполняют тяжелые операции, требующие полного объема work_mem.

  • Пример расчета для сервера с 64 ГБ RAM:
    RAM для Postgres: 64 ГБ * 0.9 ≈ 58 ГБ.
    shared_buffers: 64 ГБ * 0.25 = 16 ГБ.
    max_connections (например): 100.
    work_mem = (58 ГБ - 16 ГБ) / (100 * 2) = 42 ГБ / 200 ≈ 215 МБ.

  • Уточнение по типу нагрузки:
    OLAP (сложные запросы): Увеличивайте work_mem, чтобы тяжелые сортировки выполнялись в памяти, а не на диск. Возможно, потребуется снизить max_connections для баланса.
    OLTP (простые запросы): Значение может быть значительно меньше (например, 4-64 МБ).

Резюме: пошаговый алгоритм

  1. Рассчитать shared_buffers как 25% от RAM.

  2. Оценить доступную для Postgres RAM (обычно 90% от общего объема).

  3. Рассчитать стартовое work_mem по формуле: (RAM_for_Postgres - shared_buffers) / (max_connections * 2).

  4. Мониторинг: pg_stat_bgwriter, pg_stat_statements, общий мониторинг ОС (своп, использование RAM).

  5. Скорректировать shared_buffers в сторону увеличения, если низкий cache hit ratio.

  6. Выявлять "прожорливые" запросы по временным файлам и оптимизируйте их (индексы, переписывание) или точечно увеличивайте для них work_mem.

Эта методика даст научно обоснованную стартовую точку для настройки. Итоговые оптимальные значения всегда определяются эмпирически под конкретную нагрузку.

Итог

Правильная настройка памяти для PostgreSQL включает три уровня:

  1. Критически важные параметры ядра (shared memory, semaphores) — без них СУБД не запустится.

  2. Параметры производительности (swappiness, dirty pages) — влияют на отзывчивость и стабильность под нагрузкой.

  3. Оптимизационные настройки (huge pages, overcommit) — дают прирост в специфических сценариях.

Расчёт shared_buffers и work_mem основан на типе нагрузки (OLTP/OLAP), доступной RAM и количестве подключений, требует стартовых вычислений и последующего мониторинга.

Показать полностью 1
5

После VACUUM FULL нужно выполнять VACUUM

Серия СУБД PostgreSQL

После выполнения VACUUM FULL необходимо выполнить обычный VACUUM для обновления карты видимости (visibility map, VM), поскольку VACUUM FULL не обновляет флаги ALL_VISIBLE и ALL_FROZEN в карте видимости, несмотря на то, что он перезаписывает таблицу и замораживает кортежи.

Обоснование:

  • ‼️VACUUM FULL перезаписывает таблицу в новый файл, удаляя мёртвые кортежи и замораживая оставшиеся. Однако ‼️он не устанавливает флаги видимости в VM‼️, потому что не может гарантировать, что все кортежи на странице видимы для всех транзакций (например, из-за параллельных операций или не завершённых транзакций).

  • ➡️Карта видимости (VM) используется для оптимизации ⚠️index-only scans⚠️ и снижения нагрузки при последующих операциях VACUUM. Если флаг ALL_VISIBLE не установлен, PostgreSQL не может пропускать проверку видимости кортежей при сканировании индекса, что снижает производительность.

  • ➡️Флаги pg_class.relallvisible и pg_class.relfrozenxid также не обновляются после VACUUM FULL, что ⚠️влияет на планировщик запросов⚠️ и управление wraparound-защитой.

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

После VACUUM FULL выполните:

VACUUM your_table_name;

Это обновит карту видимости, установит флаги ALL_VISIBLE и ALL_FROZEN на страницах, где это возможно, и восстановит оптимальную производительность индексных сканирований.

Дополнительно:

ℹ️Используйте pg_visibility для проверки состояния карты видимости:

  • SELECT * FROM pg_visibility_map('your_table_name');

В большинстве случаев VACUUM FULL не рекомендуется — используйте обычный VACUUM или CLUSTER, если требуется перестроение таблицы.

Показать полностью
2

PG_EXPECTO + PGPRO_PWR : Синергия мониторинга и анализа: новые возможности диагностики и оптимизации СУБД

Серия СУБД PostgreSQL

Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).

От ожиданий — к ожидаемым результатам.

От ожиданий — к ожидаемым результатам.

Отслеживание метрик и анализ отдельных инцидентов часто не дают полной картины работы СУБД. Интеграция двух мощных инструментов — pgpro_pwr, собирающего детальную статистику, и pg_expecto, анализирующего события ожидания, — создает качественно новый уровень контроля. Этот симбиоз превращает разрозненные данные в последовательные и понятные сценарии для проактивного управления, глубокой диагностики и интеллектуальной оптимизации PostgreSQL.

Вопрос нейросети

Подготовь список новых возможностей и выгод от возможной интеграции комплексов pg_expecto и pgro_pwr

Ответ нейросети

Основываясь на возможностях pg_expecto и pgpro_pwr (или pgro_pwr), их интеграция может создать мощную платформу для управления производительностью PostgreSQL. Вот ключевые преимущества, сгруппированные по категориям.

🚨 Улучшенная диагностика и решение инцидентов

  • Контекстный анализ инцидентов: pg_expecto может использовать снимки нагрузки pgpro_pwr для сравнения состояния СУБД до и после инцидента, что помогает точнее определить причину проблем.

  • Автоматический поиск «виновников»: При падении производительности интегрированная система сможет автоматически сформировать список проблемных SQL-запросов, основываясь на корреляционном анализе ожиданий и данных о наиболее ресурсоемких операциях из pgpro_pwr.

  • Сквозной анализ «от железа до запроса»: Интеграция позволяет связать аномалии в метриках инфраструктуры (например, дисковый ввод/вывод, память) с конкретными событиями ожидания в СУБД и итоговыми медленными запросами.

🧠 Интеллектуальная оптимизация с помощью ИИ

  • Семантический анализ запросов: pg_expecto может автоматически готовить структурированные промпты для нейросетей (GPT, Claude), включая текст проблемных запросов, планы выполнения и статистику из pgpro_pwr. Это позволяет получать качественные рекомендации по оптимизации запросов, рефакторингу JOIN и условий WHERE.

  • Выявление паттернов: Нейросеть может анализировать множество запросов, выявленных pgpro_pwr, и находить общие проблемные паттерны (например, отсутствие индексов, неоптимальные соединения), давая сводные рекомендации.

  • Обоснованные рекомендации по настройке: Вместо общих советов система сможет давать конкретные рекомендации по параметрам PostgreSQL (shared_buffers, work_mem и др.), основанные на фактической нагрузке и статистике использования ресурсов.

🔮 Проактивный мониторинг и прогнозирование

  • Профили «нормального» состояния: На основе исторических снимков pgpro_pwr можно создать «цифровой двойник» СУБД в оптимальном состоянии, pg_expecto сможет отслеживать отклонения ключевых метрик от этого профиля.

  • Автоматическое создание инцидентов: Любое значимое отклонение может автоматически регистрироваться как событие в системах мониторинга (Zabbix, Grafana), сокращая время обнаружения проблем.

  • Предсказание деградации: Анализируя тенденции в данных pgpro_pwr (рост определенных ожиданий, изменение паттернов запросов), система может предупреждать о потенциальных проблемах до того, как они повлияют на пользователей.

⚙️ Операционная эффективность и автоматизация

  • Сокращение времени на анализ (MTTR): Автоматизация сбора данных, анализа и подготовки выводов значительно ускоряет расследование инцидентов.

  • Централизованное хранилище и отчетность: pgpro_pwr выступает как надежное хранилище детальной исторической статистики, а pg_expecto предоставляет интеллектуальный слой для работы с этими данными и генерации понятных отчетов.

  • Снижение порога вхождения для специалистов: Интегрированная система может направлять менее опытных инженеров, предлагая им не только данные, но и готовые гипотезы и шаги для проверки.

Пример практического сценария работы интеграции

  1. Выявление: Zabbix фиксирует рост времени отклика приложения.

  2. Сбор данных: pg_expecto автоматически запрашивает у pgpro_pwr снимок статистики за период инцидента и сравнивает его с предыдущим периодом.

  3. Анализ: Система обнаруживает резкий рост ожиданий типа IPC (межпроцессное взаимодействие) и коррелирующий с ним рост операций ввода/вывода на файловой системе /data.

  4. Поиск причины: Автоматически формируется список SQL-запросов, которые чаще всего вызывали эти ожидания.

  5. Генерация решения: Тексты запросов, их планы выполнения и контекст передаются нейросети, которая предлагает добавить конкретный недостающий индекс и приводит пример кода.

  6. Верификация: После применения изменений система продолжает мониторить метрики, подтверждая восстановление производительности.

Важные уточнения

  • Объединение сильных сторон: pgpro_pwr — это мощный источник детализированных данных, а pg_expecto интеллектуальный аналитический движок. Их интеграция позволяет не только видеть, что происходит, но и понимать, почему и что с этим делать.

  • Решение фундаментальной проблемы: Интеграция помогает ответить на сложный вопрос из поисковых результатов: что в цифрах означает «нормально» и «ненормально» для конкретной СУБД, основываясь не на общих шаблонах, а на ее собственной истории и характеристиках нагрузки.

  • Отсутствие «серебряной пули»: Важно помнить, что даже интегрированная система не заменит опыт администратора. Она призвана усилить его возможности, взяв на рутинную работу по сбору и первичному анализу данных, но итоговые решения и эксперименты должны проводиться под контролем специалиста.

Итог

Интеграция pg_expecto и pgpro_pwr формирует замкнутый цикл управления производительностью: от сбора детальной статистики и выявления аномалий до автоматизированного поиска root-cause и генерации рекомендаций по оптимизации. Это значительно сокращает время на диагностику (MTTR), позволяет перейти от реактивного к проактивному мониторингу и открывает путь к использованию ИИ для анализа паттернов и настройки СУБД, усиливая экспертов, а не заменяя их.

Показать полностью
4

PG_EXPECTO: Чек-лист проверки инфраструктуры Linux по результатам нагрузочного тестирования PostgreSQL

Серия СУБД PostgreSQL

Взято с основного технического канала Postgres DBA (возможны правки в исходной статье).

От хаоса к порядку: настройка Linux для рекордов СУБД

От хаоса к порядку: настройка Linux для рекордов СУБД

Данный чек-лист представляет собой структурированное руководство по оптимизации операционной системы Linux для развертывания высоконагруженных систем управления базами данных (СУБД). Он основан на анализе критических проблем производительности, таких как высокий I/O wait, блокировка процессов и неэффективное использование памяти. Материал систематизирован по приоритетам — от критических изменений, без которых невозможна стабильная работа, до тонкой настройки для достижения максимальной эффективности. Следуя этим рекомендациям, администраторы смогут значительно повысить отказоустойчивость и скорость отклика инфраструктуры, особенно в средах с интенсивной транзакционной (OLTP) или аналитической (OLAP) нагрузкой.

ЧЕК-ЛИСТ ПАРАМЕТРОВ LINUX ДЛЯ ОПТИМИЗАЦИИ ИНФРАСТРУКТУРЫ СУБД

КРИТИЧЕСКИЙ УРОВЕНЬ (High Priority)

Параметры, напрямую влияющие на критические проблемы: высокий I/O wait, процессы в состоянии D, нехватка RAM.

vm.dirty_ratio

Команда проверки: sysctl vm.dirty_ratio
Целевое значение: 10-15
Обоснование: Ключевой параметр! Определяет порог, при котором процессы блокируются на запись. Высокое значение (20-30) приводит к накоплению "грязных" страниц и массовым блокировкам (состояние D).

vm.dirty_background_ratio

Команда проверки: sysctl vm.dirty_background_ratio
Целевое значение: 3-5
Обоснование: Порог фоновой записи. Слишком высокое значение откладывает запись, затем вызывает "взрывную" нагрузку. Для OLAP-нагрузки с большими чтениями нужен более агрессивный фоновый сброс.

I/O Scheduler для дисков данных

Команда проверки: cat /sys/block/vd[d,x]/queue/scheduler
Целевое значение: none (noop) для KVM/VirtIO
Обоснование: В виртуальной среде (KVM) планировщик none (noop) минимизирует накладные расходы, передавая запросы гипервизору. mq-deadline или kyber могут создавать излишнюю очередь.

vm.swappiness

Команда проверки: sysctl vm.swappiness
Целевое значение: 1-10
Обоснование: При почти полной загрузке RAM (free <5%) система может начать готовиться к свопингу. Резкое снижение заставляет ядро в первую очередь сбрасывать кэш файловой системы, а не искать кандидатов на своп.

vm.dirty_expire_centisecs

Команда проверки: sysctl vm.dirty_expire_centisecs
Целевое значение: 1000-1500 (10-15 секунд)
Обоснование: Время жизни "грязной" страницы. Уменьшение делает запись более частой, но менее объемной "пачками", что сглаживает нагрузку на диск и снижает пики wa.

ВЫСОКИЙ УРОВЕНЬ (Medium Priority)

Параметры, влияющие на общую производительность и стабильность под нагрузкой.

Ограничение открытых файлов (nofile) для пользователя postgres

Команда проверки: su - postgres -c 'ulimit -n'
Целевое значение: 65535
Обоснование: При max_connections=1000 и большом количестве таблиц/индексов PostgreSQL может быстро исчерпать лимит. Это вызовет ошибки "Too many open files".

vm.vfs_cache_pressure

Команда проверки: sysctl vm.vfs_cache_pressure
Целевое значение: 50-80
Обоснование: Управляет тенденцией ядра к высвобождению памяти, занятой кэшем inode и dentry. Уменьшение значения сохраняет кэш файловой системы дольше, что полезно для OLAP с частыми чтениями.

Параметры монтирования для /data, /wal, /log

Команда проверки: mount | grep -E "(data|wal|log)"
Целевое значение: noatime,nodiratime,barrier=0 (если диск с батарейным кэшем)
Обоснование: noatime исключает запись времени доступа, снижая нагрузку на запись. barrier=0 отключает барьеры для дисков с батарейным кэшем (только если уверены в надежности).

CPU Governor

Команда проверки: cpupower frequency-info | grep governor
Целевое значение: performance
Обоснование: Фиксирует CPU на максимальной частоте, исключая задержки на переключение частот. Критично для виртуальных машин, где гипервизор может "тормозить" CPU в powersave.

Кеш hugepages (опционально)

Команда проверки: grep HugePages /proc/meminfo
Целевое значение: Рассчитать исходя из shared_buffers (например, для shared_buffers=2GB выделить 1GB hugepages)
Обоснование: Уменьшает накладные расходы на управление памятью, но требует настройки PostgreSQL (параметр huge_pages).

СРЕДНИЙ УРОВЕНЬ (Low Priority)

Параметры "тонкой настройки" или для устранения потенциальных проблем.

net.core.somaxconn

Команда проверки: sysctl net.core.somaxconn
Целевое значение: 1024
Обоснование: Максимальный размер очереди принятых соединений. При пиковых подключениях к БД может предотвратить отказы.

net.ipv4.tcp_tw_reuse

Команда проверки: sysctl net.ipv4.tcp_tw_reuse
Целевое значение: 1
Обоснование: Позволяет переиспользовать сокеты в состоянии TIME_WAIT для исходящих соединений. Снижает нагрузку на сетевой стек при активной работе.

vm.min_free_kbytes

Команда проверки: sysctl vm.min_free_kbytes
Целевое значение: 262144 (256MB)
Обоснование: Минимальный объем свободной памяти для ядра. Увеличение может предотвратить deadlock при нехватке памяти, но слишком высокое значение уменьшает доступную память для процессов.

Ограничение процессов (nproc) для пользователя postgres

Команда проверки: su - postgres -c 'ulimit -u'
Целевое значение: 4096-8192
Обоснование: С учетом max_connections=1000 и фоновых процессов autovacuum (max_workers=4) может потребоваться увеличение.

ДИАГНОСТИЧЕСКИЕ ПАРАМЕТРЫ (Для сбора информации перед оптимизацией)

Текущая нагрузка I/O

Команда проверки: iostat -dx 2 5 или iotop -o
Что оценивать: Утилизация дисков (%util), очередь (avgqu-sz), время отклика (await). Сравнить /data vs /wal.

Статистика dirty pages

Команда проверки: cat /proc/vmstat | grep -E "(dirty|writeback)"
Что оценивать: nr_dirty, nr_writeback. Если nr_dirty постоянно близко к лимиту — нужна оптимизация vm.dirty_*.

Pressure Stall Information (PSI)

Команда проверки: cat /proc/pressure/io или cat /proc/pressure/memory
Что оценивать: Показывает, как процессы страдают от нехватки I/O или памяти. Значения >10% указывают на серьезные проблемы.

Конфигурация дисковых очередей

Команда проверки: cat /sys/block/vdd/queue/nr_requests и cat /sys/block/vdd/queue/read_ahead_kb
Что оценивать: Глубина очереди (128-256 нормально) и readahead (для OLAP можно увеличить до 4096-8192).

ПРИОРИТЕТЫ И ПОРЯДОК ПРОВЕРКИ:

  1. Сначала диагностика (пункты 15-18) — понять текущее состояние системы.

  2. Критические параметры (1-5) — начинать оптимизацию с них, особенно с vm.dirty_* и I/O Scheduler.

  3. Высокие параметры (6-10) — проверить и настроить после стабилизации I/O.

  4. Средние параметры (11-14) — тонкая настройка после решения основных проблем.

ВАЖНЫЕ ПРЕДУПРЕЖДЕНИЯ:

  • Изменяйте параметры по одному и тестируйте после каждого изменения (нагрузочный тест аналогичный "Эксперименту-8").

  • Сохраняйте бэкапы конфигураций (sysctl -a > /root/sysctl_backup.conf, /etc/security/limits.conf.bak).

  • Для виртуальной среды (KVM) некоторые параметры могут контролироваться гипервизором (например, I/O Scheduler на хосте). Согласуйте изменения с администраторами виртуальной инфраструктуры.

  • Параметры файловой системы (barrier=0) применяйте только если диск имеет батарейный кэш (BBU) или вы готовы к риску потери данных при сбое питания.

Итог

Чек-лист охватывает ключевые аспекты настройки Linux для оптимальной работы СУБД, выделяя четыре уровня вмешательства: диагностика, критическая, высокая и средняя настройка.

Основное внимание уделяется управлению вводом-выводом (I/O) и памятью — параметрам vm.dirty_*, выбору планировщика дисков и настройке свопа. Регулировка этих параметров позволяет избежать лавинообразных блокировок и сгладить пиковую нагрузку на дисковую подсистему.

Дополнительно рассматриваются настройки сетевого стека, ограничений процессов и файловой системы, что в комплексе обеспечивает стабильную и предсказуемую работу базы данных под высокой нагрузкой.

Все изменения требуют поэтапного внедрения, тестирования и учета особенностей среды (виртуализация, оборудование).

Показать полностью
Отличная работа, все прочитано!

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества