Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit021e1c3

Browse files
committed
Disallow starting server with insufficient wal_level for existing slot.
Previously it was possible to create a slot, change wal_level, andrestart, even if the new wal_level was insufficient for theslot. That's a problem for both logical and physical slots, becausethe necessary WAL records are not generated.This removes a few tests in newer versions that, somewhatinexplicably, whether restarting with a too low wal_level worked (abuggy behaviour!).Reported-By: Joshua D. DrakeAuthor: Andres FreundDiscussion:https://postgr.es/m/20181029191304.lbsmhshkyymhw22w@alap3.anarazel.deBackpatch: 9.4-, where replication slots where introduced
1 parent92e371f commit021e1c3

File tree

3 files changed

+36
-22
lines changed

3 files changed

+36
-22
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
@@ -972,6 +972,11 @@ ReplicationSlotsDropDBSlots(Oid dboid)
972972
void
973973
CheckSlotRequirements(void)
974974
{
975+
/*
976+
* NB: Adding a new requirement likely means that RestoreSlotFromDisk()
977+
* needs the same check.
978+
*/
979+
975980
if (max_replication_slots==0)
976981
ereport(ERROR,
977982
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
@@ -1487,6 +1492,31 @@ RestoreSlotFromDisk(const char *name)
14871492
return;
14881493
}
14891494

1495+
/*
1496+
* Verify that requirements for the specific slot type are met. That's
1497+
* important because if these aren't met we're not guaranteed to retain
1498+
* all the necessary resources for the slot.
1499+
*
1500+
* NB: We have to do so *after* the above checks for ephemeral slots,
1501+
* because otherwise a slot that shouldn't exist anymore could prevent
1502+
* restarts.
1503+
*
1504+
* NB: Changing the requirements here also requires adapting
1505+
* CheckSlotRequirements() and CheckLogicalDecodingRequirements().
1506+
*/
1507+
if (cp.slotdata.database!=InvalidOid&&wal_level<WAL_LEVEL_LOGICAL)
1508+
ereport(FATAL,
1509+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1510+
errmsg("logical replication slots \"%s\" exists, but wal_level < logical",
1511+
NameStr(cp.slotdata.name)),
1512+
errhint("Change wal_level to be replica or higher.")));
1513+
elseif (wal_level<WAL_LEVEL_REPLICA)
1514+
ereport(FATAL,
1515+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1516+
errmsg("physical replication slots \"%s\" exists, but wal_level < replica",
1517+
NameStr(cp.slotdata.name)),
1518+
errhint("Change wal_level to be replica or higher.")));
1519+
14901520
/* nothing can be active yet, don't lock anything */
14911521
for (i=0;i<max_replication_slots;i++)
14921522
{

‎src/test/recovery/t/006_logical_decoding.pl

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use warnings;
88
use PostgresNode;
99
use TestLib;
10-
use Test::Moretests=>16;
10+
use Test::Moretests=>10;
1111
use Config;
1212

1313
# Initialize master node
@@ -133,26 +133,5 @@
133133
is($node_master->slot('otherdb_slot')->{'slot_name'},
134134
undef,'logical slot was actually dropped with DB');
135135

136-
# Restarting a node with wal_level = logical that has existing
137-
# slots must succeed, but decoding from those slots must fail.
138-
$node_master->safe_psql('postgres','ALTER SYSTEM SET wal_level = replica');
139-
is($node_master->safe_psql('postgres','SHOW wal_level'),
140-
'logical','wal_level is still logical before restart');
141-
$node_master->restart;
142-
is($node_master->safe_psql('postgres','SHOW wal_level'),
143-
'replica','wal_level is replica');
144-
isnt($node_master->slot('test_slot')->{'catalog_xmin'},
145-
'0','restored slot catalog_xmin is nonzero');
146-
is($node_master->psql(
147-
'postgres',
148-
qq[SELECT pg_logical_slot_get_changes('test_slot', NULL, NULL);]),
149-
3,
150-
'reading from slot with wal_level < logical fails');
151-
is($node_master->psql(
152-
'postgres',q[SELECT pg_drop_replication_slot('test_slot')]),
153-
0,
154-
'can drop logical slot while wal_level = replica');
155-
is($node_master->slot('test_slot')->{'catalog_xmin'},'','slot was dropped');
156-
157136
# done with the node
158137
$node_master->stop;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp