News for hackers. Stuff that matters.
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by candiddevmike on Tuesday October 03, 2023 @11:54AM (#37753560)
Help me understand the value of undoable migrations. I've always operated under "the only path is forward" and you release a new version that fixes the issue or create a new migration that does some kind of partial rollback if necessary. Once a migration is live, naively rolling things back seems like you're asking for problems.

I also only perform migrations as part of app init, not separately.

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by Nullabillity on Tuesday October 03, 2023 @12:02PM (#37753685)
During development I'll often keep rolling the same change back and forth (with minor changes), rather than recreate the database from scratch/a backup each time.
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by exekias on Tuesday October 03, 2023 @12:06PM (#37753735)
I believe this is one of the reasons why migrations become scary in many cases. If something goes wrong "the only path is forward". Also, rolling out new versions of the application means either breaking the previous versions (with some instances still running) or doing the migration in several steps.

We believe there is a better way, they way pgroll works, you can start a migration, and keep the old & new schemas working for as long as you need to rollout your app. If the new version of the app/schema doesn't behave as you were expecting, you only need to rollback the commit and undo the migration. pgroll guarantees that the previous version is still working during the whole process.

There is a graph in the readme depicting this concept:

https://github.com/xataio/pgroll/blob/main/docs/img/migratio...

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by candiddevmike on Tuesday October 03, 2023 @12:25PM (#37754053)
That's great that pgroll does this, but the heavy lifting for supporting this comes at a huge cost on the application side, IMO.
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by surjection on Tuesday October 03, 2023 @12:45PM (#37754298)
Do you mean the extra configuration required to make applications use the correct version of the database schema, or something else?
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by candiddevmike on Tuesday October 03, 2023 @12:51PM (#37754417)
Yea, keeping your application consistent with two different schema versions. And I'm not saying from a blue/green standpoint, from whatever pgroll does instead so when the rollback happens you don't lose data.
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by matsemann on Tuesday October 03, 2023 @01:23PM (#37754875)
Eh, isn't this making it easier on the application side? Today, when I make a change in my app that needs a migration, I need multiple steps to make sure I don't break old instances of the app still running. With this it looks like one can avoid all that?
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by exekias on Tuesday October 03, 2023 @02:38PM (#37755833)
That is what this project is trying to achieve. By allowing your client apps to access both the old and the new schema at the same time, you can have the old instances of your application working while the new ones (using the new schema) get deployed.

They can work in parallel for a while until you complete the rollout and call the migration as done.

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by surjection on Tuesday October 03, 2023 @01:47PM (#37755193)
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.

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by dot5xdev on Tuesday October 03, 2023 @01:09PM (#37754678)
> If the new version of the app/schema doesn't behave as you were expecting, you only need to rollback the commit and undo the migration.

If I delete a "last_name" column, apply the migration, and then decide I shouldn't have deleted users' last names. Do I get that data back?

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by indigo945 on Tuesday October 03, 2023 @01:59PM (#37755347)
Just from my understanding from having read the linked website: yes, you do.

"Applying the migration" doesn't actually do anything to the table, it just creates a new schema containing views over the old one, where the view for the table whose column you deleted hides the column. You can then try if your app still works when using accessing this schema instead of the old one. If you're happy, you can "complete" the migration, at which point only the table structure actually gets altered in a non-reversible way.

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by exekias on Tuesday October 03, 2023 @02:40PM (#37755860)
^ this is exactly how it works :)
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by javaunsafe2019 on Tuesday October 03, 2023 @02:59PM (#37756044)
But if it works like that aren’t there schema migration paths that are changing the actual content of a column and are then not undoable?
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by pcthrowaway on Tuesday October 03, 2023 @04:16PM (#37756971)
Also, if the data isn't deleted couldn't this lead to database bloat?
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by surjection on Tuesday October 03, 2023 @04:51PM (#37757395)
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.

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by surjection on Tuesday October 03, 2023 @04:58PM (#37757488)
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...

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by darkwater on Tuesday October 03, 2023 @05:21PM (#37757740)
Maybe this is explained somewhere in the docs but I'm lazy: how does it cope with possible performance issue in highly trafficked tables? Can you somehow control the backfill speed if it's taking up too much I/O?
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by surjection on Tuesday October 03, 2023 @05:33PM (#37757863)
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.

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by mst on Tuesday October 03, 2023 @02:53PM (#37755991)
Apologies for the off-topic-ness, but no matter where I've tried putting the mouse focus on the post, Up/Down don't work to scroll (but PgUp/PgDown are fine).

(I very much appreciate the effort to provide tooling that puts all these things together, btw)

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by exekias on Tuesday October 03, 2023 @03:03PM (#37756087)
Thanks for reporting! we will look into it
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by mst on Wednesday October 04, 2023 @09:25AM (#37764770)
Sorry, forgot to say: Win10 / Firefox.
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by pcthrowaway on Tuesday October 03, 2023 @04:12PM (#37756923)
I recently had to do a migration on a timescale hypertable where a "schema" was migrated for a table which had jsonb columns containing arrays of arrays of numbers to a new table containing the same data as two-dimensional postgres arrays of numeric[][] data (better storage characteristics)

Our workflow was something like:

1) Create the new hypertable

2) Create after insert trigger on first table to insert transformed data from first table into second table, and delete from first table (this ensured applications can continue running using first schema/table, without any new data being added to first table after migration)

3) Iterate over first table in time-bucketed batches using a plpgsql block to move chunks of data from first table to second table.

Would pgroll enable a similar workflow? I guess I'm curious if the way pgroll works would similarly create a trigger to allow apps to work with the initial schema as a stopgap... I guess pgroll would perform the whole migration as a series of column updates on a single table, but I'm unclear on whether it attempts to migrate all data in one step (potentially locking the table for longer periods?) while also allowing applications using the old schema to continue working so there is no downtime as changes are rolled out.

Has pgroll been tested with timescaledb at all?

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by exekias on Tuesday October 03, 2023 @04:32PM (#37757159)
To do this with pgroll I would use an alter_column migration, changing the type: https://github.com/xataio/pgroll/tree/main/docs#change-type, this would:

1) Create a new column with the desired type (numeric[][] in your case) 2) Backfill it from the original one, executing the up function to do the casting and any required transformation 3) Install a trigger to execute the up function for every new insert/update happening in the old schema version 4) After complete, remove the old column, as it's no longer needed in the new version of the schema

Backfills are executed in batches, you can check how that works here: https://github.com/xataio/pgroll/blob/main/pkg/migrations/ba...

I don't think any of us has tested pgroll against timescaledb but I would love to know about the results if anyone does!

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by vlovich123 on Tuesday October 03, 2023 @05:39PM (#37757931)
Is my understanding correct that the need to copy columns makes starting a migration potentially extremely expensive on a large database?
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by surjection on Tuesday October 03, 2023 @05:51PM (#37758084)
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.

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by claytonjy on Tuesday October 03, 2023 @06:49PM (#37758651)
This is almost exactly how I did a similar migration, also in Timescale. I used PL/pgSQL and sqitch, did you use a migration tool?
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by pcthrowaway on Tuesday October 03, 2023 @11:04PM (#37760383)
No, this was all done in handwritten .sql scripts. I don't think it matters too much in this case, but we're using Rust and the sqlx cli for driving the migrations, but that basically just runs the sql migration scripts
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by contravariant on Tuesday October 03, 2023 @12:00PM (#37753655)
I don't think 'undoable' is the clearest description, the crux is this:

> Keep two versions of the schema (previous and next) accessible at the same time during the whole migration process

This has some obvious advantages. Like you said you can't easily roll back once a migration is fully live, but it helps a lot if you can cancel a migration once it turns out it doesn't work.

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by tudorg on Tuesday October 03, 2023 @12:05PM (#37753726)
Yes, that's exactly it. I generally agree with "always move forward" but if rolling back is as easy as dropping the "new" view, that makes it a lot less scary.
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by candiddevmike on Tuesday October 03, 2023 @12:25PM (#37754041)
Isn't that what transactions are for?
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by contravariant on Tuesday October 03, 2023 @12:30PM (#37754114)
That would be hard to coordinate if your application is even slightly complicated.
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by candiddevmike on Tuesday October 03, 2023 @04:14PM (#37756937)
Not really...

- Start migration, create transaction and locks

- Do migration things

- Do some SELECTs, INSERTS, or w/e in your code to validate the schema matches your model.

- End transaction or rollback if failure

None of this is free, but it's by no means hard IMO. I do something similar in Go: https://github.com/candiddev/shared/blob/main/go/postgresql/...

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by ttfkam on Tuesday October 03, 2023 @04:35PM (#37757195)
> Start migration, create transaction and locks

If you do that on a table or two with millions of rows, you've effectively locked your database from all other access, even SELECTs.

ALTER statements typically grab exclusive locks, blocking both writes and reads. Chain a couple together and you're looking at high CPU, queued queries, and an unresponsive database for hours.

Once you realize what's happening and kill the migration in a panic, it may take tens of minutes or more for the DB to revert back to its initial state, much to everyone's impatient horror.

In simple programs and databases, everything is possible and quick. Complex programs and large databases disabuse you of your naïveté with a quickness.

I love Postgres's transactional DDL, but as the article's mention of renaming columns highlights, one transaction simply isn't enough for the job.

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by candiddevmike on Tuesday October 03, 2023 @04:44PM (#37757294)
The locks I was referring to were more around advisory locks to prevent multiple migrations from running. For the locks you mention, all migrations create some kind of table lock typically, it's up to the dev to make them as small as necessary. I don't follow your strawman.
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by bananapub on Tuesday October 03, 2023 @05:55PM (#37758138)
> I don't follow your strawman.

how large are the DB migrations you've done? your experience is seemingly completely different to mine.

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by ttfkam on Tuesday October 03, 2023 @06:43PM (#37758600)
The locks I was referring to were a direct result of many (most?) ALTER statements. Multiple clients trying to migrate isn't even in this equation. Just one client migrating can ruin your day with a single ALTER statement given a large enough database.

What's the biggest table you've ever had to modify?

Adding a column with a default is easy. What about deleting a column from a table with 10s of millions of rows? Renaming a column? Changing a column's type? Adding a CHECK constraint? Adding a NOT NULL? Adding a foreign key constraint that someone accidentally removed in the previous migration while data keeps flowing?

Those concerns aren't about your explicit advisory locks. Not by a long shot.

https://www.postgresql.org/docs/current/explicit-locking.htm...

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by vanviegen on Tuesday October 03, 2023 @04:44PM (#37757290)
That wouldn't allow you to partially roll out your new code base (depending on the altered schema), nor to easily revert such a roll out.
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by bityard on Tuesday October 03, 2023 @12:53PM (#37754455)
If your organization requires change management (as many are contractually obligated to), then you don't have much of a choice. Every change needs to be tested, every change needs a way to fully and completely roll back the change, and the rollback has to be tested.

Additionally, the people executing the change are not necessarily those who have developed the change. They need two big buttons: Do and Undo. If the change fails or breaks something, they hit the Undo button and tell the developers about it and by the way, here are the logs, please go reproduce it on the test system and try again.

I know this is not "devops," but it's still how a lot of high-availability software deployments work, particularly when hampered by bureaucratically-imposed processes.

Finally, database schema changes are a fine way to irreversibly munge your data if you are not careful. (This goes beyond SQL.) If that happens, there is no such thing as a path forward, the only way to save the ship is to restore from your most recent backup.

Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by nobleach on Tuesday October 03, 2023 @06:43PM (#37758596)
A couple of places I've worked lived like this. We used the free version of Flyway with Spring Boot and Quarkus. We got by really well "rolling forward". My next gig used Sequalize and MySQL. Aside from hating those technologies, I hated that false sense of security baked into "oh well, we can always roll back"
Re:Pgroll: zero-downtime, undoable, schema migrations for Po... by cptMayhem on Wednesday October 04, 2023 @01:12PM (#37768339)
> I hated that false sense of security baked into "oh well, we can always roll back"

That's why I like pgroll's approach, in that there isn't really a "rollback procedure" that might make things worse during emergencies, but rather old and new schemas that remain working simultaneously until the migration is marked as complete and there are no clients using the old schema. "Rolling back" is actually cancelling the new schema migration and falling back to the previous version that's been working at all times, thus minimizing the risk.