Справочник системных ошибок и решений

Windows Server, Active Directory, 1С:Предприятие, СУБД, Linux, Cisco, MikroTik, Asterisk.

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

PG_INDEX_BLOAT Linux / DevOps

Траблшутинг раздувания индексов (Index Bloat) в PostgreSQL: REINDEX CONCURRENTLY

Обновлено: 24.08.2026
  • Резкое замедление выполнения SELECT-запросов, использующих индексное сканирование (Index Scan / Index Only Scan).
  • Объем индексов на диске значительно превышает размер самих таблиц при отсутствии роста количества записей.
  • Увеличение времени прогрева буферного кэша (Buffer Cache Hit Ratio падает, растет Read I/O).
  • Высокая фрагментация B-Tree страниц после массовых операций UPDATE и DELETE.

1. Диагностика процента раздувания (Bloat) через расширение pgstattuple

CREATE EXTENSION IF NOT EXISTS pgstattuple;

-- Проверка конкретного индекса
SELECT * FROM pgstatindex('idx_orders_created_at');

-- Вычисление мертвого пространства (dead_tuple_percent / free_space)

2. Запрос для поиска топ-10 самых раздутых индексов в БД

SELECT
    schemaname, tablename, indexname,
    pg_size_pretty(pg_relation_size(indexrelid)) AS index_size,
    pg_size_pretty(pg_relation_size(indrelid)) AS table_size
FROM pg_stat_user_indexes
ORDER BY pg_relation_size(indexrelid) DESC
LIMIT 10;

3. Онлайн-перестроение индекса без эксклюзивных блокировок DML

-- Перестроение конкретного индекса в неблокирующем режиме
REINDEX INDEX CONCURRENTLY idx_orders_created_at;

-- Перестроение всех индексов таблицы
REINDEX TABLE CONCURRENTLY public.orders;

4. Тюнинг параметров Autovacuum для предотвращения повторного Bloat

Добавьте настройки в postgresql.conf или примените точечно к таблице:

ALTER TABLE orders SET (
    autovacuum_vacuum_scale_factor = 0.05,
    autovacuum_vacuum_threshold = 500,
    autovacuum_vacuum_cost_limit = 1000
);
💡 Практика специалистов: REINDEX CONCURRENTLY создает двойную нагрузку на дисковую подсистему и требует дополнительного дискового пространства, равного размеру нового индекса. Всегда контролируйте свободное место в PGDATA перед запуском.

Частые вопросы (FAQ)

Чем REINDEX CONCURRENTLY отличается от обычного REINDEX?

Обычный REINDEX берет жесткую блокировку ACCESS EXCLUSIVE на таблицу, блокируя любые операции чтения и записи. REINDEX CONCURRENTLY создает дубликат индекса в фоновом режиме под слабой блокировкой ShareUpdateExclusiveLock, не прерывая транзакции приложения.

Что делать, если выполнение REINDEX CONCURRENTLY завершилось ошибкой?

В каталоге останется невалидный индекс с суффиксом '_ccnew' или '_ccold'. Найдите его запросом `SELECT relname FROM pg_class WHERE relisvalid = false;` и удалите командой DROP INDEX CONCURRENTLY <имя_индекса>.

Полезные материалы
Рекомендуем