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

Commit691d79a

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 parent696b0c5 commit691d79a

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
@@ -79,6 +79,11 @@ CheckLogicalDecodingRequirements(void)
7979
{
8080
CheckSlotRequirements();
8181

82+
/*
83+
* NB: Adding a new requirement likely means that RestoreSlotFromDisk()
84+
* needs the same check.
85+
*/
86+
8287
if (wal_level<WAL_LEVEL_LOGICAL)
8388
ereport(ERROR,
8489
(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
@@ -971,6 +971,11 @@ ReplicationSlotsDropDBSlots(Oid dboid)
971971
void
972972
CheckSlotRequirements(void)
973973
{
974+
/*
975+
* NB: Adding a new requirement likely means that RestoreSlotFromDisk()
976+
* needs the same check.
977+
*/
978+
974979
if (max_replication_slots==0)
975980
ereport(ERROR,
976981
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
@@ -1502,6 +1507,31 @@ RestoreSlotFromDisk(const char *name)
15021507
return;
15031508
}
15041509

1510+
/*
1511+
* Verify that requirements for the specific slot type are met. That's
1512+
* important because if these aren't met we're not guaranteed to retain
1513+
* all the necessary resources for the slot.
1514+
*
1515+
* NB: We have to do so *after* the above checks for ephemeral slots,
1516+
* because otherwise a slot that shouldn't exist anymore could prevent
1517+
* restarts.
1518+
*
1519+
* NB: Changing the requirements here also requires adapting
1520+
* CheckSlotRequirements() and CheckLogicalDecodingRequirements().
1521+
*/
1522+
if (cp.slotdata.database!=InvalidOid&&wal_level<WAL_LEVEL_LOGICAL)
1523+
ereport(FATAL,
1524+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1525+
errmsg("logical replication slots \"%s\" exists, but wal_level < logical",
1526+
NameStr(cp.slotdata.name)),
1527+
errhint("Change wal_level to be replica or higher.")));
1528+
elseif (wal_level<WAL_LEVEL_REPLICA)
1529+
ereport(FATAL,
1530+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1531+
errmsg("physical replication slots \"%s\" exists, but wal_level < replica",
1532+
NameStr(cp.slotdata.name)),
1533+
errhint("Change wal_level to be replica or higher.")));
1534+
15051535
/* nothing can be active yet, don't lock anything */
15061536
for (i=0;i<max_replication_slots;i++)
15071537
{

‎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
@@ -135,26 +135,5 @@
135135
is($node_master->slot('otherdb_slot')->{'slot_name'},
136136
undef,'logical slot was actually dropped with DB');
137137

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp