mirror of
https://github.com/postgres/postgres.git
synced 2025-05-11 05:41:32 +03:00
Disallow starting server with insufficient wal_level for existing slot.
Previously it was possible to create a slot, change wal_level, and restart, even if the new wal_level was insufficient for the slot. That's a problem for both logical and physical slots, because the necessary WAL records are not generated. This removes a few tests in newer versions that, somewhat inexplicably, whether restarting with a too low wal_level worked (a buggy behaviour!). Reported-By: Joshua D. Drake Author: Andres Freund Discussion: https://postgr.es/m/20181029191304.lbsmhshkyymhw22w@alap3.anarazel.de Backpatch: 9.4-, where replication slots where introduced
This commit is contained in:
parent
558571afc7
commit
d35fd17cb5
@ -77,6 +77,11 @@ CheckLogicalDecodingRequirements(void)
|
||||
{
|
||||
CheckSlotRequirements();
|
||||
|
||||
/*
|
||||
* NB: Adding a new requirement likely means that RestoreSlotFromDisk()
|
||||
* needs the same check.
|
||||
*/
|
||||
|
||||
if (wal_level < WAL_LEVEL_LOGICAL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
|
@ -783,6 +783,11 @@ ReplicationSlotsCountDBSlots(Oid dboid, int *nslots, int *nactive)
|
||||
void
|
||||
CheckSlotRequirements(void)
|
||||
{
|
||||
/*
|
||||
* NB: Adding a new requirement likely means that RestoreSlotFromDisk()
|
||||
* needs the same check.
|
||||
*/
|
||||
|
||||
if (max_replication_slots == 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
@ -1286,6 +1291,31 @@ RestoreSlotFromDisk(const char *name)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that requirements for the specific slot type are met. That's
|
||||
* important because if these aren't met we're not guaranteed to retain
|
||||
* all the necessary resources for the slot.
|
||||
*
|
||||
* NB: We have to do so *after* the above checks for ephemeral slots,
|
||||
* because otherwise a slot that shouldn't exist anymore could prevent
|
||||
* restarts.
|
||||
*
|
||||
* NB: Changing the requirements here also requires adapting
|
||||
* CheckSlotRequirements() and CheckLogicalDecodingRequirements().
|
||||
*/
|
||||
if (cp.slotdata.database != InvalidOid && wal_level < WAL_LEVEL_LOGICAL)
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("logical replication slots \"%s\" exists, but wal_level < logical",
|
||||
NameStr(cp.slotdata.name)),
|
||||
errhint("Change wal_level to be replica or higher.")));
|
||||
else if (wal_level < WAL_LEVEL_REPLICA)
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("physical replication slots \"%s\" exists, but wal_level < replica",
|
||||
NameStr(cp.slotdata.name)),
|
||||
errhint("Change wal_level to be replica or higher.")));
|
||||
|
||||
/* nothing can be active yet, don't lock anything */
|
||||
for (i = 0; i < max_replication_slots; i++)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user