Postmaster linux что это

Обновлено: 07.07.2024

Рассмотрим способы посмотреть текущие активности, другими словами процессы и их деятельность на сервере PostgreSQL.

Что в этой статье будет рассмотрено:

  • Вы можете посмотреть на текущие активности сервера PostgreSQL с помощью представления pg_stat_activity.
  • Чтобы завершить один из обслуживающих процессов нужно использовать функцию pg_terminate_backend(<pid>).
  • Вы можете, с помощью функции pg_blocking_pids(<pid>), посмотреть кого ожидает процесс с этим pid.

Все эти действия можно выполнить с помощью инструментов командной строки операционной системы:

  • посмотреть процессы с помощью команды ps ;
  • завершить процесс с помощью команды kill -9 <pid> .

Но операционная система не сможет определить чем занят процесс postgress, поэтому ps не будет столь-же информативен, как представление pg_stat_activity.

Как вы помните при работе сервера PostgreSQL работает 1 главный процесс, который запускает остальные и следит за ними. При падении одного из процессов postgres, например когда мы его завершили командой kill -9 <pid> , главный процесс postgres может решить что в базе данных случилась ошибка и перезапустит весь кластер. Поэтому завершать процессы лучше средствами PostgreSQL, с помощью функции pg_terminate_backend(<pid>).

Практика

Создадим таблицу и вставим в неё одно значение, равное 42:

Затем заблокируем эту таблицу выполняя в ней транзакцию:

Запустим второй сеанс и подключимся к той-же самой базе данных. Затем попробуем поменять значение в заблокированной таблице:

Второй сеанс при этом завис!

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

В запросе мы получали следующую информацию:

В конфигурации сервера есть параметр:

Теперь завершим зависший процесс вручную:

После этого второй терминал должен отвиснуть и запрос выполится:

Дальше посмотрим некоторую информацию по всем процессам (фоновым и обслуживающим) которые есть в этом представлении:

Сравним с выводом команды операционной системы ps:

Можно заметить, что в представлении pg_stat_activity нет процесса stats collector.

PostgreSQL База данных Архитектура - Процесс и структура памяти

Процесс работы в заголовок

  • Процесс запуска базы данных
  • Процесс подключения к базе данных

PostgreSQL - это схема Client / Server Schema, выполняя несколько процессов на сервере.

1, структура процесса


Postgres Server Process(postmaster) Главный процесс --pg, также является родительским процессом, процесс бэкэнда, и фоновый рабочий процесс выводится из вилки серверного процесса;

Background Processes - Процесс работы в заголовках, реализация функций и управления базами данных

logger process - Процесс сбора журнала, информация о журнале вывода для журналов файлов

checkpointer process - Процессы контрольной точки, исполнительные пропускные пункты

writer process - Фон написать процесс, запись данных в общий буфер на диск

wal writer process - Фон Wal Log Process процесс, напишите журнал потоков в Walbuffer на диск

autovacuum launcher process - автоматическая обработка очистки, очистка данных версии, обращайтесь к главному процессу Postmaster для вызова процесса AutoVacuum

archiver process - Архив процесс, архивирующий журнал WAL

stats collector process - Сборка статистики (pg_stat_database, pg_stat_aactivity)

Логическая репликация, процесс отправителя WAL и т. Д.
backed process - Задний процесс, используйте для обработки клиентского соединения, пожалуйста,

pg postgres [local] idle - Местный процесс посадки

pg postgres 192.168.6.1(53171) idle - Удаленный процесс входа

pg postgres 192.168.6.1(51846) idle intransaction - Удаленный процесс входа в систему, транзакция в процессе не завершена

2, структура памяти

  • Local memory area - Под каждым процессом Backend, в основном для запроса

work_mem - используется для хранения заказа и иметь результаты

maintenance_work_mem - память, используемая руководством, такими как вакуум

temp_buffers - временная таблица хранения

  • Shared memory area - Все процессы используют, запустите память на память

WAL buffer - хранить логистику WAL

commit log - Хранить статус транзакции

3, процесс запуска базы данных

После запуска базы данных запустите процесс Postgres Server (Postmaster), а затем назначьте общую память, выделите фоновый процесс работы, Postmaster запустил порт, дождитесь запроса клиента подключения клиента

4, процесс подключения клиента

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

Это вольный перевод поста одного из сильных разработчиков Postgres - Andres Freund. Кроме того что разработчик сильный, так еще и статья довольно интересная и раскрывает детали того как работает ОС Linux.

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

Как по мне, здесь есть что обсудить. Кроме того можно сделать несколько улучшений и уменьшить использование памяти.

Я думаю что эта обеспокоенность оверхэдом на память вызвана одной общей причиной, это то что самый простой способ измерения потребления памяти через утилиты типа top и ps является довольно обманчивым.

И действительно, особенно довольно сложно измерить то как увеличивается используемая память при каждом новом соединении.

В этом посте я буду говорить о Postgres работающем на Linux, т.к. именно в этом направлении у меня больше всего опыта.

И перед тем как продолжить я хочу акцентировать внимание, что при точном и аккуратном измерении, одно соединение имеет накладные расходы на уровне меньше 2MiB (см. выводы в конце поста).

Первый взгляд

Если использовать стандартные утилиты операционной системы, то можно сделать вывод, что накладные расходы существенно больше (чем есть на самом деле). Особенно если не использовать большие страницы (huge pages), то использование памяти каждый процессом действительно выглядит слишком большим. Отмечу что настоятельно рекомендуется использовать большие страницы. Давайте взглянем на только что установленное соединение, в только что запущенном Postgres:

Утечки памяти. К счастью, нет

При этом со временем памяти используется все больше и больше. Чтобы продемонстрировать это, я воспользуюсь расширением pgprewarm, чтобы загрузить таблицу в буфер (shared buffers):

Теперь использование памяти достигло уровня 3GB. При том что, на самом деле, в этой сессии не потребовалось выделять дополнительную память. Объем используемой памяти, увеличился пропорционально объему используемого буфера:

Что еще хуже, даже если эти страницы будут использовать в других сессиях, это также будет отображаться как использование большого объема памяти:

Конечно, Postgres на самом деле не использует 3GB и 2.7GB памяти в данном случае. На самом деле, в случае huge_pages=off, утилита ps отображает объем разделяемой (shаred - память совместно используемая с другими процессами) памяти, включая и страницы в буфере которые используются в каждой сессии. Очевидно это приводит к значительной переоценке величины используемой памяти.

На помощь внезапно приходят большие страницы

Множество процессорных микро-архитектур обычно используют страницы размером 4KiB, но также могут использовать и страницы большего размера, например широко распространенный вариант это 2MiB.

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

Если повторить вышеописанный эксперимент с huge_pages=on, можно увидеть гораздо более приятные глазу результаты. Для начала, взглянем на "новый процесс":

Теперь, новый процесс использует всего около 7MiB. Такое уменьшение вызвано тем что таблицы управления страницами (page table) теперь требуют меньше места, из-за того что используются большие страницы, для управления тем же объемом памяти нужно в 512 раз меньше элементов чем раньше (4KiB * 512 = 2MiB).

Теперь давайте посмотрим что произойдет при доступе к большим объемам данных в памяти:

В отличие от самого первого эксперимента, эти процессы используют всего 12MiB и 9MiB соответственно, в то время как в прошлый раз использовалось 3GiB и 2.7GiB.

Разница довольно очевидна.

Это следствие того, как в Linux реализован учёт использования больших страниц, а не потому, что мы использовали на порядки меньше памяти: используемые большие страницы не отображаются как часть значения RSS в выводе ps и top.

Чудес не бывает

Начиная с версии ядра 4.5, появился файл /proc/$pid/status в котором отображается более подробная статистики об использование памяти процессом:

VmRSS общий размер используемой памяти. Значение является суммой трех других значений (VmRSS = RssAnon + RssFile + RssShmem)

RssAnon размер используемой анонимной памяти.

RssFile размер используемой памяти ассоциированной с файлами.

RssShmem размер используемой разделяемой памяти (включая SysV shm, сегменты в tmpfs и анонимные разделяемые сегменты)

RssAnon отображает объем "анонимной" памяти, т.е. участки рабочей памяти которые не являются отображением файлов на диске. RssFile это как раз отображение в памяти конкретных файлов на диске, включая даже исполняемый файл postgres. И последнее RssShmem отображает доступную разделяемую память без учета больших страниц.

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

И теперь взглянем на эту же статистику, но с huge_pages=on:

Увеличиваем точность

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

Первое, на самом деле учет RssFile в использовании памяти не играет роли - по факту это всего лишь исполняемый файл и используемые им разделяемые библиотеки (Postgres не использует mmap() для каких-либо файлов). Все эти файлы являются общими для всех процессов в системе и практически не дают накладных расходов для постгресовых процессов.

Второе, RssAnon также переоценивает использование памяти. Смысл тут в том что ps показывает всю память процесса целиком, при том что большая часть этой памяти в случае создания нового процесса делится между пользовательским соединением и памятью родительского процесса postgres (так же известен как postmaster). Это следует из того что Linux не копирует всю память целиком когда создает новый процесс (при выполнении операции fork()), вместо этого используется механизм Copy-on-Write для копирования в новый процесс, набора только измененных страниц.

Таким образом, пока нет хорошего способа аккуратно и точно измерить использование памяти отдельно взятого нового процесса. Но все не так плохо, начиная с версии 4.14 ядро предоставляет еще одну статистику (коммит с описанием) процесса в /proc/$pid/smaps_rollup файле. Pss показывает "принадлежащую процессу пропорциональную долю отображения" среди всех отображений этого процесса (детали можно найти в документации поиском по smaps_rollups и Pss которые сами по себе не имеют прямых ссылок). Для сегмента памяти используемого совместно между несколькими процессами, доля будет представлять собой отношение размера этого сегмента на количество процессов которые используют этот сегмент.

Pss_Anon включает в себя анонимную память используемую процессом, Pss_File включает память используемую под разделяемые библиотеки задействование процессом, и Pss_Shmem (если не используются большие страницы) показывает использование общей памяти разделенное на все процессы которые обращались к соответствующим страницам.

Но у пропорциональных значений есть небольшой недостаток, это использование делителя который зависит от числа подключений к серверу. Здесь я использовал pgbench (scale 1000, -S -M prepared -c 1024) чтобы создать большое число подключений:

И с использованием huge_pages=on:

К сожалению Pss значения учитывают только те ресурсы, что видны приложению. Например, размер таблицы страниц не учитывается. Размер таблицы страниц можно увидеть в уже упоминавшемся `/proc/$pid/status`.

Я не уверен, но насколько я знаю, VmPTE (размер таблицы страниц) полностью приватный для каждого процесса, но остальное большинство Vm* значений, включая стек VmStk являются общими через copy-on-write.

Учитывая всё это, накладные расходы с учетом таблицы страниц и с huge_pages=off:

и с huge_pages=on:

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

Вывод

На основе проделанных измерений, мы можем представить что процесс выполняющий достаточно простую read-only OLTP нагрузку имеет накладные расходы около 7.6MiB с huge_pages=off и около 1.3MiB с huge_pages=on включая Pss_Anon в VmPTE.

Даже если представить что есть некий "невидимый" оверхэд, и большой объем данных в буфере и т.д., я думаю мы вернемся к моему раннему утверждению что накладные расходы на соединение меньше чем 2MiB.

Дополнение от переводчика. В версии Postgres 14 появилось новое представление pg_backend_memory_contexts которое показывает подробную утилизацию памяти текущим процессом с точки зрения самого Postgres.

Сервер баз данных PostgreSQL имеет очень много параметров с помощью которых его можно настроить под любые нужды. В этой статье мы не будет рассматривать все эти параметры. Здесь мы посмотрим на различные cпособы конфигурирования PostgreSQL.

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

Конфигурационный файл postgresql.conf

Главный конфигурационный файл для кластера PostgreSQL – это postgresql.conf, в разных системах он может находится в разных местах. Так как мы собирали сервер из исходников и не меняли путь хранения этого файла, то по умолчанию он будет находится в каталоге PGDATA:

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

Самый точный способ узнать расположение этого файла, посмотреть из терминала psql:

Если вы измените параметры в этом файле, его нужно перечитать. Первый способ – из командной оболочки операционной системы:

Второй способ – из терминала psql:

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

Конфигурация сервера используя ALTER SYSTEM

Для настройки сервера также существует другой файл – postgresql.auto.conf. Он были придуман для настройки сервера из консоли psql. Читается этот файл после postgresql.conf, поэтому параметры из него имеют приоритет. Этот файл всегда находится в каталоге с данными (PGDATA).

Для создания параметров в файле postgresql.auto.conf нужно выполнить подобный запрос:

ALTER SYSTEM SET <параметр> TO <значение>;

Чтобы удалить параметр используем другой запрос:

ALTER SYSTEM RESET <параметр>;

А чтобы удалить все параметры из postgresql.auto.conf выполним:

ALTER SYSTEM RESET ALL;

Чтобы применить изменения нужно перечитать конфигурационные файлы как было описано выше.

Информация о текущих настройках сервера

В PostgreSQL есть 2 представления через которые можно посмотреть текущие настройки сервера:

  • pg_file_settings – какие параметры записаны в файлах postgresql.conf и postgresql.auto.conf;
  • pg_settings – текущие параметры, с которыми работает сервер.

Например посмотрим значение параметра config_file из представления pg_settings, который покажет конфигурационный файл текущего кластера:

Внесём изменения в параметр work_mem в postgresql.conf и postgresql.auto.conf. Затем посмотрим на все не закомментированные параметры в этих файлах:

Как можно заметить в примере выше, у меня 2 одинаковых параметра work_mem. Колонка applied показывает, может ли быть применён параметр. Первый work_mem не может быть применен, так как второй его перезапишет. При этом реальное значение с которым работает сервер отличается, так как сервер не перечитал конфигурацию.

Теперь посмотрим на реальное, текущее значение этого параметра:

В примере выше мы использовали расширенный режим (в конце запроса \gx), поэтому табличка перевёрнута. Разберём колонки:

  • name – имя параметра;
  • setting – текущее значение;
  • unit – единица измерения;
  • boot_val – значение по умолчанию (жёстко задано в коде postgresql);
  • reset_val – если перечитаем конфигурацию, то применится это значение;
  • source – источник, это значение по умолчанию;
  • sourcefile – если бы источником был конфигурационный файл, то тут был бы указан этот файл;
  • sourceline – номер строки в этом файле;
  • pending_restart – параметр изменили в конфигурационном файле и требуется перезапуск сервера. У нас требуется всего лишь перечитать конфигурацию;
  • context – действия, необходимые для применения параметра, может быть таким:
    • internal – изменить нельзя, задано при установке;
    • postmaster – требуется перезапуск сервера;
    • sighup – требуется перечитать файлы конфигурации;
    • superuser – суперпользователь может изменить для своего сеанса;
    • user – любой пользователь может изменить для своего сеанса на лету.

    Перечитаем конфигурацию сервера:

    Как видим, параметр изменился. Он был взят из postgresql.auto.conf и теперь равняется 10 MB.

    Установка параметров на лету

    Для своего сеанса можно изменить параметры с context=user. Для этого используется конструкция:

    SET <параметр> TO '<значение>';

    Например сделаем это для work_mem:

    Как видим, теперь источником является текущая сессия, а параметр равен 64 MB, но если мы перечитаем конфигурацию параметр снова станет равным 10 MB.

    Чтобы вернуть все на место нужно просто перезайти в psql. Или выполнить команду RESET <параметр> :

    Тоже самое может проделывать приложение для одной транзакции, и если транзакция откатывается, то и значение параметра откатывается вместе с ней:

    Как вы могли заметить посмотреть текущее значение параметра ещё можно так:

    Какие параметры требуют перезапуск сервера?

    Чтобы это выяснить нужно посмотреть все параметры у которых context = postmaster:

    Читайте также: