Skip to content

Commit 069c440

Browse files
sonika-shahclaude
andauthored
Fixes #27158: tag_usage Postgres seq-scan (1.12.7 backport) (#27824)
* Fixes #27158: restore tag_usage prefix-LIKE index on Postgres The 1.11.0 perf migration (#23054) added four `WHERE state = 1` partial indexes on tag_usage; #24063 dropped the matching `state = 1` predicate from getTagsInternalByPrefix (Suggested-state rows are valid for both classification and glossary derivation), leaving every partial index inapplicable. Postgres fell back to a parallel seq scan; MySQL was unaffected because its 1.11.0 indexes were never partial. Adds non-partial single-col btrees on targetfqnhash_lower and tagfqn_lower (mirror MySQL's idx_targetfqnhash_lower / idx_tagfqn_lower) and rebuilds the four partials as non-partial -- same shape, same INCLUDE columns, predicate coupling removed so future query changes can't silently invalidate them. Backport of #27745 (main) onto the 1.12.7 release line so customers on 1.12.x get the fix without waiting for 2.0.x. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Drop new indexes before CREATE to defuse failed-CONCURRENTLY edge case If CREATE INDEX CONCURRENTLY fails partway (lock timeout, OOM, connection drop on a busy multi-GB tag_usage), Postgres leaves the index in an INVALID state. A subsequent CREATE ... IF NOT EXISTS sees the catalog row and silently skips, leaving the index permanently broken while the migration reports success. The four composite indexes already use the DROP-then-CREATE pattern; applying the same to the two new single-col indexes for symmetry. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9fdc925 commit 069c440

4 files changed

Lines changed: 38 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-- Placeholder for 1.12.7 MySQL post-data migration script
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- Placeholder for 1.12.7 MySQL schema changes
2+
-- The Postgres-side fix for #27158 has no MySQL counterpart: MySQL's
3+
-- 1.11.0 indexes were already non-partial (no partial-index syntax in
4+
-- MySQL), so the regression that hit Postgres did not affect MySQL.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-- Placeholder for 1.12.7 PostgreSQL post-data migration script
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
-- Issue #27158: tag_usage seq-scan on Postgres. #24063 dropped the
2+
-- `state = 1` predicate that 1.11.0's partial indexes required.
3+
-- Fix: add single-col indexes on the `_lower` columns, and drop the
4+
-- `WHERE state = 1` filter from the partials so changes can't invalidate them.
5+
6+
DROP INDEX CONCURRENTLY IF EXISTS idx_tag_usage_targetfqnhash_lower_pattern;
7+
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tag_usage_targetfqnhash_lower_pattern
8+
ON tag_usage (targetfqnhash_lower text_pattern_ops);
9+
10+
DROP INDEX CONCURRENTLY IF EXISTS idx_tag_usage_tagfqn_lower_pattern;
11+
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tag_usage_tagfqn_lower_pattern
12+
ON tag_usage (tagfqn_lower text_pattern_ops);
13+
14+
DROP INDEX CONCURRENTLY IF EXISTS idx_tag_usage_target_prefix_covering;
15+
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tag_usage_target_prefix_covering
16+
ON tag_usage (source, targetfqnhash_lower text_pattern_ops)
17+
INCLUDE (tagFQN, labelType, state);
18+
19+
DROP INDEX CONCURRENTLY IF EXISTS idx_tag_usage_tagfqn_prefix_covering;
20+
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tag_usage_tagfqn_prefix_covering
21+
ON tag_usage (source, tagfqn_lower text_pattern_ops)
22+
INCLUDE (targetFQNHash, labelType, state);
23+
24+
DROP INDEX CONCURRENTLY IF EXISTS idx_tag_usage_join_source;
25+
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tag_usage_join_source
26+
ON tag_usage (tagFQNHash, source)
27+
INCLUDE (targetFQNHash, tagFQN, labelType, state);
28+
29+
CREATE EXTENSION IF NOT EXISTS pg_trgm;
30+
DROP INDEX CONCURRENTLY IF EXISTS gin_tag_usage_targetfqn_trgm;
31+
CREATE INDEX CONCURRENTLY IF NOT EXISTS gin_tag_usage_targetfqn_trgm
32+
ON tag_usage USING GIN (targetFQNHash gin_trgm_ops);

0 commit comments

Comments
 (0)