Привет, Я DocuDroid!
Оценка ИИ поиска
Спасибо за оценку нашего ИИ поиска!
Мы будем признательны, если вы поделитесь своими впечатлениями, чтобы мы могли улучшить наш ИИ поиск для вас и других читателей.
GitHub

Использование diskquota

Павел Семёнов
Contents

diskquota — это модуль Greengage DB, который позволяет ограничивать использование дискового пространства на хостах кластера.

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

Исходный код diskquota доступен в репозитории diskquota.

Сборка и установка

Предварительные условия

Для сборки diskquota необходимы git и cmake версии 3.20 или новее.

Чтобы начать использовать diskquota, необходимо собрать его из исходного кода и установить полученные бинарные файлы на всех хостах кластера:

  1. Войдите в систему как gpadmin.

  2. Клонируйте репозиторий diskquota с указанием нужного тега:

    $ git clone --branch 2.4.1 https://github.com/GreengageDB/diskquota.git
  3. Перейдите в каталог diskquota:

    $ cd diskquota
  4. Создайте каталог build и перейдите в него:

    $ mkdir -p build
    $ cd build
  5. Скомпилируйте модуль:

    $ cmake ..

    Вывод должен завершиться сообщением следующего вида:

    -- Build files have been written to: /home/gpadmin/diskquota/build
  6. Установите модуль:

    $ make install

    Вывод команды содержит сообщение с расположением и именем файла модуля:

    -- Installing: /usr/local/gpdb/lib/postgresql/diskquota-2.4.so

Чтобы проверить, что diskquota установлен успешно, подключитесь к любой базе данных кластера с помощью psql и проверьте доступные расширения:

SELECT * FROM pg_available_extensions WHERE name = 'diskquota';

Результат:

   name    | default_version | installed_version |         comment
-----------+-----------------+-------------------+-------------------------
 diskquota | 2.4             |                   | Disk Quota Main Program
(1 row)

Включение diskquota

Чтобы сделать diskquota доступным на уровне кластера:

  1. Создайте базу данных с именем diskquota. Модуль использует ее для хранения метаданных о базах данных, в которых он включен.

    $ createdb diskquota
  2. Добавьте diskquota с указанием версии в текущий список предварительно загружаемых библиотек:

    $ gpconfig -c shared_preload_libraries -v '<current_value>,diskquota-2.4'

    где <current_value> — значение параметра конфигурации shared_preload_libraries до выполнения этого шага (может быть пустым).

    РЕКОМЕНДАЦИЯ

    Вы можете получить текущее значение shared_preload_libraries с помощью gpconfig -s или использовать следующий вызов gpconfig, чтобы добавить diskquota в список, сохранив текущее значение:

    $ gpconfig -c shared_preload_libraries \
             -v "$(psql -At -c "SELECT array_to_string(array_append(string_to_array(current_setting('shared_preload_libraries'), ','), 'diskquota-2.4'), ',')" postgres)"
  3. Перезапустите кластер:

    $ gpstop -r

Активация diskquota в базе данных

Чтобы начать применять лимиты дискового пространства в базе данных, подключитесь к ней с помощью psql и зарегистрируйте расширение diskquota:

CREATE EXTENSION diskquota;

Затем инициализируйте diskquota, передав ему информацию о текущем размере таблиц с помощью функции diskquota.init_table_size_table(). Эта операция может занять некоторое время.

SELECT diskquota.init_table_size_table();

Лимиты diskquota

Что учитывается

Использование диска таблицей рассчитывается как суммарный размер ее файлов данных, индексов, TOAST-таблиц и карты свободного пространства. Для оптимизированных для добавления (AO) таблиц использование диска также включает таблицы их карты видимости (включая ее индекс типа B-дерево) и каталога блоков.

ВАЖНО

diskquota учитывает размер, который файлы таблицы занимают на диске, а не размер видимых строк таблицы. Подробнее о видимых и устаревших строках см. в статье Удаление устаревших строк с помощью VACUUM.

Если суммарный размер этих объектов превышает настроенный лимит, таблица попадает в блок-лист (denylist) diskquota. Это блокирует для данной таблицы все операции изменения данных, увеличивающие использование диска (такие как INSERT, UPDATE и COPY), до выполнения одного из следующих условий:

  • Размер таблицы становится меньше лимита в результате операций DROP, TRUNCATE или VACUUM FULL.

    ПРИМЕЧАНИЕ

    Удаление строк и обычный VACUUM (без FULL) не освобождают дисковое пространство немедленно, поэтому эти операции не помогают удалить таблицу из блок-листа.

  • Лимит увеличен выше текущего размера таблицы с помощью функций diskquota.

Операции, читающие данные из таблиц, например SELECT, всегда разрешены.

Когда проверяются лимиты

diskquota проверяет использование диска периодически, а не непрерывно. Из-за этого возможна задержка между превышением лимита и добавлением таблицы в блок-лист, а также между освобождением пространства и ее удалением из блок-листа.

Кроме того, при использовании мягких лимитов (см. раздел Мягкие и жесткие лимиты ниже) проверки квот выполняются только перед выполнением операторов, которые могут увеличить использование диска. В результате некоторые операции могут превышать настроенные лимиты.

Чтобы настроить интервал между проверками использования диска, используйте параметр конфигурации diskquota.naptime (в секундах).

Уровни применения квот

diskquota позволяет задавать лимиты использования диска на следующих уровнях:

  • Уровень схемы — дисковое пространство, доступное всем таблицам в одной схеме.

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

  • Уровень схемы в табличном пространстве — дисковое пространство, доступное всем таблицам определенной схемы в конкретном табличном пространстве.

  • Уровень роли в табличном пространстве — дисковое пространство, доступное всем таблицам, принадлежащим определенной роли, в конкретном табличном пространстве.

  • Уровень табличного пространства на сегмент — дисковое пространство, которое может использоваться на одном сегменте при применении квоты схемы или роли в табличном пространстве.

Мягкие и жесткие лимиты

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

Жесткие лимиты обеспечивают более строгое ограничение. При их включении diskquota также проверяет лимиты во время выполнения оператора и прерывает его, если лимит превышен. Чтобы включить жесткие лимиты, установите параметр конфигурации diskquota.hard_limit в значение on.

ВАЖНО

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

Рабочие процессы diskquota

diskquota использует фоновые рабочие процессы на мастер-хосте.

Один процесс запуска (launcher) diskquota управляет несколькими рабочими процессами (worker). Рабочие процессы отвечают за сбор информации о размере таблиц и применение квот в базах данных. Количество рабочих процессов определяется параметром конфигурации diskquota.max_workers.

ПРИМЕЧАНИЕ

Рабочие процессы берутся из общего пула фоновых процессов Greengage DB, размер которого определяется параметром конфигурации сервера max_worker_processes. Поэтому значение diskquota.max_workers не может превышать max_worker_processes.

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

Если баз данных с diskquota больше, чем доступных рабочих процессов, diskquota переключается в динамический режим. В этом режиме процесс launcher запускает и останавливает рабочие процессы при каждой проверке использования диска (то есть каждые diskquota.naptime секунд).

Общее количество баз данных, объекты которых могут отслеживаться diskquota одновременно, ограничено параметром конфигурации diskquota.max_monitored_databases.

Установка и снятие квоты диска

diskquota предоставляет следующие функции для установки и удаления квоты диска на разных уровнях:

  • set_schema_quota() — квота на уровне схемы;

  • set_role_quota() — квота на уровне роли;

  • set_schema_tablespace_quota() — квота на уровне схемы в табличном пространстве;

  • set_role_tablespace_quota() — квота на уровне роли в табличном пространстве;

  • set_per_segment_quota() — квота табличного пространства на сегмент.

Функции принимают идентификаторы объектов и значения лимитов в качестве аргументов. Значения лимитов должны включать единицу измерения: MB, GB, TB или PB.

Чтобы снять квоту, укажите значение лимита -1. Это отменяет ограничение и позволяет объекту использовать все доступное дисковое пространство (с учетом других квот, если они есть).

ВАЖНО

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

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

Квота схемы или роли

Чтобы ограничить размер всех таблиц в схеме до 300 GB, вызовите diskquota.set_schema_quota():

SELECT diskquota.set_schema_quota('sales', '300 GB');

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

SELECT diskquota.set_role_quota('alice', '10 GB');

Чтобы снять квоту для указанной схемы или роли, вызовите те же функции с -1 в качестве лимита:

SELECT diskquota.set_schema_quota('sales', '-1');

Квота табличного пространства для схем и ролей

Квоты табличного пространства ограничивают объем дискового пространства, который схема или роль может использовать в конкретном табличном пространстве. Это полезно, когда разные табличные пространства используют разные типы хранилища, например быстрое или архивное.

Чтобы задать квоты на уровне табличного пространства, используйте функции set_schema_tablespace_quota() и set_role_tablespace_quota(). Их аргументы — имя схемы или роли, имя табличного пространства и значение квоты с единицей измерения.

Примеры:

SELECT diskquota.set_schema_tablespace_quota('sales', 'fast_storage', '10 GB');
SELECT diskquota.set_role_tablespace_quota('alice', 'fast_storage', '500 MB');

Чтобы снять квоту табличного пространства для указанной схемы или роли, вызовите те же функции с -1 в качестве лимита:

SELECT diskquota.set_schema_tablespace_quota('sales', 'fast_storage', '-1');

Квота табличного пространства на сегмент

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

Используйте функцию diskquota.set_per_segment_quota() для настройки этого лимита. Ее аргументы — имя табличного пространства и значение коэффициента.

Коэффициент определяет предел использования дискового пространства одним сегментом по отношению к среднему значению на сегмент. Среднее значение рассчитывается так:

average_per_segment = tablespace_quota / segment_num

Коэффициент выступает множителем для этого среднего значения.

Например, для схемы задана квота в табличном пространстве 80 ГБ:

SELECT diskquota.set_schema_tablespace_quota('sales', 'fast_storage', '80 GB');

Если в кластере 8 основных сегментов, среднее использование на сегмент составляет 80 GB / 8, то есть 10 ГБ. Чтобы разрешить одному сегменту превышать это значение до двух раз, установите коэффициент 2.0:

SELECT diskquota.set_per_segment_quota('fast_storage', '2.0');

В этом случае любой отдельный сегмент может использовать до 20 ГБ в табличном пространстве fast_storage для схемы sales. При этом суммарное использование всеми сегментами не может превышать 80 ГБ.

Чтобы снять квоту табличного пространства на сегмент, вызовите функцию с -1 в качестве коэффициента:

SELECT diskquota.set_per_segment_quota('fast_storage', '-1');

Это отменяет квоту на сегмент, оставляя квоту табличного пространства на уровне схемы в 80 ГБ в силе.

Обратите внимание, что квота на сегмент хранится в виде коэффициента, а не абсолютного значения. Если квота табличного пространства изменяется с помощью set_schema_tablespace_quota() или set_role_tablespace_quota(), эффективный лимит на сегмент изменяется соответственно.

Мониторинг использования diskquota

Просмотр информации о модуле diskquota

Функция diskquota.status() возвращает общую информацию о модуле diskquota:

SELECT diskquota.status();

Пример результата:

              status
----------------------------------
 ("soft limits",on)
 ("hard limits",off)
 ("current binary version",2.4.0)
 ("current schema version",2.4)
(4 rows)

Просмотр отслеживаемых баз данных

Чтобы просмотреть базы данных, в которых включен diskquota, выполните запрос к таблице diskquota_namespace.database_list в базе данных diskquota:

\c diskquota
SELECT d.datname
FROM diskquota_namespace.database_list q,
     pg_database d
WHERE q.dbid = d.oid
ORDER BY d.datname;

Пример результата:

   datname
-------------
 marketplace
 books_store
(2 rows)

Просмотр настроенных квот и использования диска

Следующие представления показывают настроенные квоты и использование диска в текущей базе данных:

  • diskquota.show_fast_schema_quota_view — активные квоты на уровне схемы:

    SELECT * FROM diskquota.show_fast_schema_quota_view;

    Пример результата:

      schema_name | schema_oid | quota_in_mb | nspsize_in_bytes
    --------------+------------+-------------+------------------
     sales        |      16653 |        1024 |         52690944
    (1 row)
  • diskquota.show_fast_role_quota_view — активные квоты на уровне роли:

    SELECT * FROM diskquota.show_fast_role_quota_view;

    Пример результата:

     role_name | role_oid | quota_in_mb | rolsize_in_bytes
    -----------+----------+-------------+------------------
     alice     |    16657 |        1024 |        360972288
    (1 row)
  • diskquota.show_fast_schema_tablespace_quota_view — активные квоты на уровне схемы в табличном пространстве:

    SELECT * FROM diskquota.show_fast_schema_tablespace_quota_view;

    Пример результата:

      schema_name | schema_oid | tablespace_name | tablespace_oid | quota_in_mb | nspsize_tablespace_in_bytes
    --------------+------------+-----------------+----------------+-------------+-----------------------------
     sales        |      16653 | fast_storage    |          16671 |          90 |                      786432
    (1 row)
  • diskquota.show_fast_role_tablespace_quota_view — активные квоты на уровне роли в табличном пространстве:

    SELECT * FROM diskquota.show_fast_role_tablespace_quota_view;

    Пример результата:

     role_name | role_oid | tablespace_name | tablespace_oid | quota_in_mb | rolsize_tablespace_in_bytes
    -----------+----------+-----------------+----------------+-------------+-----------------------------
     alice     |    16657 | fast_storage    |          16671 |          90 |                           0
    (1 row)
  • diskquota.show_segment_ratio_quota_view — квоты диска на сегмент (коэффициенты):

    SELECT * FROM diskquota.show_segment_ratio_quota_view;

    Пример результата:

     tablespace_name | tablespace_oid | per_seg_quota_ratio
    -----------------+----------------+---------------------
     fast_storage    |          16671 |                   2
    (1 row)

Пример: использование квоты диска на уровне схемы

  1. Создайте схему в базе данных с включенным diskquota:

    CREATE SCHEMA limited_schema;
  2. Установите лимит 1 МБ для этой схемы с помощью diskquota.set_schema_quota():

    SELECT diskquota.set_schema_quota('limited_schema', '1 MB');
  3. Создайте таблицу в схеме и вставьте небольшой объем данных, не превышающий лимит:

    CREATE TABLE limited_schema.counter_table(i int);
    INSERT INTO limited_schema.counter_table SELECT generate_series(1,100);

    Операция выполняется успешно, так как квота не превышена.

    Проверьте текущее использование дискового пространства в представлении diskquota.show_fast_schema_quota_view:

    SELECT * FROM diskquota.show_fast_schema_quota_view;

    Результат:

      schema_name   | schema_oid | quota_in_mb | nspsize_in_bytes
    ----------------+------------+-------------+------------------
     limited_schema |      16653 |           1 |           131072
    (1 row)
  4. Вставьте большой объем данных, превышающий лимит 1 МБ:

    INSERT INTO limited_schema.counter_table SELECT generate_series(1,10000000);

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

    Теперь представление diskquota.show_fast_schema_quota_view показывает, что схема занимает значительно больше места, чем разрешено квотой:

    SELECT * FROM diskquota.show_fast_schema_quota_view;

    Результат:

      schema_name   | schema_oid | quota_in_mb | nspsize_in_bytes
    ----------------+------------+-------------+------------------
     limited_schema |      16653 |           1 |        360972288
    (1 row)

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

  5. Попробуйте вставить еще одну строку:

    INSERT INTO limited_schema.counter_table VALUES (10000001);

    Операция завершается с ошибкой:

    ERROR:  schema's disk space quota exceeded with name: limited_schema
  6. Чтобы снять квоту для схемы, установите ее значение в -1:

    SELECT diskquota.set_schema_quota('limited_schema', '-1');

    Операции изменения данных снова разрешены:

    INSERT INTO limited_schema.counter_table VALUES (10000001);

    Результат:

    INSERT 0 1

Пример: установка жесткого лимита

Чтобы проверить работу жестких лимитов:

  1. Снова установите квоту 1 МБ для схемы limited_schema и очистите таблицу counter_table:

    SELECT diskquota.set_schema_quota('limited_schema', '1 MB');
    TRUNCATE TABLE limited_schema.counter_table;
  2. Включите жесткие лимиты, установив параметр diskquota.hard_limit в значение on, и перезагрузите конфигурацию:

    $ gpconfig -c diskquota.hard_limit -v 'on'
    $ gpstop -u
  3. Попробуйте вставить объем данных, превышающий лимит:

    INSERT INTO limited_schema.counter_table SELECT generate_series(1,10000000);

    В этом случае оператор будет прерван во время выполнения, как только квота будет превышена:

    ERROR:  schema's disk space quota exceeded with name: 16653  (seg1 10.92.41.158:10001 pid=4105)

Прерывание логически откатывает изменения, сделанные оператором, поэтому COUNT(*) показывает, что таблица пуста:

SELECT COUNT(*) FROM limited_schema.counter_table;

Результат:

 count
-------
     0
(1 row)

Тем не менее, файлы данных, созданные оператором до прерывания, остаются на диске. Это можно проверить с помощью pg_total_relation_size():

SELECT pg_size_pretty(pg_total_relation_size('limited_schema.counter_table'));

Результат:

 pg_size_pretty
----------------
 76 MB
(1 row)
ПРИМЕЧАНИЕ

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

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

  • VACUUM FULL

  • TRUNCATE

  • DROP

Эти операции освобождают дисковое пространство и позволяют diskquota удалить таблицу из блок-листа при следующей периодической проверке.

Приостановка diskquota

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

SELECT diskquota.pause();
ПРИМЕЧАНИЕ

В некоторых случаях операции VACUUM и VACUUM FULL могут временно увеличить размер таблицы, что может привести к превышению настроенной квоты. Чтобы избежать потенциальных проблем, рекомендуется приостановить diskquota перед выполнением VACUUM и VACUUM FULL.

Чтобы возобновить проверки diskquota, вызовите diskquota.resume():

SELECT diskquota.resume();

Эффект diskquota.pause() не сохраняется при перезапуске кластера. При необходимости вызовите эту функцию снова после перезапуска, чтобы оставить diskquota в приостановленном состоянии.

Выключение diskquota

Прекратить применение лимитов дискового пространства в кластере можно двумя способами:

  • Удалить расширение diskquota из базы данных.

  • Отключить diskquota на уровне кластера.

Выключение в базе данных

Чтобы прекратить применение квот в конкретной базе данных, удалите расширение diskquota. Перед удалением расширения рекомендуется вызвать diskquota.pause(), чтобы избежать возможных взаимных блокировок:

SELECT diskquota.pause();
DROP EXTENSION diskquota;

Выключение на уровне кластера

Чтобы полностью прекратить использование diskquota в кластере, удалите его из параметра конфигурации shared_preload_libraries:

$ gpconfig -c shared_preload_libraries -v '<value_without_diskquota>'

где <value_without_diskquota> — текущее значение shared_preload_libraries (полученное с помощью gpconfig -s shared_preload_libraries) без записи diskquota-<version>.

Затем перезапустите кластер:

$ gpstop -r

Чтобы снова включить diskquota, повторите шаги, описанные в Включение diskquota.

Справочник функций

init_table_size_table() returns void

Вычисляет размеры объектов базы данных для расширения diskquota. Вызовите эту функцию после создания расширения diskquota в базе данных, чтобы инициализировать внутренние метаданные, используемые для применения квот.

set_role_quota(role_name text, quota text) returns void

Устанавливает квоту диска для роли. Суммарный размер всех отношений, принадлежащих этой роли в текущей базе данных, не может превышать данный лимит. Квота должна задаваться строкой, состоящей из числа и единицы измерения: MB, GB, TB или PB.

set_role_tablespace_quota(role_name text, tablespace_name text, quota text) returns void

Устанавливает квоту диска для роли в табличном пространстве. Суммарный размер всех отношений, принадлежащих этой роли в указанном табличном пространстве, не может превышать данный лимит. Квота должна задаваться строкой, состоящей из числа и единицы измерения: MB, GB, TB или PB.

set_schema_quota(schema_name text, quota text) returns void

Устанавливает квоту диска для схемы. Суммарный размер всех отношений в этой схеме не может превышать данный лимит. Квота должна задаваться строкой, состоящей из числа и единицы измерения: MB, GB, TB или PB.

set_schema_tablespace_quota(schema_name text, tablespace_name text, quota text) returns void

Устанавливает квоту диска для схемы в табличном пространстве. Суммарный размер всех отношений в этой схеме в указанном табличном пространстве не может превышать данный лимит. Квота должна задаваться строкой, состоящей из числа и единицы измерения: MB, GB, TB или PB.

set_per_segment_quota(tablespace_name text, ratio float4) returns void

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

pause() returns void

Временно отключает применение квот, прекращая выдачу ошибок при превышении лимитов. Обратите внимание, что фоновые процессы diskquota продолжают работать и собирать статистику размеров.

resume() returns void

Возобновляет применение квот после их приостановки с помощью pause().

status() returns table

Отображает версии бинарного файла и схемы diskquota, а также состояние применения мягких и жестких лимитов в текущей базе данных. Результат содержит два столбца: name и status.

Справочник параметров конфигурации

diskquota.hard_limit

Включает или отключает жесткие лимиты использования диска. При включении SQL-запросы завершаются во время выполнения, как только квота превышена.

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

Диапазон значений Значение по умолчанию Область определения Контекст

boolean

off

master

sighup

diskquota.hashmap_overflow_report_timeout

Задает интервал (в секундах) между предупреждениями о переполнении общей хеш-таблицы diskquota.

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

Диапазон значений Значение по умолчанию Область определения Контекст

0 — INT_MAX / 1000

60

master

superuser

diskquota.max_active_tables

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

Увеличьте это значение в средах с большим количеством часто изменяемых таблиц.

Диапазон значений Значение по умолчанию Область определения Контекст

1 — INT_MAX

307200

master

postmaster

diskquota.max_monitored_databases

Задает максимальное количество баз данных, которые diskquota может одновременно отслеживать. Если этот лимит достигнут, дополнительные базы данных с включенным расширением diskquota не будут отслеживаться.

Увеличьте это значение в кластерах с большим количеством баз данных, использующих diskquota.

Диапазон значений Значение по умолчанию Область определения Контекст

1 — 1024

50

master

postmaster

diskquota.max_quota_probes

Задает максимальное количество объектов quota probe в кластере. Quota probe — это внутренний объект, обеспечивающий отслеживание одной конкретной квоты, например, для роли или схемы. diskquota создает probe для всех объектов, размер которых можно ограничить, даже если квоты для них не установлены. Например, если в кластере 100 ролей, создаются 100 probe, даже если квоты установлены только для 10 ролей.

Учитывая возможные уровни установки квот, значение diskquota.max_quota_probes должно быть не меньше:

role_num * database_num + schema_num + role_num * tablespace_num * database_num + schema_num * tablespace_num

где:

  • role_num — количество ролей в кластере;

  • database_num — количество баз данных;

  • schema_num — количество схем в кластере;

  • tablespace_num — количество табличных пространств в кластере.

Более высокие значения позволяют обрабатывать больше новых объектов, создаваемых со временем, но увеличивают потребление памяти (48 байт на один probe).

Диапазон значений Значение по умолчанию Область определения Контекст

131072 — INT_MAX

1048576

master

postmaster

diskquota.max_reject_entries

Задает максимальное количество записей в блок-листе на одну базу данных. Каждая запись соответствует объекту (например, схеме или роли), превысившему квоту. Если этот лимит достигнут, новые нарушения могут отслеживаться некорректно.

Увеличьте это значение в средах с большим количеством одновременно превышенных квот.

Диапазон значений Значение по умолчанию Область определения Контекст

1 — INT_MAX

8192

master

postmaster

diskquota.max_table_segments

Задает максимальное количество сегментов таблиц, которые может отслеживать diskquota.

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

Диапазон значений Значение по умолчанию Область определения Контекст

131072 — INT_MAX

10485760

master

postmaster

diskquota.max_workers

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

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

Подробнее см. Рабочие процессы diskquota.

Диапазон значений Значение по умолчанию Область определения Контекст

1 — 20

10

master

postmaster

diskquota.naptime

Задает интервал (в секундах) между периодическими вычислениями размера отношений.

Меньшие значения повышают отзывчивость применения квот, но увеличивают нагрузку на систему. Большие значения уменьшают нагрузку, но увеличивают задержку между превышением квоты и ее применением.

Настраивайте этот параметр в зависимости от требуемого баланса между скоростью работы diskquota и производительностью.

Диапазон значений Значение по умолчанию Область определения Контекст

1 — INT_MAX

2

master

sighup

diskquota.worker_timeout

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

Увеличьте это значение в средах с большими объемами данных или медленным хранилищем.

Диапазон значений Значение по умолчанию Область определения Контекст

1 — INT_MAX

60

master

sighup