Minimal downtime major PostgreSQL version upgrades with pg_easy_replicate
21–30 of 63 posts
Re: Minimal downtime major PostgreSQL version upgrades with pg_easy_replicate
#22I checked the code and noticed some things that you might want to address in the future (I've done major version upgrades via logical replication myself several times using a script similar to this).
The "default" way of bringing the target DB in sync with the source one (CREATE PUBLICATION on the source then CREATE SUBSCRIPTION on the target) only works for moderately sized databases. Even on ~50GB I noticed that it may take hours to catch up with the origin. There are a couple of solutions:
1. Drop all indices except for the primary keys before performing initial copy, and then restore the indices after all tables have been copied and replication stream started.
2. Instead of copying into a blank database, you could instead create a logical dump using pg_dump with snapshot isolation, restore it on the target DB using pg_restore, create a subscription in the disabled state, advance the logical replication slot to the LSN with which you created the logical dump, and then enable the subscriptions. This way your target database would only have to process the delta between the time you created a dump and the current time. I have a snippet illustrating how we did it: https://gist.github.com/take-five/1dab3a99c8636a93fc69f36ff9....
3. We found out that pg_dump + pg_restore is still very slow on larger databases (~1TB) and it's untenable to wait several hours. Remember that while you're waiting until the dump is being restored, the source database is accumulating WALs which it should later send to the target DB. If left unchecked for 12-18 hours, it could lead to running out of disk space. This was unacceptable for us, so instead of creating a target DB from a logical dump, we created a copy of the source database from AWS RDS snapshot, upgraded it using pg_upgrade and then set up logical replication (similar to how it's described in Percona blog: https://www.percona.com/blog/postgresql-logical-replication-...). Something like this can probably be achieved with ZFS snapshots.
--
Otherwise, it was very similar to how you programmed your library.
Recently, I saw an article here on HN on the same topic of migrating Postgres databases using logical replication. There was a very nice idea to set up _reverse_ logical replication after switchover so that it's possible to roll back quickly in case something breaks.
EDIT: formatting
Re: Minimal downtime major PostgreSQL version upgrades with pg_easy_replicate
#23I know I am going to get fairly polarized responses on this one... Too bad it is written in Ruby.
Re: Minimal downtime major PostgreSQL version upgrades with pg_easy_replicate
#24Nice UX! I checked the code and noticed some things that you might want to address in the future (I've done major version upgrades via logical replication myself several times using a script similar to this). The "default" way of bringing the target DB in sync with the source one (CREATE PUBLICATION on the source then CREATE SUBSCRIPTION on the target) only works for moderately sized databases. Even on ~50GB I notice…
Re: bi-directional replication, you read my mind :). https://github.com/shayonj/pg_easy_replicate/blob/8df94aa93f...
These two features are top of my list to support in pg_easy_replicate
Re: Minimal downtime major PostgreSQL version upgrades with pg_easy_replicate
#25Let's say I have a Rails app and I want to do a major postgres version upgrade using this tool. I see one of the requirements is that 'Both databases should have the same schema'. How should I manually load the schema to the new database (running on port 5433 for instance)?
Yeah I think the documentation is a bit ambiguous here. Postgres "schemas" have a very specific meaning, different from what most people think of when they hear the word. It's more like a table namespace. https://www.postgresql.org/docs/current/ddl-schemas.html
So even if a tool like that needed a little boost at the beginning to get going, I’d have something that already took care of that.
Re: Minimal downtime major PostgreSQL version upgrades with pg_easy_replicate
#26Have done minimal downtime major version upgrades using standard replication, switching between two "master" servers. In the five minute range.
When the database goes down, you have to do something else. Could be the server crashed or could just be a Postgres upgrade. Five minutes is just about the right amount of time for an open circuit to do its job.
Re: Minimal downtime major PostgreSQL version upgrades with pg_easy_replicate
#27Waiting for a rolling restart or DNS cache expiration could take a while, during which the app is talking to a read-only database, if I understand correctly.
Re: Minimal downtime major PostgreSQL version upgrades with pg_easy_replicate
#28The fastest way to switchover is probably adding a iptables rule on the old server to DNAT to the new server. Unless you have a load-balancer or another network middleware like Kubernetes' clusterIP services (which uses iptables or IPVS internally). Waiting for a rolling restart or DNS cache expiration could take a while, during which the app is talking to a read-only database, if I understand correctly.
Re: Minimal downtime major PostgreSQL version upgrades with pg_easy_replicate
#29The fastest way to switchover is probably adding a iptables rule on the old server to DNAT to the new server. Unless you have a load-balancer or another network middleware like Kubernetes' clusterIP services (which uses iptables or IPVS internally). Waiting for a rolling restart or DNS cache expiration could take a while, during which the app is talking to a read-only database, if I understand correctly.
Re: Minimal downtime major PostgreSQL version upgrades with pg_easy_replicate
#30I know I am going to get fairly polarized responses on this one... Too bad it is written in Ruby.