PostgreSQL. Часть 6. Регулярное обслуживание PostgreSQL

В моем блоге уже был цикл статей с конспектом по MySQL. Эта одна из публикаций цикла конспектов по PostgreSQL. Материал этих публикаций не особо структурирован и представляет собой просто мои заметки – конспектировал что-то новое и то, что я посчитал интересным и важным. Эта публикация посвящена тому, как выполняется регулярное обслуживание PostgreSQL.

Список литературы

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

1. Книга PostgreSQL 14 Administration Cookbook.

2. Курс DBA1: Администрирование PostgreSQL 13. Базовый курс.

Регулярное обслуживание

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

Убедитесь, что функции самоочитски включены. Нужно проверить – включен ли autovacuum в конфигурационном файле postgresql.conf:

sudo nano /etc/postgresql/12/main/postgresql.conf
autovacuum = on
track_counts = on

По умолчанию автоочистка включена.

Максимально количество процессов самоочистки работающих параллельно задается параметром autovacuum_max_workers в конфигурационном файле postgresql.conf. Каждый из этих процессов генерирует определенную нагрузку. Вся нагрузка всех процессов самоочитски суммируется и не может быть больше значения параметра autovacuum_vacuum_cost_limit в конфигурационном файле postgresql.conf. Это необходимо для того, чтобы процессы самоочитски не использовали абсолютно все ресурсы сервера. Увеличение значение параметра autovacuum_vacuum_cost_delay замедлит процесс самоочитски и немного высвободит ресурсы сервера. Однако, этого не рекомендуется делать.

Пример конфигурации более агрессивной автоматической очистки. Параметры в конфигурационном файле postgresql.conf:

autovacuum = on
autovacuum_max_workers = 3
autovacuum_analyze_scale_factor = 0.05
autovacuum_vacuum_cost_delay = 0
autovacuum_vacuum_scale_factor = 0.1

Пример конфигурации менее агрессивной автоматической очистки. Параметры в конфигурационном файле postgresql.conf:

autovacuum = on
autovacuum_max_workers = 3
autovacuum_analyze_scale_factor = 0.1
autovacuum_vacuum_cost_delay = 5
autovacuum_vacuum_scale_factor = 0.2

Устранение проблем с раздуванием

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

Самый первый шаг в диагностике – посмотреть самый старый снимок данных:

SELECT now() -
CASE
WHEN backend_xid IS NOT NULL
THEN xact_start
ELSE query_start END
AS age
, pid
, backend_xid AS xid
, backend_xmin AS xmin
, state
FROM pg_stat_activity
WHERE backend_type = 'client backend'
ORDER BY 1 DESC;

Если какие-то сессии находятся в состоянии “idle_in_transaction”, то есть смысл установить значение параметра “idle_in_transaction_session_timeout”, например, в минуту или пару минут (зависит от профиля нагрузки на сервер и приложение, которое использует БД). Штатное значение этого параметра равно нулю, т.е. сессии или транзакции никогда не завершаются и потенциально могут выполняться день, два или более.

Если использование параметра “idle_in_transaction_session_timeout”не представляется возможным, то можно рассмотреть параметр “old_snapshot_threshold”. Он определяет время, после которого неиспользуемые строки могут быть удалены. Если какой-то запрос попытается прочитать такие строки, то он будет отменен. Для всех других запросов, время выполнения которых меньше значения параметра “old_snapshot_threshold ” никаких негативных эффектов не будет.

Обслуживание индексов

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

Например, можно переиндексировать одну конкретную базу данных:

reindexdb

Переиндексировать все базы данных:

reindexdb -a

Лучше всего индексировать отдельные таблицы, т.к. устанавливается AccessExclusiveLock в процессе перестроения индекса..

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

REINDEX INDEX CONCURRENTLY test_category_idx;

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

sudo -u postgres reindexdb --dbname app --concurrently -t postgres.t --verbose

Индексы

Запрос для определения частоты использования индексов:

SELECT schemaname, relname, indexrelname, idx_scan
FROM pg_stat_user_indexes ORDER BY idx_scan;

Осторожное удаление индексов

Не всегда безопасно удалять индекс сразу. Можно на время его “отключить”.

Запрос для отображения отключенных индексов:

SELECT ir.relname AS indexname
, it.relname AS tablename
, n.nspname AS schemaname
FROM pg_index i
JOIN pg_class ir ON ir.oid = i.indexrelid
JOIN pg_class it ON it.oid = i.indrelid
JOIN pg_namespace n ON n.oid = it.relnamespace
WHERE NOT i.indisvalid;

Процедура:

1. Создать функцию ля отключения индекса:

CREATE OR REPLACE FUNCTION trial_drop_index(iname
TEXT) RETURNS VOID
LANGUAGE SQL AS $$ UPDATE pg_index
SET indisvalid = false
WHERE indexrelid = $1::regclass;
$$;

2. Применить её к потенциально неиспользуемому индексу.

select trial_drop_index('idx_t_s');

3. Еще раз проверит список отключенных индексов:

SELECT ir.relname AS indexname
, it.relname AS tablename
, n.nspname AS schemaname
FROM pg_index i
JOIN pg_class ir ON ir.oid = i.indexrelid
JOIN pg_class it ON it.oid = i.indrelid
JOIN pg_namespace n ON n.oid = it.relnamespace
WHERE NOT i.indisvalid;

4. Функция для отмены удаления:

CREATE OR REPLACE FUNCTION trial_undrop_index(iname
TEXT) RETURNS VOID
LANGUAGE SQL AS
$$ UPDATE pg_index
SET indisvalid = true
WHERE indexrelid = $1::regclass;
$$;

5. Пример включения ранее отключенного индекса:

select trial_undrop_index('idx_t_s');

Другие связанные статьи

PostgreSQL. Часть 1. Информационные запросы PostgreSQL

PostgreSQL. Часть 2. Нюансы настройки сервера PostgreSQL

PostgreSQL. Часть 3. Управление сервером PostgreSQL

PostgreSQL. Часть 4. Безопасность в PostgreSQL

PostgreSQL. Часть 5. Мониторинг и диагностика PostgreSQL

PostgreSQL. Часть 7. Производительность и конкурентный доступ PostgreSQL

PostgreSQL. Часть 8. Резервное копирование и восстановление PostgreSQL

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *