HNHacker News
TopNewBestAskShowJobs

surjection

17 karma · joined November 5, 2013

submissionscomments
surjection··on Pgroll: zero-downtime, reversible schema migrations for Postgres
Yes, for those pgroll migrations that require a new column + backfill, starting the migration can be expensive.

Backfills are done in fixed size batches to avoid long lived row locks, but the operation can still be expensive in terms of time and potentially I/O. Options to control the rate of backfilling could be a useful addition here but they aren't present yet.

surjection··on Pgroll: zero-downtime, reversible schema migrations for Postgres
There's nothing about this in the docs :)

Backfills are done in fixed size batches to avoid taking long-lived row locks on many rows but there is nothing in place to control the overall rate of backfilling.

This would certainly be a nice feature to add soon though.

surjection··on Pgroll: zero-downtime, reversible schema migrations for Postgres
Any pgroll operations[0] that require a change to an existing column, such as adding a constraint, will create a new copy of the column and backfill it using 'up' SQL defined in the migration and apply the change to that new column.

There are no operations that will modify the data of an existing column in-place, as this would violate the invariant that the old schema must remain usable alongside the new one.

[0] - https://github.com/xataio/pgroll/tree/main/docs#operations-r...

surjection··on Pgroll: zero-downtime, reversible schema migrations for Postgres
The bloat incurred by the extra column is certainly present while the migration is in progress (ie after it's been started with `pgroll start` but before running `pgroll complete`).

Once the migration is completed any extra columns are dropped.

surjection··on Pgroll: zero-downtime, reversible schema migrations for Postgres
An example would make this more concrete.

This migration[0] adds a CHECK constraint to a column.

When the migration is started, a new column with the constraint is created and values from the old column are backfilled using the 'up' SQL from the migration. The 'up' SQL rewrites values that don't meet the constraint so that they do.

The same 'up' SQL is used 'on the fly' as data is written to the old schema by applications - the 'up' SQL is used (as part of a trigger) to copy data into the new column, rewriting as necessary to ensure the constraint on the new column is met.

As the sibling comment makes clear, it is currently the migration author's responsibility to ensure that the 'up' SQL really does rewrite values so that they meet the constraint.

[0] - https://github.com/xataio/pgroll/blob/main/examples/22_add_c...

surjection··on Pgroll: zero-downtime, reversible schema migrations for Postgres
Allowing the database and the application to be out of sync (to +1/-1 versions) is really the point of pgroll though.

pgroll presents two versions of the database schema, to be used by the current and vNext versions of the app while syncing data between the two.

An old version of the app can continue to access the old version of the schema until such time as all instances of the application are gracefully shut down. At the same time the new versions of the app can be deployed and run against the new schema.

surjection··on Pgroll: zero-downtime, reversible schema migrations for Postgres
There is no code to do this because it's actually a nice feature of postgres - if the underlying column is renamed, the pgroll views that depend on that column are updated automatically as part of the same transaction.
surjection··on Pgroll: zero-downtime, reversible schema migrations for Postgres
I don't see the need to keep your application consistent with both schema versions. During a migration pgroll exposes two Postgres schema - one for the old version of the database schema and another for the new one. The old version of the application can be ignorant of the new schema and the new version of the application can be ignorant of the old.

pgroll (or rather the database triggers that it creates along with the up and down SQL defined in the migration) does the work to ensure that data written by the old applications is visible to the new and vice-versa.

A rollback in pgroll then only requires dropping the schema that contains the new version of the views on the underlying tables and any new versions of columns that were created to support them.

surjection··on Pgroll: zero-downtime, reversible schema migrations for Postgres
You're right. I wish schema wasn't such an overloaded term :)

In order to access either the old or new version of the schema, applications should configure the Postgres `search_path`[0] which determines which schema and hence which views of the underlying tables they see.

This is touched on in the documentation here[1], but could do with further expansion.

[0] - https://www.postgresql.org/docs/current/ddl-schemas.html#DDL... [1] - https://github.com/xataio/pgroll/blob/main/docs/README.md#cl...

surjection··on Pgroll: zero-downtime, reversible schema migrations for Postgres
Another pgroll author here :)

I'm not very familiar with pg-osc, but migrations with pgroll are a two phase process - an 'in progress' phase, during which both old and new versions of the schema are accessible to client applications, and a 'complete' phase after which only the latest version of the schema is available.

To support the 'in progress' phase, some migrations (such as adding a constraint) require creating a new column and backfilling data into it. Triggers are also created to keep both old and new columns in sync. So during this phase there is 'bloat' in the table in the sense that this extra column and the triggers are present.

Once completed however, the old version of this column is dropped from the table along with any triggers so there there is no bloat left behind after the migration is done.

surjection··on Pgroll: zero-downtime, reversible schema migrations for Postgres
Do you mean the extra configuration required to make applications use the correct version of the database schema, or something else?
surjection··on Pgroll: zero-downtime, reversible schema migrations for Postgres
We are looking to build integrations with other tools but for now isn't recommended to use pgroll alongside another migration tool.

To try out pgroll on a database with an existing schema (whether created by hand or by another migration tool), you should be able to have pgroll infer the schema when you run your first migration.

You could try this out in a staging/test environment by following the docs to create your first migration with pgroll. The resulting schema will then contain views for all your existing tables that were created with alembic. Subsequent migrations could then be created with pgroll.

It would be great to try this out and get some feedback on how easy it is to make this switch; it may be that the schema inference is incomplete in some way.

surjection··on Pgroll: zero-downtime, reversible schema migrations for Postgres
Hi, one of the authors of pgroll here.

Migrations are JSON format as opposed to pure SQL for at least a couple of reasons:

1. The need to define up and down SQL scripts that are run to backfill a new column with values from an old column (eg when adding a constraint).

2. Each of the supported operation types is careful to sequence operations in such a way to avoid taking long-lived locks (eg, initially creating constraints as NOT VALID). A pure SQL solution would push this kind of responsibility onto migration authors.

A state-based approach to infer migrations based on schema diffs is out of scope for pgroll for now but could be something to consider in future.

surjection··on Show HN: Spawn – Throwaway Databases for CI and Development
We're a small team working on Spawn, a SaaS for provisioning ephemeral databases for CI pipelines and development workflows.

Spawn supports multiple database engines, database instances start in seconds regardless of data size and can be snapshotted and restored just as quickly. We think they make a great replacement for database servers installed on developer machines, offer an easier alternative to Docker + volume management and unlock better database CI by allowing easier testing with realistic data sets.

We'd love to know what you think. Is this something that would fit into your development or CI workflows?