docs: PostgreSQL cross-cluster instance migration guide (KB260720001) + pending PG-solutions review fixes#809
Open
SuJinpei wants to merge 17 commits into
Open
docs: PostgreSQL cross-cluster instance migration guide (KB260720001) + pending PG-solutions review fixes#809SuJinpei wants to merge 17 commits into
SuJinpei wants to merge 17 commits into
Conversation
…1526) Precipitate historical internal KB PostgreSQL solutions, modernized to the current acid.zalan.do/v1 postgresql CR and verified live on ACP 4.2/4.3, bilingual (en + zh): - KB260515007 How to Migrate a PostgreSQL Instance to Another Node - KB260515008 How to Deploy CloudBeaver for PostgreSQL Management Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The zh translations are produced by the translation pipeline from the en sources (tracked via sourceSHA); they should not be committed by hand. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- CloudBeaver: retrieve superuser password from the operator-created Secret (postgres.<cluster>.credentials...) instead of a non-existent PGPASSWORD_SUPERUSER env var - node migration: label only the target node to avoid rescheduling onto the source Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…001) Validated end-to-end on operator v4.3.3 across two ACP platforms (NodePort pairing, two-phase switchover, checksum-gated cutover). Includes troubleshooting for the ECO-703 cross-version XCR schema drift and standby-recreate secret cleanup. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ordered teardown (standby first, then remove clusterReplication from the promoted primary), operator-side cleanup behavior (sys_operator schema drop, xdc_hotstandby slot removal), leftover-object cleanup, and verification. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…slot/xcr svc) Ran the full teardown on the validated v4.3.3 pair: sys_operator schema drop confirmed automatic; PVC retention is config-dependent (deleted with the CR on v4.3.3); the physical xdc_hotstandby slot and the -xcr service linger and need manual removal. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
For topologies with no inter-cluster network where the workstation reaches both API servers: pg_dump piped between two kubectl exec sessions. Validated live (100k rows, exact checksum parity, clean exit); documents the version-matched-binary and spilo-schema-exclusion requirements found during validation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…721001 Workstation-relayed logical migration as its own doc, tested verbatim end-to-end before commit. Testing corrected the restore identity: restore as the CR-defined application user (plus --no-comments), otherwise objects land owned by postgres and the app user cannot query them. Migration guide now links to the standalone doc instead of embedding the procedure. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Verify with exact per-table counts (query_to_xml) instead of the n_live_tup estimate, in both baseline and post-restore steps - Run the relay pipe under pipefail and report per-side PIPESTATUS so a source-side dump failure cannot be masked - Add extension preflight: inventory pg_extension on the source and pre-create missing extensions as postgres on the target; new troubleshooting entry for 'permission denied to create extension' - Scope the ownership guidance to the single-owner operator layout and extend the fallback ALTER note beyond public tables/sequences - Add security notes: password visibility in local process listings, dump-file permissions/retention, TLS transport - List required Kubernetes permissions and Spilo image assumptions in Prerequisites - Reword the 'no version-matching constraints' claim (here and in the companion guide's pointer) to same-or-newer target major, no downgrades Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Executor feedback: the examples read as if 'appdb' were the whole instance. Step 1 now enumerates the source's application databases (pg_database query, validated live) and states that Steps 2-4 repeat once per database with the name/owner substituted; Step 2 and the Step 3 pipe restate it at the point of use. The postgres maintenance database is explicitly excluded from migration. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reduce the procedure from repeat-Steps-2-4-per-database to one script run: enumerate all application databases, auto-create ones missing on the target (e.g. postgres-owned databases created outside the CR), pre-create extensions, transfer each database as its owner, verify exact per-table counts, and report PASS/FAIL per database. Step 1 also gains a generator for the target CR users:/databases: sections. Validated end-to-end on the longterm-c -> longterm-b pair with a 3-database fixture (two CR-owned + one stray postgres-owned): all databases PASS first try, ownership and per-user access verified. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The scripted whole-instance migration is now the main procedure (Steps 1-5: create target CR, stop writes, run script, verify app access, cut over). The per-database manual steps move to a 'Reference: Manual Single-Database Transfer' section — kept because debugging a per-database FAIL, single-database/partial migrations, and the resumable file-based variant for very large databases all need the standalone commands and flag rationale. Troubleshooting pointers retargeted; added explicit warning not to rerun the whole script after a partial success (re-restoring populated databases collides). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Step 1 gains a 'Preserve application credentials' sub-step: copy each application user's credential secret from the source into the target namespace BEFORE creating the target CR — the operator adopts existing secrets and sets role passwords from them instead of generating new ones, so applications keep their credentials and only the endpoint changes at cutover. System users (postgres/standby) are skipped. New troubleshooting entry for the CR-created-first case: patch the secret AND ALTER ROLE together. Live-validated on the C->B pair: pre-staged secrets adopted (target secret == source password, login with source password OK), full scripted migration PASS, migrated data queried on the target with the source-era passwords for both users. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The script now accepts database names as arguments (bash migrate.sh appdb) to migrate a subset — validated live with two sequential single-database runs — which was the reference section's main job (redoing one FAIL). Its remaining unique content is folded in place: the file-based large-database variant becomes a compact Step 3 subsection, the -x re-grant note moves to Step 4, and the multi-owner scope note plus newer-major binary tip move into the troubleshooting entries that need them. Doc shrinks by a net 40 lines with a single flow: 5 steps + troubleshooting. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 (blocker): the script can no longer report success after migrating zero databases — pod lookups and the source-major probe are guarded with early exits, and an ATTEMPTED counter turns empty enumeration or a non-matching subset argument into an explicit error. Validated: bogus cluster name exits 1 at preflight, full run reports the count, 'bash migrate.sh nosuchdb' exits 1. 2 (major): the credential pre-stage loop derives the user from the secret's NAME (the CR user the target operator looks up) instead of the decoded username field, copies credential bytes base64-verbatim, skips pooler alongside postgres/standby, and documents the password-rotation limitation. 3 (major): the password recovery is injection-safe — base64 merge patch for the secret and psql :'pw' literal quoting for ALTER ROLE. Validated with a password containing quotes, backslash, and SQL. 4 (minor): the verification query schema-qualifies table names and excludes the schemas the dump excludes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Remove the last manual side-path: instead of a hand-run dump/restore for large databases, the script now has two modes through the same code — default pipe, or DUMP_DIR=/path for per-database dump files with atomic completion (.partial + mv) and reuse on rerun, making transfers resumable. The failed-restore redo simplifies to DROP DATABASE + rerun with the database name (the script recreates the database with the correct owner). Validated live: file-mode full run, resume run reusing a completed dump after DROP, and pipe mode unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Finding 1 (major): a leftover completed dump could be silently reused across maintenance windows, migrating stale data past the count check. File mode now takes a fresh dump on every run by default; REUSE_DUMPS=1 opts into reuse, documented as safe only while source writes have stayed stopped since the dump was taken. Validated live: after a post-window source write, the default rerun re-dumped and migrated the new row; REUSE_DUMPS=1 reuses the completed dump. Finding 2 (nit): FAIL message says 'transfer exit' instead of 'pipe exit', correct for both modes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
How_to_Migrate_a_PostgreSQL_Instance_Across_Clusters.md(KB260720001) — cross-cluster/cross-platform PostgreSQL instance migration using the operator's hot-standby (XCR) feature with a two-phase switchover and checksum-gated cutover. Companion to KB251000009 (Hot Standby Cluster Configuration Guide).Validation
The migration guide was validated end-to-end on 2026-07-20 with operator v4.3.3 on two separate ACP platforms (NodePort pairing, arm64, PG 16): standby bootstrap from peer, checksum parity, demote-then-promote switchover, reverse replication after cutover.
The troubleshooting section encodes real failures encountered during validation, including the cross-version XCR schema drift (ECO-703) and the standby-recreate secret cleanup trap.
🤖 Generated with Claude Code