Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion internal/postgres/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -690,13 +690,29 @@ func createContentSearchIndexesPG(ctx context.Context, db *sql.DB) {
log.Printf("pg schema: invalid pg_trgm schema %q: %v", extSchema, err)
return
}
// fastupdate=off keeps the index bounded: the default fastupdate=on
// buffers inserts into a pending list that only VACUUM merges, which grows
// unbounded when continuous ingest starves autovacuum.
if _, err := db.ExecContext(ctx, fmt.Sprintf(
`CREATE INDEX IF NOT EXISTS idx_messages_content_trgm
ON messages USING gin (content %s.gin_trgm_ops)`, quotedExt,
ON messages USING gin (content %s.gin_trgm_ops)
WITH (fastupdate = off)`, quotedExt,
)); err != nil {
log.Printf(
"pg schema: creating messages.content trigram index failed: %v", err,
)
return
}
// CREATE INDEX IF NOT EXISTS only applies WITH (fastupdate = off) on
// first creation. Re-apply on every boot so stores upgraded from a
// prior schema (which left fastupdate=on) also get the bounded index.
if _, err := db.ExecContext(ctx,
`ALTER INDEX idx_messages_content_trgm SET (fastupdate = off)`,
); err != nil {
log.Printf(
"pg schema: disabling fastupdate on messages.content trigram index failed: %v",
err,
)
}
}

Expand Down
18 changes: 18 additions & 0 deletions internal/postgres/search_content_pgtest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,24 @@ func TestPGContentSearchTrigramIndex(t *testing.T) {
).Scan(&hasIdx), "query pg_indexes")
assert.True(t, hasIdx,
"idx_messages_content_trgm missing after EnsureSchema")

// fastupdate=off must be set so the pending list cannot grow
// unbounded under continuous ingest. The schema bootstrap applies
// this on every boot (including stores upgraded from an earlier
// schema that created the index with the default fastupdate=on).
var fastupdateOff bool
require.NoError(t, store.DB().QueryRowContext(ctx,
`SELECT EXISTS (
SELECT 1
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = $1
AND c.relname = 'idx_messages_content_trgm'
AND 'fastupdate=off' = ANY(c.reloptions)
)`, contentSearchSchema,
).Scan(&fastupdateOff), "query pg_class.reloptions")
assert.True(t, fastupdateOff,
"idx_messages_content_trgm must have fastupdate=off")
}

// TestPGSearchContentRegex verifies regex mode.
Expand Down
Loading