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

Commitd851bef

Browse files
Dirty replication slots when using sql interface
When pg_logical_slot_get_changes(...) sets confirmed_flush_lsn to the point atwhich replay stopped, it doesn't dirty the replication slot. So if the replaydidn't cause restart_lsn or catalog_xmin to change as well, this change willnot get written out to disk. Even on a clean shutdown.If Pg crashes or restarts, a subsequent pg_logical_slot_get_changes(...) callwill see the same changes already replayed since it uses the slot'sconfirmed_flush_lsn as the start point for fetching changes. The caller can'tspecify a start LSN when using the SQL interface.Mark the slot as dirty after reading changes using the SQL interface so thatusers won't see repeated changes after a clean shutdown. Repeated changes stilloccur when using the walsender interface or after an unclean shutdown.Craig Ringer
1 parentb618208 commitd851bef

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

‎src/backend/replication/logical/logicalfuncs.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,22 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin
321321
* business..)
322322
*/
323323
if (ctx->reader->EndRecPtr!=InvalidXLogRecPtr&&confirm)
324+
{
324325
LogicalConfirmReceivedLocation(ctx->reader->EndRecPtr);
326+
/*
327+
* If only the confirmed_flush_lsn has changed the slot won't get
328+
* marked as dirty by the above. Callers on the walsender interface
329+
* are expected to keep track of their own progress and don't need
330+
* it written out. But SQL-interface users cannot specify their own
331+
* start positions and it's harder for them to keep track of their
332+
* progress, so we should make more of an effort to save it for them.
333+
*
334+
* Dirty the slot so it's written out at the next checkpoint. We'll
335+
* still lose its position on crash, as documented, but it's better
336+
* than always losing the position even on clean restart.
337+
*/
338+
ReplicationSlotMarkDirty();
339+
}
325340

326341
/* free context, call shutdown callback */
327342
FreeDecodingContext(ctx);

‎src/test/recovery/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,5 @@ check:
1818

1919
cleandistcleanmaintainer-clean:
2020
rm -rf tmp_check
21+
22+
EXTRA_INSTALL = contrib/test_decoding
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Testing of logical decoding using SQL interface and/or pg_recvlogical
2+
use strict;
3+
use warnings;
4+
use PostgresNode;
5+
use TestLib;
6+
use Test::Moretests=> 2;
7+
8+
# Initialize master node
9+
my$node_master = get_new_node('master');
10+
$node_master->init(allows_streaming=> 1);
11+
$node_master->append_conf(
12+
'postgresql.conf',qq(
13+
max_replication_slots = 4
14+
wal_level = logical
15+
));
16+
$node_master->start;
17+
my$backup_name ='master_backup';
18+
19+
$node_master->safe_psql('postgres',qq[CREATE TABLE decoding_test(x integer, y text);]);
20+
21+
$node_master->safe_psql('postgres',qq[SELECT pg_create_logical_replication_slot('test_slot', 'test_decoding');]);
22+
23+
$node_master->safe_psql('postgres',qq[INSERT INTO decoding_test(x,y) SELECT s, s::text FROM generate_series(1,10) s;]);
24+
25+
# Basic decoding works
26+
my($result) =$node_master->safe_psql('postgres',qq[SELECT pg_logical_slot_get_changes('test_slot', NULL, NULL);]);
27+
is(scalar(split /^/m,$result), 12,'Decoding produced 12 rows inc BEGIN/COMMIT');
28+
29+
# If we immediately crash the server we might lose the progress we just made
30+
# and replay the same changes again. But a clean shutdown should never repeat
31+
# the same changes when we use the SQL decoding interface.
32+
$node_master->restart('fast');
33+
34+
# There are no new writes, so the result should be empty.
35+
$result =$node_master->safe_psql('postgres',qq[SELECT pg_logical_slot_get_changes('test_slot', NULL, NULL);]);
36+
chomp($result);
37+
is($result,'','Decoding after fast restart repeats no rows');
38+
39+
# done with the node
40+
$node_master->stop;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp