A thread per connection is a almost always the correct decision for performance, but by choosing a process per connection, postgres is able to let you load whatever sketchy extensions you want. Worst case you crash the process, not the database. It would be nice if you could strike a balance so a segfaul in the extension only crashes a small percentage of connections, not the whole thing.

That’s not true for Postgres however: due to its usage of a shared memory pool, whenever a subprocess is terminated unexpectedly, Postgres will kill all other processes and enter recovery mode, replaying the WAL, during which time it will not accept connection requests.

It does this because it can’t possibly know whether the dying process did bad things to the shared memory pool.

You are correct! TIL, and thank you. Connection processes get a SIGQUIT, shared buffers cleared, and WAL replayed, but postmaster stays alive. It's effectively an online restart.

I’d be very curious to hear what an online restart approach for sketchy extensions crashing a shared thread per connection process might look like. This is more a question for the author of the project but I’m curious if they have plans in that direction.

systems, upstart or even simple primitive script wrapper.

Built-in is also possible: just fork once after start, and you have parent as watchdog and restarter.

What's online about this restart? Just that the tcp port keeps listening? I assume all running transaction will have to be aborted, right? And connections dropped?

The postmaster is effectively your supervisor. It could see the child segfault and abort the whole DB, but that would be deferring supervision to your init system. Not ideal.

If it's a choice between performance and being able to "safely" run sketchy extensions, I'd rather have performance.

A mixture of threads and processes that can be used to match processors, disk I/O, and network interfaces.

A very long time ago, there was once a feature called "Data Blades" which tanked a commercial database vendor. A badly behaving blade could bring down the entire database. Most anyone who has been working on databases for a few decades remembers this and makes a point of either not introducing these sorts of features or making use of processes over threads.

I have not looked at the code referenced in the mentioned project, but thus far I haven't seen a model that could craft a complete SQL parser on its own.

There are a number of problems, and design decisions, that a developer decides on when writing a database that I don't see any current models… just because you have the ingredients does not mean that the stew is edible.

Informix. Michael Stonebraker, to his credit, learned a lot along the way and revised his thinking about database technology and capability after believing that a single engine could be good at everything.

> A very long time ago, there was once a feature called "Data Blades" which tanked a commercial database vendor.

I have no idea what this is and a web search turned up Harbor Freight woodworking tools.

My first web search (data blades) turned up harbor freight woodworking tools.

Then I made a second web search: data blades database.

That turned up some ibm database software module technology which I assume is what's being discussed.

I performed both searches on Kagi and didn't see anything about IBM. I do see results for "DataBlade" and "Data blade database" but I didn't try those specific variations after my first two attempts returned nothing of interest. That's too much effort to decipher a HN post.

> That's too much effort to decipher a HN post.

It would have been less effort than it took you to write this comment. Perhaps next time that you can’t be bothered, just ignore the comment and move on to another thread that meets your required spoonfeeding levels.

Yeah you're absolutely correct. Too late to edit/delete.

ignoring the part where you tell others how to live, I believe the effort estimates you used suggest you may struggle typing and project it on others.

Doing a few searches and reviewing their results is effort.

Google doesn't really say what went wrong if it's about Informix.

people complain when not spoonfed; however there seems to be no issues about spending effort to complain.

I think it's this: https://www.ibm.com/docs/en/informix-servers/15.0.x?topic=co...

And what you found seems to be "Dado", not "Data".

Yes, Kagi was sufficiently confused as to what "Data blades" are that it actually thought I was looking for replacement woodworking blades. "DataBlade" finds the IBM Informix product.

While PG's behavior doesn't guarantee a lack of data corruption, "an extension crashed, all bets are off, tear everything down" is going to give you a much better fighting chance against data corruption vs the alternative.

In the age of vibe-generated code, I promise you're gonna want the safety.

What about just not installing sketchy extensions?

I know right? Postgres is not firefox, we don't operate with 25 extensions on all the time. At most we have 1 and normally we have 0.

So load them up in read replicas

Or use webassembly to sandbox them

[deleted]

You have to have a write path. You're gonna want what to be non-sketchy and performant.

Especially since all those sketchy extensions can be rewritten in rust over a weekend and have their bugs fixed as well.

You could fix probably the sketchy extension issue with WASM.

Limit, not fix.

Do you mean that you don't run sketchy extensions and therefore this doesn't affect you, or that you're ok with data loss due to extension failures?

What about extensions that are not sketchy? Lots of good ones out there.

People are assuming the extensions can't also be rewritten to be good.

Presumably they'd be fine running in a threaded context.

An extension written for a single threaded host system might not work in a multi-threaded context. For example if has global or shared state that isn't protected with locks or similar (which is unfortunately fairly common in c code)

Extensions like pgvector, TimescaleDB would probably need to be ported tho, not sure how much but there are footguns.

Not needed in many (most?) cases.

But it isn't.

Threads does not offer any major performance advantage, performance of processes vs threads is virtually the same. The reason the PostgreSQL project is moving towards threads is to make development easier.

> Threads does not offer any major performance advantage

This is very not true. When it comes to parallel queries, a process model adds a ton of overhead. You can't pass pointers between processes because the address space is different. This adds a ton of overhead in a bunch of different places. For example when doing a parallel hash join, Postgres will have each worker build a local hash table. Then it will take all the tuples out of the local hash table and copy them through shared memory to the leader who will then construct a new hash table. This duplicates a lot of work as you have to hash the tuples multiple times.

A lot of getting to Clickhouse level performance was making better use of parallelism.

Passing pointers is not significantly faster than passing offsets into a shared memory pool.

Sorry, what? Passing a pointer is a matter of wrapping the value into the CPU register. OTOH passing an offset into a shared memory is a write to main memory so several magnitudes slower.

Ok ... you know PostgreSQL supports hash tables in shared memory, right? PostgreSQL could in theory share those if we wanted to. The issue is just that coding anything which uses shared memory is a lot of work.

Additionally the reasons PostgreSQL does not offer Clickhouse performance has very little to do with parallelism. PostgreSQL plans to move to threading but the efforts around imporving OLAP performance are almost entirely unrelated.

> The issue is just that coding anything which uses shared memory is a lot of work.

Doesn’t that kind of prove the parent’s point though? In theory shared memory can do anything that threads can do. But if in practice some feature doesn’t get implemented in the multi-process design (because shared memory is hard), when it likely would have been implemented in a threaded design, then that’s still an advantage for threads.

Apart from being a lot of work are you really gaining much at that point? Memory corruption can still take down both sides...

i may be missing context, but shared memory across processes, without ipc?

There's nothing special about threads vs processes in Linux. mmap works the same, the challenge is to map the same file. You can share a path, pass a file descriptor via fork or unix domain socket, among other techniques.

That induces disk I/O overhead (even if it somehow doesn't impact IPC performance)

It doesnt. Processes can share memory

The file doesn’t have to be disk-backed.

Don't you need something mounted for that?

No, you can use a memfd.

And `/dev/shm/` (which postgres uses by default on most Unix platforms)

Being really pedantic here, shared memory is considered IPC, but not the kind you're thinking of. Shared address space, no overhead.

As long as we're pedantic ... the subject is shared memory. Unless you specify the same, non-null, target address in the call to mmap (and the kernel happens to grant you that mapping on all calling sites), the addresses will be different; the address space is not shared (each mapping might also have different access permissions).

That distinction is important as pointers generally cannot be shared (a problem which can of course be solved with one more indirection ;-) .

MSSQL can handle 32k open connections no need to run a pooler in front of it, can PG do 32k connections and a process for each?

MSSQL shares cached query plans between connections including jitted code, PG cannot do that and the changes needed to make the plans cross process portable would be extensive while sharing between threads is just normal code sharing between threads.

unless you're spawning them for new connections.

Some, but not that much. Switching PostgreSQL to a threaded model will not magically make spawning connections fast. PostgreSQL connections are quite heavyweight.

The reason to use threads is almost entirely about ease of development, not about performance. If you use shrared memory like PostgreSQL does you need to write your own allocators, etc. So much you get for free if you use threads.

Doesn't postgres (rightly) have a cow if a process has a disorderly shutdown (at least while in a write transaction) because there's shared memory between the processes?

Some see a 30 year old system and think "outdated", I see a 30 year old system and think "time tested."

Clearly a process per connection is more stable and that's what I'm using.

It's unclear what problem such optimizations are solving anyway, with the old way you could only support a million concurrent users with a single server? Are we missing out on supporting ten million concurrent users with 2 servers instead of 10? Ostensibly reducing the minimum db hardware opex for a 10B$ company from 10k$/month to 2k$/month?

A million users? Hell, I'd bet 99.999% of live postgres databases in existence serve less than 5 users on average. Even among products that actually make a profit, I bet 99.9% of them serve less than 100 customers a day. We hooligans on hacker news manage the 0.1% of databases, and in my newfound consulting life, I'm hoping to never support one of those again.

> Clearly a process per connection is more stable

Even if those processes share most of their memory, and are written in a notoriously memory-unsafe language?

A significant performance improvement can well be the difference between being able to run the entire database on one beefy server, and having to shard. And that has a huge cost in terms of complexity and thus reliability and development time.

Is that a serious issue? Wouldn't it just restart the split second later? Or does it take a long time to start?

(Or I guess it would get stuck in a doom loop or something?)

I'm not informed of the Postgres's internals, but, maybe, that can be solved by grouping threads into different processes depending on which set of extensions they request.

[deleted]

A more modern way to do this might be to support WebAssembly plugins.

The extensions might need to be rewritten, but hey, we have AI for that now, so why not :-)

An OS thread per connection can be fine for performance if you don't have to scale your connections, but if you don't need to scale connections why have connections at all? Databases are even more performant when you eliminate connection overhead entirely.

Thread pools

[deleted]