Skip to content

perf(supervisor): fix extension filtering + batch post_start into one psql#9

Merged
jaredLunde merged 1 commit into
mainfrom
fix/extensions-batch-poststart
Jun 26, 2026
Merged

perf(supervisor): fix extension filtering + batch post_start into one psql#9
jaredLunde merged 1 commit into
mainfrom
fix/extensions-batch-poststart

Conversation

@jaredLunde

Copy link
Copy Markdown
Contributor

Why

post_start was ~1.6s of mostly waste, from two compounding bugs:

  1. extension_installed checked the wrong file. It looked for {ext}.so, but CREATE EXTENSION <name> needs {name}.control. So postgis (lib postgis-3.so) read as "not installed" → the bake (which filters by extension_installed) skipped it, while runtime (which did not filter) created it fresh every boot (~900ms+ — the actual long pole).
  2. Dead/misnamed OPTIONAL entries: auto_explain (preload-only, no control), pgvectorscale/pg_jsonschema/pg_search (not built for noble+pg18), and pgvector (the extension is vector). Each = a wasted psql round-trip failing "not available".

Fixes

  • extension_installed → control-file check (bake-vs-runtime consistent).
  • OPTIONAL_EXTENSIONS = only installable: pg_stat_statements, pg_trgm, vector, pg_partman, hypopg, pg_repack, postgis. postgis now baked → runtime no-op.
  • Batch: post_start assembles one SQL script and runs it via a single psql -f - (ON_ERROR_STOP=1) instead of ~15 spawns. New pg::psql_script + pg::alter_role_password_sql; pgbouncer SQL → sql::PGBOUNCER_AUTH_SQL; assembly extracted to pure, unit-tested build_post_start_script.

Tests

post_start_script_* (assembly + replicator/CDC conditionals) + full unit suite green.

🤖 Generated with Claude Code

… psql

Two compounding problems made post_start ~1.6s of mostly-waste:

1. `extension_installed` checked for `{ext}.so` in pkglibdir, but `CREATE
   EXTENSION <name>` actually needs `{name}.control`. So it mis-judged
   installability: `postgis` (lib is `postgis-3.so`) read as "not installed".
   Because the build-time bake (template.rs) filters by `extension_installed`
   but the runtime post_start did NOT, postgis was SKIPPED at bake then created
   FRESH every boot (~900ms+) — the real long pole, not the no-ops.

2. The OPTIONAL list carried entries that can never succeed (`auto_explain` is
   preload-only/no control file; `pgvectorscale`/`pg_jsonschema`/`pg_search`
   aren't built for noble+pg18) and a misnamed one (`pgvector` → the extension
   is `vector`). Each was a wasted psql round-trip failing "not available".

Fixes:
- `extension_installed` checks the control file (`/usr/share/postgresql/18/
  extension/{ext}.control`) — the correct, bake-vs-runtime-consistent test.
- OPTIONAL_EXTENSIONS = only entries with a control file: pg_stat_statements,
  pg_trgm, vector, pg_partman, hypopg, pg_repack, postgis. Now postgis is baked
  and runtime is a no-op; the dead ones are gone.
- post_start assembles ONE SQL script (password + pgbouncer auth + filtered
  CREATE EXTENSIONs + conditional replicator/CDC) and runs it in a single
  `psql -f -` with ON_ERROR_STOP=1, replacing ~15 process spawns + reconnects.
  New `pg::psql_script` + `pg::alter_role_password_sql`; pgbouncer SQL moved to
  `sql::PGBOUNCER_AUTH_SQL`; script assembly extracted to a pure, unit-tested
  `build_post_start_script`.

Tests: post_start_script_* (assembly + replicator/CDC conditionals) + full
unit suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jaredLunde jaredLunde merged commit 4e4571b into main Jun 26, 2026
1 check passed
@jaredLunde jaredLunde deleted the fix/extensions-batch-poststart branch June 26, 2026 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant