Pgroll – Zero-downtime, reversible, schema changes for PostgreSQL (new website)
pgroll.com
pgroll.com
Before: You had a .sql file and if you messed up you had to revert manually. Maybe you would pre-write the revert script, maybe your site is down if you mess up. It's super easy to understand what is happening though.
Now: you use pgroll. An absolute heaping ton of magic is happening behind the scenes. Every table is replaced by a view and tables have tons of 'secret' columns holding old data. Every operation that made sense before (ALTER TABLE foo ADD COLUMN bar INTEGER NOT NULL) turns into some ugly json mess (look at the docs, it's horrible) that then drops into the magic of pgroll to get turned into who knows what operations in the db, with the PROMISE that it can be reversed safely. Since all software has bugs, pgroll has bugs. When pgroll leaves you in a broken state, which it will sooner or later, you are just FUCKED. You will have to reverse engineer all it's complicated magic and try to get it back on the rails live.
You're trading something you understand and is simple, but maybe not super convenient, for something that is magically convenient and which will eventually put a bullet in your head. It's a horrific product, don't use it.
Obviously for startups, you're 100% right. Just announce a brief downtime and/or do migrations after-hours. Keep it simple, no one will care if their requests timeout once every week for 30 seconds.
If your company has hundreds of developers making changes across every timezone and downtime (or developers being blocked waiting for scheduled merge windows) costs real money or creates real problems other than optics, something like this or Vitess (MySQL) is definitely worth it.
Engineering should not be a "one-size-fits-all" type of job, and while I do love postgres, my main gripe with the community is that the "keep it simple stupid" mentality persists well beyond its sell-by date in many cases.
You keep things simple because you need to be able to understand what is going on to work with it later. pgroll is inherently complex and poorly designed, but even if it wasn't it is still bad to use something that you can't reasonably correct the problems it causes when it breaks.
The argument that "all software has bugs" applies to both the database itself as well as the software you're writing on top. Hence why "reversible" is the 2nd selling-point here.
Nope, schema changes are not that common compared to other tasks and will only account for a small fraction of your DBA's day. I can say this from copious (over 20 years) experience.
They will make FAR fewer mistakes than some random engineer. It takes less time (like a fraction, 1/20 or less) to validate and give feedback on schema changes than it does to untangle the mess that gets made otherwise, restore data from backups, go to meetings to explain outages to executives, etc etc so if you want to keep your DBA's happy and able to sign out of work at a reasonable hour, make sure they get to approve schema changes before they go out. Not to mention that very few engineers have a good understanding of schema design or how to write performant schemas, how to index data, etc. Getting a good migration the first time is just so much less painful and time consuming than trying to deal with bad ones.
But that's the thing, with tools like this, pt-online-schema-change etc., it is reasonable for a DBA to review changes written by other engineers. Without them, when you have extremely large data sets, it is necessary to do magic with triggers, views, etc. to safely make certain kinds of changes. And doing that is beyond the experience of most non-dba engineers, and has a lot of nuance to it. I'm not saying DBAs shouldn't have to approve schema changes. I'm saying they shouldn't have to write complicated migration scripts by hand.
> I think you are way out of your realm of experience here.
Or maybe my experience is different than yours.
However, migrations won't be faster when you use a tool like this, they will be slower. So maybe you are fine with migrations taking weeks and weeks to complete, but in that case how many migrations are you running that your DBA's are overwhelmed by the volume of migrations to approve? Which one is true?
I'm not. At least that wasn't my intention. My reply was in the context of "bigger and more important" companies, which are also more likely to have extremely large datasets, and where taking long, or even short periods of downtime for a database migration is unacceptable.
> migrations won't be faster when you use a tool like this, they will be slower
Sure, but they can be run without taking downtime.
> So maybe you are fine with migrations taking weeks and weeks to complete, but in that case how many migrations are you running that your DBA's are overwhelmed by the volume of migrations to approve? Which one is true?
Both can be true. Most migrations will take a lot less time, maybe minutes, maybe hours, sometimes days. Migrations that take weeks are rare, but they do happen. But, having a migration take several hours with no downtime can often be preferable to taking a few minutes of downtime, even if you are ok with having scheduled downtime, because it will unblock work dependent on the new schema sooner. Of course, it depends on your situation. If schema changes are rare, you probably don't need to worry about something like this. If your tables are small enough that schema changes can be done quickly with minimal or no downtime, then you probably don't need this. But there are cases where tools like this fill a need.
That statement is conflating some things, re: "tool like this". In most cases, schema management tooling is a separate layer above online schema change tooling.
Online schema change tools (e.g. pt-online-schema-change) are designed to execute table alterations in a non-disruptive fashion, even if the table is huge and/or being written heavily. These tools are indeed often slower than running an ALTER TABLE directly in the database, because the non-disruptive design involves a more complex set of operations occurring in the background. No real way around that; it's a trade-off.
In contrast, schema management tools -- ranging from simple migration tools, to more complex services/daemons -- are focused on tracking schema information (either imperative migrations or declarative desired-state) in a source control repo, and executing SQL either directly or by shelling out to another tool. They sometimes include more complex components such as schema linters, verification logic, schedulers, shard mappings, web GUIs, APIs for checking whether a change has been completed yet, etc.
Pgroll is rather unusual in that it overlaps into both domains. That approach has pros and cons, but that isn't my point here; rather, I'd say it's best to avoid generalizing about "tools like this" when discussing a tool that works differently than most other software in the same space.
That aside, as someone who has spent most of the majority of the past two decades working on database infrastructure at a wide range of different scales and companies, I largely disagree with your statement about schema changes being a trivial part of the database team's day.
In my experience, that only happens in two scenarios, at opposite ends of a spectrum: either a company that isn't making many product changes and therefore doesn't have many corresponding schema changes; OR a company that has enough schema changes for safe self-service schema management automation to be a worthwhile investment.
Most "tech" companies do fall into that latter extreme though, and greatly benefit from self-service schema management automation. This is about product development velocity, not table size.
In order to avoid downtime and locking, you generally need multiple steps (e.g. some variation of add another column, backfill the data, remove previous column). You can codify this in long guidebooks on how to do schema changes (for example this one from gitlab [1]). You also need to orchestrate your app deployments in between those steps, and you often need to have some backwards compatibility code.
This is all fine but: 1. it slows you down and 2. it's manual and error prone. With pgroll, the process is always the same (start pgroll migration, deploy code, complete/rollback migration) so the team can exercise it often.
Second, while any software has bugs, it's worth noting that the main reason roll-ing back is quick and safe with pgroll is that it only has to drop views and any hidden columns. While the physical schema is changed, it is in a backwards compatible way until with complete the migration, so you can always skip the views if you have to bypass whatever pgroll is doing.
[1]: https://docs.gitlab.com/ee/development/migration_style_guide...
A bit of friction on tasks that can result in massive problems can cause people to tap the brakes a bit.
Recently on the market for a tool to manage SQL migration patches with no need for slow rollouts, I reviewed many such tools and the one that impressed me was sqitch: https://github.com/sqitchers/sqitch
So if you are interrested in this field and if Pgroll is not quite what you are looking for, I recommand you have a look at sqitch.
If you don't need slow rollouts, what would you say the downsides of using Pgroll over Sqitch would be?
(I've used neither, but I got the impression from the op that slow rollouts was a feature, not a requirement)
It's also why I'm dubious of "revert patches" in general. If there exist a revert patch for a migration, that's an easy migration. Sqitch can use a revert patch, like it can use a verify statement, but just for the convenience; it does not require them.
Yet, 9 schema migrations out of 10 are easy ones that pgroll handle nicely. It's a bit like using an ORM : if you just need a DB to store objects manipulated only in your program, sure go ahead use an ORM; but if your DB is the core of your business then you'd better not let an ORM anywhere near your schema.
At the end of the day, I'm under the impression that if one wants to handle the general case then one has to keep the whole previous DB and apps in one hand and the new DB and apps in the other, and transition customers from the former to the later. That's much less work if you don't need slow rollout.
I'm open to the fact that we may have just had legacy antipatterns drug into the project, since it was shoehorned into the team by a similarly strongly opinionated advocate
I also don't think rebasing is the nightmare everybody makes it out to be. git rebase -i follow the instructions and you are good to go
Getting people to write deploy/revert scripts are relatively easy. Asking them to write verify scripts that do more than check that a column has been added/removed is hard.
There's the "physical" issues of modifying a schema, and sqitch is great for that. But handling the "logical" issues of schema migration is more than an automated tool for running scripts.
This tool (pgroll) allows you to actually test the modified schema for logical validity without impacting the ongoing operations, which to me, seems like a win.
I came to the conclusion that you can not have anything more than that without compromising on how you can change your schema.
> So it's hard to keep track of what the actual resulting schema should look like after each change has been applied to work out whether it's correct.
At first sight, this is a gripe that has to be addressed to SQL itself that the SQL to change a schema can not trivially be inferred from the "before" and "after" schema definitions. But probably there is no way around it, il all generality.
One can store the current version of the schema in the source repository and make sure that the schema extracted after one or several applications of the migration match that.
Really the only way I can think of is some sort of DAG of DDL blobs, but I have no idea whether you can express a combination of DDL and DML changes into the one tree so that they can be properly diff'ed.
Changes in production are not just changes in the schema, there are changes to data as well. Really the entire RDBMS needs to have "time" and DDL incorporated into the relations.
What we want to do is add the ability to generate the pgroll migrations based on the prisma generated migration files. Depending on the operation, you might need to add more info.
This will work fairly generally, not only prisma.
There must be an easier way to write migrations for pgroll though. I mean, JSON, really?
The reason for JSON is because the pgroll migrations are "higher level". For example, let's say that you are adding a new unique column that should infer its data from an existing column (e.g. split `name` into `first_name` and `last_name`). The pgroll migration contains not only the info that new columns are added, but also about how to backfill the data.
The sql2pgroll converter is creating the higher level migration files, but leaves placeholder for the "up" / "down" data migrations.
The issue where sql2pgroll is tracked is this one: https://github.com/xataio/pgroll/issues/504
pgroll is written in Go, so if you were to accept configuration written in CUE, you would get the best of all worlds:
* Besides support for comments, there's first-class support in Go for writing configuration in CUE and then importing it: https://cuelang.org/docs/concept/how-cue-works-with-go/#load...
* SQL can written in files with .sql extensions and embedded in CUE with @embed: https://cuelang.org/docs/howto/embed-files-in-cue-evaluation...
At ORIS I wrote a Laravel wrapper for PTOSC and really miss it now that I'm back on PostgreSQL. Now I mostly use updatable views in front of modified tables then drop-swap things later once any transitional backfilling is done.