psql_resources_consumption_limits. Контроль потребления ресурсов#

В исходном дистрибутиве установлено по умолчанию: нет.

Связанные компоненты: отсутствуют.

Схема размещения: ext.

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

Внимание!

Процессы расширений ограничены в соответствии с установленными лимитами (включая задания pg_cron и т.п.).

В Pangolin поддерживается:

  • функциональность фиксированного задания ограничений ресурсов для процессов сессий СУБД;

  • завершение с ошибкой сессии, превысившей ограничение на потребление ресурса, и всех ее подпроцессов;

  • обнаружение превышения квоты на ресурсы асинхронно.

Примечание:

Управление ограничениями на уровне отдельной сессии не поддерживается.

Подробнее с функциональностью «Контроль потребления ресурсов БД» можно ознакомиться в одноименном разделе документа «Руководство администратора».

Доработка#

Доработка не проводилась.

Ограничения#

Ограничения отсутствуют.

Установка#

Для установки расширения и включения функциональности контроля потребления ресурсов выполните шаги:

  1. Добавьте имя библиотеки расширения в параметр shared_preload_libraries конфигурационного файла postgresql.conf/postgres.yml:

    shared_preload_libraries = 'psql_resources_consumption_limits'
    
  2. Перечитайте конфигурацию и перезагрузите кластер:

    pangolin-manager-ctl -c /etc/pangolin-manager/postgres.yml reload clustername
    
    pangolin-manager-ctl -c /etc/pangolin-manager/postgres.yml restart clustername
    
  3. Выполните команду по добавлению расширения (для создания представления мониторинга):

    CREATE EXTENSION psql_resources_consumption_limits;
    

Примечание:

Необходимо учесть увеличение background worker на единицу, и увеличить лимит background worker.

Отключение функциональности#

Для отключения функциональности:

  1. Выполните команду по удалению расширения:

    DROP EXTENSION psql_resources_consumption_limits;
    
  2. Удалите имя библиотеки расширения из параметра shared_preload_libraries конфигурационного файла postgresql.conf/postgres.yml:

    shared_preload_libraries = 'psql_resources_consumption_limits'
    
  3. Перезагрузите кластер:

    restart --force && reload --force
    

Примечание:

Если требуется временное отключение функциональности для всех ролей, без удаления расширения, то это возможно сделать, установив параметр psql_resources_consumption_limits.check_interval в нулевое значение.

Настройка#

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

Пример:

psql_resources_consumption_limits.check_interval
  • mem_limit - ограничение на суммарное потребление оперативной памяти одной сессией;

    Задается в килобайтах kB (kilobytes), мегабайтах MB (megabytes), гигабайтах GB (gigabytes), терабайтах TB (terabytes), без указания единиц — килобайты.

    Допускаются только положительные целочисленные значения. При указании отрицательного значения или лимита, превышающего физическую память КТС (параметр MemTotal в файле /proc/meminfo), Pangolin не запускается с выводом ошибки о недопустимом значении или превышении лимита. Если задано нулевое значение, то контроль за потреблением оперативной памяти отключен. По умолчанию лимит равен нулю (контроль отключен).

  • cpu_limit - ограничение на процент потребления ядер CPU всеми процессами одной сессии;

    Задается в процентах.

    Допускаются положительные целочисленные значения. При указании отрицательного значения или лимита превышающего количество ядер CPU КТС, умноженных на 100, Pangolin не запускается с выводом ошибки о невалидном значении или превышении лимита. Если задано нулевое значение, то контроль за потреблением CPU отключен. По умолчанию лимит равен нулю (контроль отключен).

    Допускаются значения больше 100, например, 350, что означает: «потребление CPU всеми процессами сессии не может превысить 3.5 ядер»».

  • mem_exceeding_reaction - реакция на превышение лимита потребления оперативной памяти:

    • terminate (значение по умолчанию) - прерывание всех процессов сессии с выводом сообщения в лог;

    • alert - вывод сообщения в лог о превышении лимита;

  • cpu_exceeding_reaction - реакция на превышение лимита потребления CPU:

    • terminate (значение по умолчанию) - прерывание всех процессов сессии с выводом сообщения в лог;

    • alert - вывод сообщения в лог о превышении лимита;

  • alert_log_level - уровень лога для реакций alert на превышения лимитов. Принимает значения:

    • debug5;

    • debug4;

    • debug3;

    • debug2;

    • debug1;

    • debug;

    • info;

    • notice;

    • log;

    • warning (значение по умолчанию);

Примечание:

При установке mem_exceeding_reaction, cpu_exceeding_reaction и alert_log_level в значения, отличные от допустимых, выводится предупреждение о невалидности параметра, и используется значение по умолчанию.

  • alert_timeout - время ожидания для повторного вывода сообщения в лог (задается в единицах времени);

    Отрицательные значения не допускаются, максимальное значение - 1 час. Если процесс продолжает выполняться после превышения лимита (реакция на превышение лимита - вывод сообщения в лог), то следующее сообщение о его превышении появится не раньше, чем через установленный тайм-аут. Если установлено нулевое значение, то сообщения выводятся на каждое превышение лимита. Значение по умолчанию - 1 секунда. При указании отрицательного значения или значения, превышающего 1 час, выводится предупреждение о невалидном параметре и используется значение по умолчанию.

  • check_interval - интервал контроля превышения.

    Задается во временных единицах. Отрицательные значения не допускаются, максимальное значение – 5 минут. Если задано нулевое значение, то контроль за потреблением оперативной памяти и CPU отключен. Значение по умолчанию – 30 с. Если задано значение отличное от нуля и включен контроль хотя бы за одним из ресурсов, то процесс будет периодически запускаться с заданным интервалом времени и проверять превышение лимитов.

Параметры можно изменять без перезапуска сервера.

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

Параметры (кроме интервала контроля) могут быть заданы суперпользователем отдельно для каждой роли через ALTER ROLE ... SET name=value;. В этом случае реакция на их превышение и лимиты сессий в рамках данной роли будут проверяться с учетом этих параметров. Как и при определении соответствующих параметров в конфигурации сервера, ограничение будет применяться к каждой из сессий по отдельности. В каждой из сессий значение параметра для роли переопределяет общее значение. Контроль суммарного потребления ресурсов всеми пользовательскими сессиями не выполняется.

Использование модуля#

Примечание

Примеры использования представлены для конфигурации standalone-patroni-pgbouncer.

Подготовительные действия#

В конфигурационном файле /etc/patroni/postgres.yml:

  1. Отключите парольные политики:

    password_policies_enable: off
    
  2. Добавьте расширение psql_resources_consumption_limits для включения функциональности контроля ресурсов:

    shared_preload_libraries = 'psql_resources_consumption_limits'
    
  3. Настройте период проверки лимитов:

    psql_resources_consumption_limits.check_interval: 100ms
    
  4. Добавьте тестовых пользователей в конфигурационный файл pg_hba.conf:

    host all u1 {IP-address}/{port} trust
    host all u2 {IP-address}/{port} trust
    host all u3 {IP-address}/{port} trust
    
  5. Разрешите тестовым пользователям авторизовываться без пароля:

    enabled_extra_auth_methods: trust
    
  6. Перечитайте конфигурацию на кластере:

    restart --force && reload --force
    

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

  1. Создайте тестовые роли:

    CREATE USER u1 WITH PASSWORD 'u1';
    CREATE USER u2 WITH PASSWORD 'u2';
    CREATE USER u3 WITH PASSWORD 'u3';
    
  2. Создайте расширения контроля потребления ресурсов:

    CREATE EXTENSION psql_resources_consumption_limits;
    
  3. Создайте расширения pg_background:

    CREATE EXTENSION pg_background;
    
  4. Разрешите тестовым пользователям использовать расширение 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;
    
  5. Разрешите тестовым пользователям использовать функции из схемы 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 для реакций на превышения памяти/процессора запросы будут остановлены досрочно, в логах будет информация о нарушении лимитов.

  1. Включите лимиты потребления ресурсов и установите значение 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>
    
  2. Сбросьте настройки лимитов потребления ресурсов для всех тестовых ролей:

    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
    
  3. Выполните нагрузочные запросы от имени тестовых ролей:

    1. От имени u1, запрос, потребляющий память:

      psql -U u1
      
    2. От имени u2, запрос, потребляющий процессорное время:

      psql -U u2
      

    Запущены pg_background процессы:

    pg_background_launch
    ----------------------
    PID
    (1 row)
    
  4. Проверьте, что запросы не выполняются, процессов не существует:

    ps aux | grep PID | grep -v grep
    

    Идентификаторы процессов не найдены в системе.

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

    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 для реакций на превышения памяти/процессора запросы не будут остановлены досрочно, но в логах будет информация о нарушении лимитов.

  1. Включите лимиты потребления ресурсов и установить значение 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>
    
  2. Сбросьте настройки лимитов потребления ресурсов для всех тестовых ролей:

    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
    
  3. Выполните нагрузочные запросы от имени тестовых ролей:

    1. От имени u1, запрос, потребляющий память:

      psql -U u1
      
    2. От имени u2, запрос, потребляющий процессорное время:

      psql -U u2
      

    Запущены pg_background процессы:

    pg_background_launch
    ----------------------
    PID
    (1 row)
    
  4. Проверьте, что запросы выполняются, процессы существуют:

    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
    
  5. Проверьте, что в логах базы присутствуют сообщения о превышении лимитов для всех нагрузочных запросов:

    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
    

    Сообщения об остановке процессов отсутствуют.

  6. Остановите нагрузочные запросы:

    kill -SIGTERM PID
    

    Процесс остановлен, вывод команд не содержит ошибок.