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

Commitb0afdca

Browse files
committed
Fix slot data persistency when advancing physical replication slots
Advancing a physical replication slot with pg_replication_slot_advance()did not mark the slot as dirty if any advancing was done, preventing thefollow-up checkpoint to flush the slot data to disk. This caused theadvancing to be lost even on clean restarts. This does not happen forlogical slots as any advancing marked the slot as dirty. Perdiscussion, the original feature has been implemented so as in the eventof a crash the slot may move backwards to a past LSN. This property iskept and more documentation is added about that.This commit adds some new TAP tests to check the persistency of physicaland logical slots after advancing across clean restarts.Author: Alexey Kondratov, Michael PaquierReviewed-by: Andres Freund, Kyotaro Horiguchi, Craig RingerDiscussion:https://postgr.es/m/059cc53a-8b14-653a-a24d-5f867503b0ee@postgrespro.ruBackpatch-through: 11
1 parent26a81bb commitb0afdca

File tree

4 files changed

+67
-16
lines changed

4 files changed

+67
-16
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20470,8 +20470,11 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
2047020470
<entry>
2047120471
Advances the current confirmed position of a replication slot named
2047220472
<parameter>slot_name</parameter>. The slot will not be moved backwards,
20473-
and it will not be moved beyond the current insert location. Returns
20474-
name of the slot and real position to which it was advanced to.
20473+
and it will not be moved beyond the current insert location. Returns
20474+
the name of the slot and the real position to which it was advanced to.
20475+
The information of the updated slot is written out at the follow-up
20476+
checkpoint if any advancing is done. In the event of a crash, the
20477+
slot may return to an earlier position.
2047520478
</entry>
2047620479
</row>
2047720480

‎src/backend/replication/slotfuncs.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,14 @@ pg_physical_replication_slot_advance(XLogRecPtr moveto)
370370
MyReplicationSlot->data.restart_lsn=moveto;
371371
SpinLockRelease(&MyReplicationSlot->mutex);
372372
retlsn=moveto;
373+
374+
/*
375+
* Dirty the slot so as it is written out at the next checkpoint.
376+
* Note that the LSN position advanced may still be lost in the
377+
* event of a crash, but this makes the data consistent after a
378+
* clean shutdown.
379+
*/
380+
ReplicationSlotMarkDirty();
373381
}
374382

375383
returnretlsn;
@@ -467,9 +475,9 @@ pg_logical_replication_slot_advance(XLogRecPtr moveto)
467475
* keep track of their progress, so we should make more of an
468476
* effort to save it for them.
469477
*
470-
* Dirty the slot so it's written out at the next checkpoint.
471-
*We'll still lose its position on crash, as documented, but it's
472-
*better than always losingtheposition even oncleanrestart.
478+
* Dirty the slot so it is written out at the next checkpoint.
479+
*The LSN position advanced to may still be lost on a crash
480+
*but this makesthedata consistent after acleanshutdown.
473481
*/
474482
ReplicationSlotMarkDirty();
475483
}
@@ -566,15 +574,6 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS)
566574
values[0]=NameGetDatum(&MyReplicationSlot->data.name);
567575
nulls[0]= false;
568576

569-
/* Update the on disk state when lsn was updated. */
570-
if (XLogRecPtrIsInvalid(endlsn))
571-
{
572-
ReplicationSlotMarkDirty();
573-
ReplicationSlotsComputeRequiredXmin(false);
574-
ReplicationSlotsComputeRequiredLSN();
575-
ReplicationSlotSave();
576-
}
577-
578577
ReplicationSlotRelease();
579578

580579
/* Return the reached position. */

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

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use warnings;
44
use PostgresNode;
55
use TestLib;
6-
use Test::Moretests=>32;
6+
use Test::Moretests=>34;
77

88
# Initialize master node
99
my$node_master = get_new_node('master');
@@ -344,3 +344,28 @@ sub replay_check
344344
is($xmin,'','xmin of cascaded slot null with hs feedback reset');
345345
is($catalog_xmin,'',
346346
'catalog xmin of cascaded slot still null with hs_feedback reset');
347+
348+
# Test physical slot advancing and its durability. Create a new slot on
349+
# the primary, not used by any of the standbys. This reserves WAL at creation.
350+
my$phys_slot ='phys_slot';
351+
$node_master->safe_psql('postgres',
352+
"SELECT pg_create_physical_replication_slot('$phys_slot', true);");
353+
$node_master->psql('postgres',"
354+
CREATE TABLE tab_phys_slot (a int);
355+
INSERT INTO tab_phys_slot VALUES (generate_series(1,10));");
356+
my$current_lsn =$node_master->safe_psql('postgres',
357+
"SELECT pg_current_wal_lsn();");
358+
chomp($current_lsn);
359+
my$psql_rc =$node_master->psql('postgres',
360+
"SELECT pg_replication_slot_advance('$phys_slot', '$current_lsn'::pg_lsn);");
361+
is($psql_rc,'0','slot advancing with physical slot');
362+
my$phys_restart_lsn_pre =$node_master->safe_psql('postgres',
363+
"SELECT restart_lsn from pg_replication_slots WHERE slot_name = '$phys_slot';");
364+
chomp($phys_restart_lsn_pre);
365+
# Slot advance should persist across clean restarts.
366+
$node_master->restart;
367+
my$phys_restart_lsn_post =$node_master->safe_psql('postgres',
368+
"SELECT restart_lsn from pg_replication_slots WHERE slot_name = '$phys_slot';");
369+
chomp($phys_restart_lsn_post);
370+
ok(($phys_restart_lsn_precmp$phys_restart_lsn_post) == 0,
371+
"physical slot advance persists across restarts");

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

Lines changed: 25 additions & 1 deletion
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=>10;
10+
use Test::Moretests=>12;
1111
use Config;
1212

1313
# Initialize master node
@@ -135,5 +135,29 @@
135135
is($node_master->slot('otherdb_slot')->{'slot_name'},
136136
undef,'logical slot was actually dropped with DB');
137137

138+
# Test logical slot advancing and its durability.
139+
my$logical_slot ='logical_slot';
140+
$node_master->safe_psql('postgres',
141+
"SELECT pg_create_logical_replication_slot('$logical_slot', 'test_decoding', false);");
142+
$node_master->psql('postgres',"
143+
CREATE TABLE tab_logical_slot (a int);
144+
INSERT INTO tab_logical_slot VALUES (generate_series(1,10));");
145+
my$current_lsn =$node_master->safe_psql('postgres',
146+
"SELECT pg_current_wal_lsn();");
147+
chomp($current_lsn);
148+
my$psql_rc =$node_master->psql('postgres',
149+
"SELECT pg_replication_slot_advance('$logical_slot', '$current_lsn'::pg_lsn);");
150+
is($psql_rc,'0','slot advancing with logical slot');
151+
my$logical_restart_lsn_pre =$node_master->safe_psql('postgres',
152+
"SELECT restart_lsn from pg_replication_slots WHERE slot_name = '$logical_slot';");
153+
chomp($logical_restart_lsn_pre);
154+
# Slot advance should persists across clean restarts.
155+
$node_master->restart;
156+
my$logical_restart_lsn_post =$node_master->safe_psql('postgres',
157+
"SELECT restart_lsn from pg_replication_slots WHERE slot_name = '$logical_slot';");
158+
chomp($logical_restart_lsn_post);
159+
ok(($logical_restart_lsn_precmp$logical_restart_lsn_post) == 0,
160+
"logical slot advance persists across restarts");
161+
138162
# done with the node
139163
$node_master->stop;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp