Skip to content

Fix pg_upgrade compatibility: omit removed catalog columns from views (re-release 0.2.2)#18

Merged
jnasbyupgrade merged 32 commits intoPostgres-Extensions:masterfrom
jnasbyupgrade:binary-pg-upgrade-ci
May 1, 2026
Merged

Fix pg_upgrade compatibility: omit removed catalog columns from views (re-release 0.2.2)#18
jnasbyupgrade merged 32 commits intoPostgres-Extensions:masterfrom
jnasbyupgrade:binary-pg-upgrade-ci

Conversation

@jnasbyupgrade
Copy link
Copy Markdown
Contributor

@jnasbyupgrade jnasbyupgrade commented Apr 30, 2026

Re-release of 0.2.2 (originally released 2026-04-27) fixing pg_upgrade
compatibility with PostgreSQL 12 and 17+.

pg_upgrade physically copies data files and re-applies schema definitions on
the new cluster. Any view referencing a catalog column removed in the new
PostgreSQL version will cause the upgrade to fail. The initial 0.2.2 release
missed several such columns:

  • relhasoids — removed from pg_catalog.pg_class in PG12
  • relhaspkey — removed from pg_catalog.pg_class in PG17
  • attcacheoff — removed from pg_catalog.pg_attribute in PG17

Those columns are removed in this release.

Also, the existing pg-upgrade-test CI job used pg_upgradecluster (dump/restore),
which reinstalls extensions at the current version and masks exactly this class
of problem. Replaced with binary pg_upgrade, which physically copies data
files and correctly catches view/column incompatibilities across major versions.

jnasbyupgrade and others added 22 commits April 30, 2026 17:53
…test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
`relhasoids` was removed in PG12. When binary pg_upgrade restores view
definitions on PG12, `_cat_tools.pg_class_v` fails because it references
`c.relhasoids` (included by the dynamic column-list builder on PG10/11
where the column exists).

Explicitly add `relhasoids` to the omit list in `omit_column()` so the
view is defined without it on all PostgreSQL versions, making binary
pg_upgrade from PG10/PG11 to PG12+ work correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pg_upgrade writes multiple log files (pg_upgrade_internal.log,
pg_upgrade_server.log, pg_upgrade_dump_*.log, etc.) to its working
directory. Run it from a dedicated /tmp/pg_upgrade_logs dir and use
`tail -n +1` on failure to print all logs with their filenames.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Pass --no-data-checksums to pg_createcluster so the new cluster
  matches the old cluster (which pg-start creates without checksums)
- Use find+xargs instead of bare glob for log output so it doesn't
  fail when pg_upgrade exits before writing any log files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Only run on push to master (not PR branches); pull_request handles
  those, preventing each PR push from triggering two CI runs
- Detect old cluster's data_checksums setting and pass --data-checksums
  to pg_createcluster only if needed, instead of --no-data-checksums
  which doesn't exist pre-PG18

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The psql query to detect checksums was running after pg_ctlcluster stop,
so it always failed silently and checksum_flag was never set.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PG18 changed initdb's default to enable data checksums. Use
pg_controldata (works on stopped clusters) to detect the old cluster's
checksum setting, then:
- If old cluster has checksums: pass --data-checksums to new initdb
- If not, and new initdb supports --no-data-checksums (PG18+):
  explicitly disable to override the new default
- Otherwise: no flag needed (pre-PG18 default is no checksums)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Instead of detecting and matching checksums, recreate the old cluster
with --data-checksums immediately after pg-start, and always pass
--data-checksums when creating the new cluster. Both clusters
consistently have checksums; no detection logic needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add pg_isready -t 30 after pg_ctlcluster start to wait for the
  socket to be available before proceeding
- Remove the standard 'test' job (not needed on this branch)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pg_createcluster defaults to peer/md5 auth; the container runs as root
so peer auth fails for user postgres. Pass --auth trust to match what
pg-start configures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Like relhasoids (removed in PG12), relhaspkey was removed in PG11.
Without excluding it, binary pg_upgrade from PG10 to PG11+ fails with
"column c.relhaspkey does not exist".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Set PGUSER=postgres at job level, eliminating -U postgres / PGUSER=postgres
  throughout all steps
- Set INITDB_OPTS=--data-checksums --auth trust at job level so both
  pg_createcluster calls stay in sync
- Fix log capture on failure: PG17+ writes pg_upgrade logs to
  $new_datadir/pg_upgrade_output.d/ instead of CWD; search both paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
attcacheoff was an internal column in pg_attribute removed in PG18.
Without excluding it, binary pg_upgrade to PG18 fails with
"column a.attcacheoff does not exist".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…_CONFIG

- PGUSER: postgres moved to top-level env (applies to all jobs)
- PGDATABASE set at step level where a specific db is needed
- PG_CONFIG set at step level for new cluster install (make inherits env)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jnasbyupgrade jnasbyupgrade changed the title ci: use binary pg_upgrade instead of pg_upgradecluster Fix pg_upgrade compatibility: omit removed catalog columns from views (re-release 0.2.2) May 1, 2026
jnasbyupgrade and others added 7 commits May 1, 2026 14:35
README: warn that catalog-exposing objects are not a stable API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove step-level env: blocks to avoid future duplication.
PG_CONFIG is now at pg-upgrade-test job level alongside INITDB_OPTS.
PGDATABASE values are inlined with -d flags since they differ between
steps and a job-level value would affect make test calls.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
HISTORY: remove re-release note (now in PR description only)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ate test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…vel env

Job-level PG_CONFIG broke the old cluster install since the new PG
isn't installed yet at that point. Pass it inline as a make argument
for the new cluster step instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
jnasbyupgrade and others added 3 commits May 1, 2026 15:02
…ster

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
paths-ignore skips CI entirely when only *.md or *.asc files change.

all-checks-passed is a single stable check name suitable for use as a
required status check in branch protection rules. It fails if any job
failed or was cancelled, passes if all passed or were skipped (e.g. on
a docs-only push). It also self-inspects ci.yml to catch any jobs
accidentally omitted from its needs list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jnasbyupgrade jnasbyupgrade merged commit d203d88 into Postgres-Extensions:master May 1, 2026
17 checks passed
@jnasbyupgrade jnasbyupgrade deleted the binary-pg-upgrade-ci branch May 1, 2026 20:21
jnasbyupgrade added a commit that referenced this pull request May 1, 2026
… (re-release 0.2.2) (#18)

Re-release of 0.2.2 (originally released 2026-04-27) fixing `pg_upgrade`
compatibility with PostgreSQL 12 and 17+.

`pg_upgrade` physically copies data files and re-applies schema
definitions on
the new cluster. Any view referencing a catalog column removed in the
new
PostgreSQL version will cause the upgrade to fail. The initial 0.2.2
release
missed several such columns:

- `relhasoids` — removed from `pg_catalog.pg_class` in PG12
- `relhaspkey` — removed from `pg_catalog.pg_class` in PG17
- `attcacheoff` — removed from `pg_catalog.pg_attribute` in PG17

Those columns are removed in this release.

Also, the existing `pg-upgrade-test` CI job used `pg_upgradecluster`
(dump/restore),
which reinstalls extensions at the current version and masks exactly
this class
of problem. Replaced with binary `pg_upgrade`, which physically copies
data
files and correctly catches view/column incompatibilities across major
versions.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
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