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

Commit b48df81

Browse files
committed
Fix oldest xmin and LSN computation across repslots after advancing
Advancing a replication slot did not recompute the oldest xmin and LSN values across replication slots, preventing resource removal like segments not recycled at checkpoint time. The original commit that introduced the slot advancing in 9c7d06d never did the update of those oldest values, and b0afdca removed this code. This commit adds a TAP test to check segment recycling with advancing for physical slots, enforcing an extra segment switch before advancing to check if the segment gets correctly recycled after a checkpoint. Reported-by: Andres Freund Reviewed-by: Alexey Kondratov, Kyptaro Horiguchi Discussion: https://postgr.es/m/20200609171904.kpltxxvjzislidks@alap3.anarazel.de Backpatch-through: 11
1 parent 0a40563 commit b48df81

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

src/backend/replication/slotfuncs.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,13 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
621621
values[0] = NameGetDatum(&MyReplicationSlot->data.name);
622622
nulls[0] = false;
623623

624+
/*
625+
* Recompute the minimum LSN and xmin across all slots to adjust with the
626+
* advancing potentially done.
627+
*/
628+
ReplicationSlotsComputeRequiredXmin(false);
629+
ReplicationSlotsComputeRequiredLSN();
630+
624631
ReplicationSlotRelease();
625632

626633
/* Return the reached position. */

src/test/recovery/t/001_stream_rep.pl

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use warnings;
44
use PostgresNode;
55
use TestLib;
6-
use Test::More tests => 35;
6+
use Test::More tests => 36;
77

88
# Initialize master node
99
my $node_master = get_new_node('master');
@@ -364,15 +364,26 @@ sub replay_check
364364
qq[SELECT 1 FROM replayed WHERE val = $newval]);
365365
is($is_replayed, qq(1), "standby_2 didn't replay master value $newval");
366366

367+
# Drop any existing slots on the primary, for the follow-up tests.
368+
$node_master->safe_psql('postgres',
369+
"SELECT pg_drop_replication_slot(slot_name) FROM pg_replication_slots;");
370+
367371
# Test physical slot advancing and its durability. Create a new slot on
368372
# the primary, not used by any of the standbys. This reserves WAL at creation.
369373
my $phys_slot = 'phys_slot';
370374
$node_master->safe_psql('postgres',
371375
"SELECT pg_create_physical_replication_slot('$phys_slot', true);");
376+
# Generate some WAL, and switch to a new segment, used to check that
377+
# the previous segment is correctly getting recycled as the slot advancing
378+
# would recompute the minimum LSN calculated across all slots.
379+
my $segment_removed = $node_master->safe_psql('postgres',
380+
'SELECT pg_walfile_name(pg_current_wal_lsn())');
381+
chomp($segment_removed);
372382
$node_master->psql(
373383
'postgres', "
374384
CREATE TABLE tab_phys_slot (a int);
375-
INSERT INTO tab_phys_slot VALUES (generate_series(1,10));");
385+
INSERT INTO tab_phys_slot VALUES (generate_series(1,10));
386+
SELECT pg_switch_wal();");
376387
my $current_lsn =
377388
$node_master->safe_psql('postgres', "SELECT pg_current_wal_lsn();");
378389
chomp($current_lsn);
@@ -392,3 +403,9 @@ sub replay_check
392403
chomp($phys_restart_lsn_post);
393404
ok( ($phys_restart_lsn_pre cmp $phys_restart_lsn_post) == 0,
394405
"physical slot advance persists across restarts");
406+
407+
# Check if the previous segment gets correctly recycled after the
408+
# server stopped cleanly, causing a shutdown checkpoint to be generated.
409+
my $master_data = $node_master->data_dir;
410+
ok(!-f "$master_data/pg_wal/$segment_removed",
411+
"WAL segment $segment_removed recycled after physical slot advancing");

0 commit comments

Comments
 (0)