Центр Диагностики & База Системных Ошибок

Решения для Windows Server, Active Directory, 1С, СУБД, Linux, Cisco, MikroTik и IP-телефонии.

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