Why I Enjoy PostgreSQL – Infrastructure Engineer's Perspective
shayon.dev
shayon.dev
I would expect major caveats in such a feature, like long lived table locks taking down the whole application for an hour when you don't exactly know what you're doing. For example concurrent index creation is harmless on its own, but combined with another fast but locking schema change, you could get a long lived lock, taking down the application until the index creation finishes (had a similar incident in a different database).
MS SQL fellow here, rather than postgres, but the concepts should be the same. No docs I can immediately point you at, but some feeling for how I [don't] do things:
I still wouldn't perform most schema updates in live production, I'd wait for a maintenance window.
The key benefit from my PoV is that the changes are transactional so either all work or they rollback and you are back where you started instead of some mysterious mid-way point. Adding indexes is fine, as long as you have spare IO capacity for the process to chew if performed on a large table, and many index alterations can be done online too, and adding/modifying procs, views, and similar objects can be similarly undisruptive if properly wrapped in transactions (so active sessions never see a half updated set of parts), but I'd not make actual table changes “properly live” in production.
> I would expect major caveats in such a feature, like long lived table locks
In DBs with transactional DDL some table operations are practically lock-free or just happen so fast that they might as well be, such as (usually) adding a NULLable column or making an existing one NULLable, and some other operations are, despite being long-winded, sometimes possible to perform online (the new structure is added, then a final sync done for changes made while that happened, then switched over to, and the old parts cleaned up now the new are in use), but I'd never risk it unless I really really had to make the change ASAP and absolutely couldn't arrange a maintenance break in good time.
> For example concurrent index creation is harmless on its own, but combined with another fast but locking schema change
There should only ever be your process making schema changes, as the application and other users shouldn't be at all, so in theory you don't need to worry about two changes competing for locks or causing lock escalation like that. Several concurrent online index creations/modifications are fine, as long as you can afford the extra IO load that will impose, particularly if the objects being touched are on different storage (or otherwise have separate IO quotas) so the two index changes won't compete with each other for IO, but not table changes and similar: keep them to one at once, while nothing else is happening.
By default it runs all of your DDL within a transaction, but in some cases where you can't run in a transaction (like adding a value to an enum type) it makes it easy to disable it: https://knexjs.org/#Migrations-API-transactions
Same with MS SQL Server. Make several schema changes, and be assured that if things go base-over-apex part way through you are going to be returned to the last good state.
I kid, I kid, but yeah it feels like there's some room for improvement when it comes to the infrastructure side of working with Postgres
It was discussed here on HN about a week back: https://news.ycombinator.com/item?id=29825520
Replication and failover are actually hard problems to solve and the logical replication now gives Postgres the flexibility needed to avoid the WAL-shipping (and the Oracle et al equivalents).
In particular, RDBMS with ACID require 2-phase commits to have true replication, which then requires a transaction controller, which then needs to be HA and have failover. Lots of people cut corners on this and only discover their loss of data when a failover event happens.
PostGIS is truly amazing and I'm not sure any other RDBMS has a similarly extended GIS capability.
To be fair to Snowflake, they make a great product, even if their pricing model is bananas and they want to be Oracle when they grow up.
> When an infrastructure engineer tells you they prefer MySQL. It’s probably because for them it’s simpler/easier to operate it. Backups, replication, failover, upgrades. Accomplishing what is most important to them.
> When product engineers prefer postgres, it’s usually because of something like postgis, jsonb/hstore. Some feature they can use in the app to build something faster.
> I hope this helps in explaining why you often see the infra orgs of many large/high scale companies choose mysql.
Isn't that missing a very important reason which is that
(a) MySQL was better known in the period 2000-2010 when is when many of the large/high scale companies started to create their infrastructure, and
(b) Your choice of database tends to be sticky
PostgreSQL's replication is still a bit of a pain and MySQL has things like Vitess that which offer great tools for scaling out a database (including sharding, replication, etc)
PostgreSQL has improved a lot from the 2000-2010 time period, but MySQL still has some good stuff going for it.
I have yet to play with postgis specifically, i have read many good things. Thinking of un-archiving some old side projects and experimenting with postgis!
• Materialized views with indexing are an easy way to solve many speed issues where you'd like to use a fancy query quickly.
• The GEOGRAPHY data type is great for data integrity, but often slower for queries. I've made sure our primary data is stored as GEOGRAPHY then added expression indices [1] casting to GEOMETRY. Spatial joins and filters can be done on the casted column where faster queries are needed.
• Source data is often very high resolution. If you don't need it, simplifying high accuracy data (5m or whatever) to something much lower resolution (500m, 1km, or whatever) in a derived view or table using PostGIS' simplification functions can greatly improve spatial predicate performance.
[1] https://www.postgresql.org/docs/14/indexes-expressional.html
Now.. which order was the correct one? I have forgotten after not doing gis stuff for some years now.
The Postgres documentation (which is generally excellent) describes workflows for upgrading across major releases, including what can be fairly described as an "in-place" upgrade, via pg_upgrade and the "--link" option.
Upgrades without downtime can be achieved by using logical replication to create a standby instance running the new major release, then switching the new instance to primary.
The one place where I've found DBUA to fail is an upgrade of a 32-bit database to 64-bit (version 11.2.0.4 was the last offered for 32-bit). This type of upgrade requires the command-line dbupgrade utility, and it's a bit more complex.
Complete export/import is only required when switching architectures for Oracle. Postgres should try for this sometime.
I've also seen MS SQL Server quietly upgrade an imported database.
I'm loving the cockroachdb upgrade process for our cluster - you just do a zero-downtime rolling restart to the next major version, with the ability to roll back to the old version if you see issues, and then when ready allow the database to apply it's migrations internally to upgrade the data structures, which is also zero-downtime.
I think that "Real Application Cluster" (RAC) databases, where multiple Oracle database instances are connected to the storage table spaces, are able to perform a rolling upgrade, but I have not researched it in depth. I am certain that quarterly patches can be deployed in this way.
> As next steps, we’re continuing to investigate the specific failure scenario, and have paused schema migrations until we know more on safeguarding against this issue.
While MSSQL has some nice operational features over SQLAnywhere, it feels like going back to the stone age in terms of writing queries.
Most annoyingly are the silly limitations w.r.t. aliases, there's no regexp matching, no nice list() function only annoying string_agg()...
Especially the aliases will be super-painful. Just going through a few non-trivial ones, I'm looking at turning them into 5+ levels of nesting due to that.
Alas, our customers wants to manage their own MSSQL instance, so that's what we gotta cater for. If I had anything to say, we'd most definitely would move to PostgreSQL.
https://babelfishpg.org/docs/internals/software-architecture...
If you must use Microsoft SQL Server, at least deploy it on Linux.
Microsoft's published TPC-H scores are all higher on Linux than Windows, and Patch Tuesday is agony for those who need an available database.
Oracle's Ksplice is also free on Ubuntu. Try to use XFS, as all the top TPC scores seem to be using this filesystem.
http://tpc.org/tpch/results/tpch_perf_results5.asp?resulttyp...
I did not, that's really interesting thanks!
> If you must use Microsoft SQL Server, at least deploy it on Linux
For customers where we'll still be managing the DB, that's definitely an option I'll push for checking out.
That said, management can trump peak performance. We've been a Windows shop for 20+ years, if support judges it too hard to learn the idea is DOA.
It needs external connection manager (pgbouncer). Replication is very basic: one should do a backup/restore first and then start a replication praying in the meantime for WAL not to run too far. Until version 13 (released year ago) it was either that, or dedicated replication slot will overflow the disk and kill your master if any replica falls out of sync.
No automatic failover out of the box? That's not what I used to with Mongo. Come on, even Redis learned that trick (with Sentinel, yes, but it is part of the package).
Continuous WAL archiving and point-in-time-recovery is a nice feature, but it needs fs-level backup, not the one from pg_dump. What pg_dump is for, then?
Need time and experience to wrap my head around all this.
Anyway, to start of: why would you want a connection manager Middleware for a pet project? Do you honestly expect to need hundreds/thousands of simultaneous db connections?
The original replication does exactly what it was supposed to, but is not what developers often think they want, which is clearly the reason for your outrage. Clustering isn't easy, as mongodb continues to prove to day by making creation of them easy but then catastrophically fail in production under load as the countless post mortems show. I really doubt you're going to need it anyway for a pet project....
As an employee of MongoDB we treat "catastrophic" failures of our software pretty seriously. If you have experienced a failure we want to hear about. Paying customer or no...
I've heard that MongoDB has improved a lot over the years, so I really shouldn't have said that.
I see a recommendation of using pgbouncer almost on every tutorial and how-to and feel it is really a vital point. As a newbie user I want to be on a safe side with that. Also, heavily concurrent app architecture, even with connection pooling, may easily produce tens of connections with moderate load and jump to hundreds during peaks. I know from the experience that API users tend not to think about load they create on the other side, just hacking together series of wrapped calls.
Can you elaborate on "countless postmortems", please? On my work we recently had a 12 hours downtime on one of our 20 Mongo databases, but it was caused by a mistake during recovery from storage overflow. I will give a credit to Postgres here, by the way: on disk with 0 bytes free it still works in read-only mode.
It is production ready as long as you want to run it on a single box and scale vertically - which is a lot of projects out there. Agree on the other points.
You are right. Despite I love PostgreSQL, MongoDB is eons ahead in terms of replication and sharding.
Also, it is possible to horizontally scale postgres. It's not for the light of heart, but the easiest way is with read only replicas, which is pretty easy (especially with RDS), and read heavy loads are where postgres really shines, and also most apps out there.