Check the number of potential synchronous standbys
Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.
You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:
docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t40776psql -h localhost -U postgresBuilt from patchset v1 (message #1), September 20, 2026 at 08:28 AM.
Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:
git clone --branch t40776_1 https://github.com/hackorum-dev/postgres.gitIn a checkout you already have, add the fork once:
git remote add hackorum https://github.com/hackorum-dev/postgres.gitthen, for this patchset and every later one:
git fetch hackorum t40776_1 && git checkout t40776_1Patchset v1 (message #1) is on t40776_1
Hi all,
When the number of potential synchronous standbys is smaller than num_sync, such as 'FIRST 3 (1,2)', 'ANY 4 (1,2,3)' in the synchronous_standby_names, the processes will wait for synchronous replication forever.
Obviously, it's not expected. I think return false and a error message may be better. And attached is a patch that implements the simple check.
What do you think about this?
--
Zhang Wenjie
"=?gb18030?B?1cXOxL3c?=" <757634191@qq.com> writes:
When the number of potential synchronous standbys is smaller than num_sync, such as 'FIRST 3 (1,2)', 'ANY 4 (1,2,3)' in the synchronous_standby_names, the processes will wait for synchronous replication forever.
Obviously, it's not expected. I think return false and a error message may be better. And attached is a patch that implements the simple check.
Well, it's not *that* simple; this patch rejects cases like "ANY 2(*)"
which need to be accepted. That causes the src/test/recovery tests
to fail (you should have tried check-world).
I also observe that there's a test case in 007_sync_rep.pl which is
actually exercising the case you want to reject:
# Check that sync_state of each standby is determined correctly
# when num_sync exceeds the number of names of potential sync standbys
# specified in synchronous_standby_names.
test_sync_state(
$node_master, qq(standby1|0|async
standby2|4|sync
standby3|3|sync
standby4|1|sync),
'num_sync exceeds the num of potential sync standbys',
'6(standby4,standby0,standby3,standby2)');
So it can't be said that nobody thought about this at all.
Now, I'm not convinced that this represents a useful use-case as-is.
However, because we can't know how many standbys may match "*",
it's clear that the code has to do something other than just
abort when the situation happens. Conceivably we could fail at
runtime (not GUC parse time) if the number of required standbys
exceeds the number available, rather than waiting indefinitely.
However, if standbys can come online dynamically, a wait involving
"*" might be satisfiable after awhile even if it isn't immediately.
On the whole, given the fuzziness around "*", I'm not sure that
it's easy to make this much better.
regards, tom lane