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

Commit 1816a1c

Browse files
committed
Fix checkpoint signalling
Checkpointer uses its MyLatch to wake up when a checkpoint request is received. But before commit c655077 the latch was not used for anything else, so the code could just go to sleep after each loop without rechecking the sleeping condition. That commit added a separate ResetLatch in its code path[1], which can cause a checkpoint to go unnoticed for potentially a long time. Fix by skipping sleep if any checkpoint flags are set. Also add a test to verify this; authored by Kyotaro Horiguchi. [1] CreateCheckPoint -> InvalidateObsoleteReplicationSlots -> ConditionVariableTimeSleep Report and diagnosis by Kyotaro Horiguchi. Co-authored-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Co-authored-by: Álvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://postgr.es/m/20200408.141956.891237856186513376.horikyota.ntt@gmail.com
1 parent fef819a commit 1816a1c

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

src/backend/postmaster/checkpointer.c

+7
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,13 @@ CheckpointerMain(void)
494494
*/
495495
pgstat_send_bgwriter();
496496

497+
/*
498+
* If any checkpoint flags have been set, redo the loop to handle the
499+
* checkpoint without sleeping.
500+
*/
501+
if (((volatile CheckpointerShmemStruct *) CheckpointerShmem)->ckpt_flags)
502+
continue;
503+
497504
/*
498505
* Sleep until we are signaled or it's time for another checkpoint or
499506
* xlog file switch.

src/test/recovery/t/019_replslot_limit.pl

+42-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use PostgresNode;
99

1010
use File::Path qw(rmtree);
11-
use Test::More tests => 13;
11+
use Test::More tests => 14;
1212
use Time::HiRes qw(usleep);
1313

1414
$ENV{PGDATABASE} = 'postgres';
@@ -179,7 +179,47 @@
179179
}
180180
ok($failed, 'check that replication has been broken');
181181

182-
$node_standby->stop;
182+
$node_master->stop('immediate');
183+
$node_standby->stop('immediate');
184+
185+
my $node_master2 = get_new_node('master2');
186+
$node_master2->init(allows_streaming => 1);
187+
$node_master2->append_conf(
188+
'postgresql.conf', qq(
189+
min_wal_size = 32MB
190+
max_wal_size = 32MB
191+
log_checkpoints = yes
192+
));
193+
$node_master2->start;
194+
$node_master2->safe_psql('postgres',
195+
"SELECT pg_create_physical_replication_slot('rep1')");
196+
$backup_name = 'my_backup2';
197+
$node_master2->backup($backup_name);
198+
199+
$node_master2->stop;
200+
$node_master2->append_conf(
201+
'postgresql.conf', qq(
202+
max_slot_wal_keep_size = 0
203+
));
204+
$node_master2->start;
205+
206+
$node_standby = get_new_node('standby_2');
207+
$node_standby->init_from_backup($node_master2, $backup_name,
208+
has_streaming => 1);
209+
$node_standby->append_conf('postgresql.conf', "primary_slot_name = 'rep1'");
210+
$node_standby->start;
211+
my @result =
212+
split(
213+
'\n',
214+
$node_master2->safe_psql(
215+
'postgres',
216+
"CREATE TABLE tt();
217+
DROP TABLE tt;
218+
SELECT pg_switch_wal();
219+
CHECKPOINT;
220+
SELECT 'finished';",
221+
timeout => '60'));
222+
is($result[1], 'finished', 'check if checkpoint command is not blocked');
183223

184224
#####################################
185225
# Advance WAL of $node by $n segments

0 commit comments

Comments
 (0)