INVALID-Indizes finden und bereinigen
PostgreSQLWartungBefehl
SELECT n.nspname AS schema_name,
c.relname AS index_name,
t.relname AS table_name,
pg_size_pretty(pg_relation_size(c.oid)) AS index_size,
i.indisvalid,
i.indisready,
format('DROP INDEX CONCURRENTLY %I.%I;', n.nspname, c.relname) AS fix
FROM pg_index i
JOIN pg_class c ON c.oid = i.indexrelid
JOIN pg_class t ON t.oid = i.indrelid
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE NOT i.indisvalid OR NOT i.indisready;
-- Before dropping: is an index build still in progress?
SELECT pid, relid::regclass AS table_name, index_relid::regclass AS index_name, command, phase
FROM pg_stat_progress_create_index;Was es tut
Listet ungültige Indizes, die fehlgeschlagene Läufe von CREATE INDEX CONCURRENTLY oder REINDEX CONCURRENTLY hinterlassen haben, mit ihrer Größe und erzeugt den Drop-Befehl.
Wann einsetzen
Nach fehlgeschlagenen oder abgebrochenen Online-Indexoperationen, bei routinemäßigen Health-Checks und vor einem Major-Upgrade.
Vorsicht
Ein laufendes CREATE INDEX CONCURRENTLY / REINDEX CONCURRENTLY erscheint ebenfalls als INVALID; prüfe vor dem Löschen pg_stat_progress_create_index. Ein INVALID-Index wird von Abfragen nicht genutzt, wird bei indisready = true aber weiterhin bei jedem INSERT/UPDATE gepflegt, ist also reiner Overhead. Er lässt sich mit REINDEX INDEX CONCURRENTLY neu aufbauen, was aber erneut fehlschlägt, solange die Ursache (z. B. eine Unique-Verletzung) nicht behoben ist. Reste von REINDEX CONCURRENTLY tragen das Suffix _ccnew/_ccold. DROP INDEX CONCURRENTLY kann nicht innerhalb eines Transaktionsblocks laufen.