Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d35fd17

Browse files
committed
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
1 parent 558571a commit d35fd17

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

src/backend/replication/logical/logical.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ CheckLogicalDecodingRequirements(void)
7777
{
7878
CheckSlotRequirements();
7979

80+
/*
81+
* NB: Adding a new requirement likely means that RestoreSlotFromDisk()
82+
* needs the same check.
83+
*/
84+
8085
if (wal_level < WAL_LEVEL_LOGICAL)
8186
ereport(ERROR,
8287
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

src/backend/replication/slot.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,11 @@ ReplicationSlotsCountDBSlots(Oid dboid, int *nslots, int *nactive)
783783
void
784784
CheckSlotRequirements(void)
785785
{
786+
/*
787+
* NB: Adding a new requirement likely means that RestoreSlotFromDisk()
788+
* needs the same check.
789+
*/
790+
786791
if (max_replication_slots == 0)
787792
ereport(ERROR,
788793
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
@@ -1286,6 +1291,31 @@ RestoreSlotFromDisk(const char *name)
12861291
return;
12871292
}
12881293

1294+
/*
1295+
* Verify that requirements for the specific slot type are met. That's
1296+
* important because if these aren't met we're not guaranteed to retain
1297+
* all the necessary resources for the slot.
1298+
*
1299+
* NB: We have to do so *after* the above checks for ephemeral slots,
1300+
* because otherwise a slot that shouldn't exist anymore could prevent
1301+
* restarts.
1302+
*
1303+
* NB: Changing the requirements here also requires adapting
1304+
* CheckSlotRequirements() and CheckLogicalDecodingRequirements().
1305+
*/
1306+
if (cp.slotdata.database != InvalidOid && wal_level < WAL_LEVEL_LOGICAL)
1307+
ereport(FATAL,
1308+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1309+
errmsg("logical replication slots \"%s\" exists, but wal_level < logical",
1310+
NameStr(cp.slotdata.name)),
1311+
errhint("Change wal_level to be replica or higher.")));
1312+
else if (wal_level < WAL_LEVEL_REPLICA)
1313+
ereport(FATAL,
1314+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1315+
errmsg("physical replication slots \"%s\" exists, but wal_level < replica",
1316+
NameStr(cp.slotdata.name)),
1317+
errhint("Change wal_level to be replica or higher.")));
1318+
12891319
/* nothing can be active yet, don't lock anything */
12901320
for (i = 0; i < max_replication_slots; i++)
12911321
{

0 commit comments

Comments
 (0)