CapyDB/ docs
GuidesImports & Migrations

Migrate from Cloud SQL or AlloyDB

Move a Google Cloud SQL for PostgreSQL or AlloyDB database into CapyDB.

Cloud SQL and AlloyDB are close cousins, and the two things that differ between them for a migration are exactly the two things that matter: the flag that enables logical replication is spelled differently, and AlloyDB has features that do not exist on plain Postgres.

Reachability first

Neither service publishes a hostname. Cloud SQL gives you an IP (and the Cloud SQL Auth Proxy); AlloyDB is private-IP only. The importer connects from the CapyDB control plane, so before anything else, decide how it will reach the database:

  • Cloud SQL, public IP: add an authorized network for the import window and remove it afterwards.
  • Cloud SQL, private IP, or AlloyDB: there is no public path. Either stand up a proxy you control, or take a dump and use a dump-file import.
postgres://migration_user:password@34.x.x.x:5432/dbname?sslmode=require

For a near-zero-downtime import

Cloud SQL:

gcloud sql instances patch your-instance --database-flags=cloudsql.logical_decoding=on
gcloud sql instances restart your-instance

AlloyDB — note the different flag name:

gcloud alloydb instances update your-instance \
  --cluster=your-cluster --region=your-region \
  --database-flags=alloydb.logical_decoding=on

Both need a restart to take effect. Setting the flag alone does not change wal_level, which is the usual reason a migration that "should" stream does not. Confirm what the server actually reports:

capydb migrate scan --source-url "$GCP_DATABASE_URL"

Then give the migration role replication rights:

ALTER ROLE migration_user WITH REPLICATION;

AlloyDB-specific caveats

  • The columnar engine is AlloyDB-only. It is an accelerator, not stored data, so nothing is lost in the copy - but query plans that depended on it will not behave the same way on plain Postgres.
  • google_columnar_engine, google_ml_integration and the other google_* extensions have no equivalent. Anything calling them has to change. The preflight separates the ones with dependent objects from the ones that are merely installed.

Cloud SQL-specific caveats

  • The default user is not a superuser - it is a cloudsqlsuperuser. Event triggers do not move.
  • cloudsql.* GUCs and the cloudsqladmin role do not exist on plain Postgres; nothing should reference them, but a scan will tell you if something does.

Preflight and import

capydb import preflight --project your-project --source-url "$GCP_DATABASE_URL"

capydb import --project your-project --source-url "$GCP_DATABASE_URL" --follow
capydb import follow-status --project your-project
capydb import cutover --project your-project

After the import

  1. \dx for extensions, and re-enable on the project anything the restore could not create.
  2. Spot-check sequences.
  3. ANALYZE;
  4. Swap the connection string in every consumer, then remove the authorized network or tear down the proxy.