Контроль потребления СУБД Pangolin вычислительных ресурсов
Функциональность доступна только для редакций Enterprise и Enterprise для ERP-систем.
Описание
Функциональность реализована в виде расширения psql_resources_consumption_limits, которое позволяет ограничивать позволяет ограничивать потребление оперативной памяти и процессорного времени процессами СУБД.
Процессы расширений ограничены в соответствии с установленными лимитами (включая задания pg_cron и т.п.).
В СУБД Pangolin поддерживается:
- функциональность фиксированного задания ограничений ресурсов для процессов сессий СУБД;
- завершение с ошибкой сессии, превысившей ограничение на потребление ресурса, и всех ее подпроцессов;
- обнаружение превышения квоты на ресурсы асинхронно.
Управление ограничениями на уровне отдельной сессии не поддерживается.
Схема процесса
Процесс первоначальной настройки и изменения настройки квотирования ресурсов:

Настройка
Настройка фиксированных ограничений функциональности задается параметрами расширения psql_resources_consumption_limits.
Включение функциональности
Включение функциональности происходит при активации расширения psql_resources_consumption_limits. С процессом установки расширения можно ознакомиться в разделе соответствующего расширения документа «Описание расширений продукта СУБД Pangolin».
Примеры конфигурации лимитов ресурсов
Потребление ресурсов ограничено для выбранных ролей:
- В конфигурации или через
ALTER SYSTEM SETустановлен нулевой параметрpsql_resources_consumption_limits.mem_limit(илиpsql_resources_consumption_limits.cpu_limit) — глобальная проверка отключена. - Для выбранных ролей заданы ненулевые значения
psql_resources_consumption_limits.mem_limit(илиpsql_resources_consumption_limits.cpu_limit) черезALTER ROLE ... SET name=value;— проверка для отдельных ролей включена.
Потребление ресурсов действует для всех ролей, кроме указанных:
- В конфигурации или через
ALTER SYSTEM SETустановлен ненулевой параметрpsql_resources_consumption_limits.mem_limit(илиpsql_resources_consumption_limits.cpu_limit) — глобальная проверка включена. - Для выбранных ролей заданы нулевые значения
psql_resources_consumption_limits.mem_limit(илиpsql_resources_consumption_limits.cpu_limit) черезALTER ROLE ... SET name=value;— проверка для отдельных ролей отключена.
Асинхронный поиск превышения лимитов
Контроль превышения лимитов реализуется в отдельном процессе.
Процесс запускается всегда, не зависимо от того, включен ли контроль за ресурсами или нет. Если контроль ни за одним ресурсом не включен, то процесс находится в ожидании. По SIGHUP процесс перечитывает конфигурационные параметры и, если контроль хотя бы за одним из ресурсов был включен, то процесс начинает периодическую проверку превышения лимитов.
Если контролируемый процесс превысит лимит внутри интервала контроля, но на момент проверки лимиты превышены не будут, то это превышение пройдет незамеченным для контролирующего процесса.
Параллельное выполнение запросов
При порождении процессом сессии СУБД подпроцессов параллельного выполнения запросов или подпроцессов фонового выполнения (parallel worker или background worker) суммарное потребление ресурсов такой сессией и ее подпроцессами не может превысить заданное ограничение на сессию.
Потребление памяти одной сессией
Лимит учитывает только RSS-память процесса.
Значение RSS для процесса вычисляется по полю resident [количество страниц памяти RSS] внутри файла /proc/<pid>/statm. Чтобы перевести значение в байты resident умножается на sysconf(_SC_PAGESIZE) [Кбайт].
Считывается потребление резидентной памяти для каждого процесса сессии по pid, затем вычисляется суммарное потребление для сессии.
Потребление CPU одним процессом сессии
Потребление CPU процессом вычисляется по изменению полей utime, stime [clock ticks] внутри файла /proc/<pid>/stat со времени последнего измерения. Для этого на каждой итерации в памяти сохраняются поля utime, stime и время измерения, которые будут использоваться для вычисления процента потребления CPU на следующей итерации:
(((current utime + current stime) - (saved utime + saved stime)) / sysconf(_SC_CLK_TCK)) * 100 / (текущее время - время прошлого измерения)
Где sysconf(_SC_CLK_TCK) – функция, возвращающая количество тактов процессора в одной секунде.
Потребление CPU считывается для каждого процесса сессии по pid, затем вычисляется суммарное потребление для сессии.
Остановка процессов сессии
При превышении сессией установленных лимитов все ее процессы останавливаются сигналом SIGTERM.
Получение данных о потреблении ресурсов по процессам сессии
Данные о потреблении ресурсов процессами отображаются в новом представлении psql_resources_consumption_limits.consumption.
Контроль системных процессов
Контроль потребления ресурсов не производится для системных процессов СУБД Pangolin (в том числе для процессов потоковой и логической репликации).
Сценарии использования
Примеры использования представлены для конфигурации standalone-patroni-pgbouncer.
Подготовительные действия
В конфигурационном файле /etc/patroni/postgres.yml:
-
Отключите парольные политики:
password_policies_enable: off -
Добавьте расширение
psql_resources_consumption_limitsдля включения функциональности контроля ресурсов:shared_preload_libraries = 'psql_resources_consumption_limits' -
Настройте период проверки лимитов:
psql_resources_consumption_limits.check_interval: 100ms -
Добавьте тестовых пользователей в конфигурационный файл
pg_hba.conf:host all u1 {IP-Address}/{port} trust
host all u2 {IP-Address}/{port} trust
host all u3 {IP-Address}/{port} trust -
Разрешите тестовым пользователям авторизовываться без пароля:
enabled_extra_auth_methods: trust -
Перечитайте конфигурацию на кластере:
restart --force && reload --force
Далее произведите действия от имени администратора базы данных:
-
Создайте тестовые роли:
CREATE USER u1 WITH PASSWORD 'u1';
CREATE USER u2 WITH PASSWORD 'u2';
CREATE USER u3 WITH PASSWORD 'u3'; -
Создайте расширение контроля потребления ресурсов:
CREATE EXTENSION psql_resources_consumption_limits; -
Создайте расширение pg_background:
CREATE EXTENSION pg_background; -
Разрешите тестовым пользователям использовать расширение
pg_background:GRANT EXECUTE ON FUNCTION pg_background_launch TO u1;
GRANT EXECUTE ON FUNCTION pg_background_result TO u1;
GRANT EXECUTE ON FUNCTION pg_background_launch TO u2;
GRANT EXECUTE ON FUNCTION pg_background_result TO u2;
GRANT EXECUTE ON FUNCTION pg_background_launch TO u3;
GRANT EXECUTE ON FUNCTION pg_background_result TO u3; -
Разрешите тестовым пользователям использовать функции из схемы
public:GRANT USAGE ON SCHEMA public TO u1;
GRANT USAGE ON SCHEMA public TO u2;
GRANT USAGE ON SCHEMA public TO u3;
Тестовые запросы
С использованием pg_background (не блокирующий консоль)
Тестовый запрос, потребляющий память:
SELECT * FROM public.pg_background_launch('
do $$
declare
i int[] := ''{1}'';
begin
for counter in 1..23 loop
i := i || i;
end loop;
PERFORM pg_sleep(600);
end $$;
');
Тестовый запрос, потребляющий процессорное время:
SELECT * FROM public.pg_background_launch('
do $$
begin
while true loop
end loop;
end $$;
');
Тестовый запрос, потребляющий минимальный объем ресурсов:
SELECT * FROM public.pg_background_launch('
do $$
begin
PERFORM pg_sleep(600);
end $$;
');
Без использования pg_background (блокирующий консоль)
Тестовый запрос, потребляющий память:
do $$
declare
i int[] := '{1}';
begin
for counter in 1..23 loop
i := i || i;
end loop;
PERFORM pg_sleep(600);
end $$;
Тестовый запрос, потребляющий процессорное время:
do $$
begin
while true loop
end loop;
end $$;
Тестовый запрос, потребляющий минимальный объем ресурсов:
do $$
begin
PERFORM pg_sleep(600);
end $$;
Контроль потребления ресурсов при активных лимитах (со значением 'terminate')
При выключенных лимитах потребления в конфигурации и сброшенных настройках лимитов для ролей контроль за потреблением ресурсов не осуществляется.
При включенных лимитах потребления в конфигурации, но выключенных лимитах для ролей, контроль за потреблением ресурсов не осуществляется (настройки роли имеют высший приоритет).
Сценарий показывает, что при включенных лимитах потребления в конфигурации и сброшенных настройках лимитов для ролей осуществляется контроль за потреблением ресурсов.
При установке значения terminate для реакций на превышения памяти/процессора запросы будут остановлены досрочно, в логах будет информация о нарушении лимитов.
-
Включите лимиты потребления ресурсов и установите значение
terminateдля реакций на превышения памяти и процессора в конфигурации:psql_resources_consumption_limits.mem_limit: 32768
psql_resources_consumption_limits.cpu_limit: 50
psql_resources_consumption_limits.mem_exceeding_reaction: terminate
psql_resources_consumption_limits.cpu_exceeding_reaction: terminateПеречитайте конфигурацию:
restart --force && reload --forceЛимиты потребления ресурсов включены в конфигурации. Конфигурация перечитана:
Success: restart on member <clustername> -
Сбросьте настройки лимитов потребления ресурсов для всех тестовых ролей:
ALTER USER u1 RESET psql_resources_consumption_limits.mem_limit;
ALTER USER u1 RESET psql_resources_consumption_limits.cpu_limit;
ALTER USER u1 RESET psql_resources_consumption_limits.mem_exceeding_reaction;
ALTER USER u1 RESET psql_resources_consumption_limits.cpu_exceeding_reaction;
ALTER USER u2 RESET psql_resources_consumption_limits.mem_limit;
ALTER USER u2 RESET psql_resources_consumption_limits.cpu_limit;
ALTER USER u2 RESET psql_resources_consumption_limits.mem_exceeding_reaction;
ALTER USER u2 RESET psql_resources_consumption_limits.cpu_exceeding_reaction;Настройки тестовых ролей сброшены:
ALTER ROLE -
Выполните нагрузочные запросы от имени тестовых ролей:
-
От имени
u1, запрос, потребляющий память:psql -U u1 -
От имени
u2, запрос, потребляющий процессорное время:psql -U u2
Запущены
pg_backgroundпроцессы:pg_background_launch
----------------------
PID
(1 row) -
-
Проверьте, что запросы не выполняются, процессов не существует:
ps aux | grep PID | grep -v grepИдентификаторы процессов не найдены в системе.
-
Проверьте, что в логах базы присутствуют сообщения о превышении лимитов для всех нагрузочных запросов:
pglog | grep 'Terminate process'
pglog | grep 'has violated the memory limit'
pglog | grep 'has violated the cpu limit'Найдены логи о превышении лимитов. Пример вывода:
2023-10-22 12:36:46 MSK [5010]: [7-1] app=psql_resources_consumption_limits checker,user=postgres,db=postgres,client=[bgworker],type=psql_resources_consumption_limits checker WARNING: Terminate process 5055
2023-10-22 12:36:46 MSK [5010]: [4-1] app=psql_resources_consumption_limits checker,user=postgres,db=postgres,client=[bgworker],type=psql_resources_consumption_limits checker WARNING: The process 5043 memory consumption 110736 (session 110736) has violated the memory limit 32768
2023-10-22 12:36:46 MSK [5010]: [6-1] app=psql_resources_consumption_limits checker,user=postgres,db=postgres,client=[bgworker],type=psql_resources_consumption_limits checker WARNING: The process 5055 memory consumption 95460 (session 110736) has violated the memory limit 32768
2023-10-22 12:37:00 MSK [5010]: [8-1] app=psql_resources_consumption_limits checker,user=postgres,db=postgres,client=[bgworker],type=psql_resources_consumption_limits checker WARNING: The process 5072 cpu consumption 99 (session 99) has violated the cpu limit 50
2023-10-22 12:37:00 MSK [5010]: [10-1] app=psql_resources_consumption_limits checker,user=postgres,db=postgres,client=[bgworker],type=psql_resources_consumption_limits checker WARNING: The process 5076 cpu consumption 99 (session 99) has violated the cpu limit 50
Контроль потребления ресурсов при активных лимитах (со значением 'alert')
При установке значения alert для реакций на превышения памяти/процессора запросы не будут остановлены досрочно, но в логах будет информация о нарушении лимитов.
-
Включите лимиты потребления ресурсов и установите значение
alertдля реакций на превышения памяти и процессора в конфигурации:psql_resources_consumption_limits.mem_limit: 32768
psql_resources_consumption_limits.cpu_limit: 50
psql_resources_consumption_limits.mem_exceeding_reaction: alert
psql_resources_consumption_limits.cpu_exceeding_reaction: alertПеречитайте конфигурацию:
restart --force && reload --forceЛимиты потребления ресурсов включены в конфигурации. Конфигурация перечитана:
Success: restart on member <clustername> -
Сбросьте настройки лимитов потребления ресурсов для всех тестовых ролей:
ALTER USER u1 RESET psql_resources_consumption_limits.mem_limit;
ALTER USER u1 RESET psql_resources_consumption_limits.cpu_limit;
ALTER USER u1 RESET psql_resources_consumption_limits.mem_exceeding_reaction;
ALTER USER u1 RESET psql_resources_consumption_limits.cpu_exceeding_reaction;
ALTER USER u2 RESET psql_resources_consumption_limits.mem_limit;
ALTER USER u2 RESET psql_resources_consumption_limits.cpu_limit;
ALTER USER u2 RESET psql_resources_consumption_limits.mem_exceeding_reaction;
ALTER USER u2 RESET psql_resources_consumption_limits.cpu_exceeding_reaction;Настройки тестовых ролей сброшены:
ALTER ROLE -
Выполните нагрузочные запросы от имени тестовых ролей:
-
От имени
u1, запрос, потребляющий память:psql -U u1 -
От имени
u2, запрос, потребляющий процессорное время:psql -U u2
Запущены
pg_backgroundпроцессы:pg_background_launch
----------------------
PID
(1 row) -
-
Проверьте, что запросы выполняются, процессы существуют:
ps aux | grep PID | grep -v grepИдентификаторы процессов существуют в системе. Пример вывода:
postgres 6344 100 0.0 4883224 12760 ? Rs 12:53 0:35 postgres: clustername: pg_background by PID 6339 DO -
Проверьте, что в логах базы присутствуют сообщения о превышении лимитов для всех нагрузочных запросов:
pglog | grep 'has violated the memory limit'
pglog | grep 'has violated the cpu limit'Но нет сообщений об остановке процессов:
pglog | grep 'Terminate process'Найдены логи о превышении лимитов. Пример вывода:
2023-10-22 12:55:00 MSK [6285]: [2171-1] app=psql_resources_consumption_limits checker,user=postgres,db=postgres,client=[bgworker],type=psql_resources_consumption_limits checker WARNING: The process 6324 memory consumption 46480 (session 46480) has violated the memory limit 32768
2023-10-22 12:55:17 MSK [6285]: [2496-1] app=psql_resources_consumption_limits checker,user=postgres,db=postgres,client=[bgworker],type=psql_resources_consumption_limits checker WARNING: The process 6344 cpu consumption 99 (session 99) has violated the cpu limit 50Сообщения об остановке процессов отсутствуют.
-
Остановите нагрузочные запросы:
kill -SIGTERM PIDПроцесс остановлен, вывод команд не содержит ошибок.