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

Commit8a695d7

Browse files
author
Amit Kapila
committed
Add a test for commitac0e331 using the injection point.
This test uses an injection point to bypass the time overhead caused bythe idle_replication_slot_timeout GUC, which has a minimum value of oneminute.Author: Hayato Kuroda <kuroda.hayato@fujitsu.com>Author: Nisha Moond <nisha.moond412@gmail.com>Reviewed-by: Peter Smith <smithpb2250@gmail.com>Reviewed-by: Vignesh C <vignesh21@gmail.com>Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>Discussion:https://postgr.es/m/CALj2ACW4aUe-_uFQOjdWCEN-xXoLGhmvRFnL8SNw_TZ5nJe+aw@mail.gmail.com
1 parent302cf15 commit8a695d7

File tree

3 files changed

+131
-9
lines changed

3 files changed

+131
-9
lines changed

‎src/backend/replication/slot.c

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include"storage/procarray.h"
5757
#include"utils/builtins.h"
5858
#include"utils/guc_hooks.h"
59+
#include"utils/injection_point.h"
5960
#include"utils/varlena.h"
6061

6162
/*
@@ -1669,16 +1670,31 @@ DetermineSlotInvalidationCause(uint32 possible_causes, ReplicationSlot *s,
16691670
{
16701671
Assert(now>0);
16711672

1672-
/*
1673-
* Check if the slot needs to be invalidated due to
1674-
* idle_replication_slot_timeout GUC.
1675-
*/
1676-
if (CanInvalidateIdleSlot(s)&&
1677-
TimestampDifferenceExceedsSeconds(s->inactive_since,now,
1678-
idle_replication_slot_timeout_mins*SECS_PER_MINUTE))
1673+
if (CanInvalidateIdleSlot(s))
16791674
{
1680-
*inactive_since=s->inactive_since;
1681-
returnRS_INVAL_IDLE_TIMEOUT;
1675+
/*
1676+
* We simulate the invalidation due to idle_timeout as the minimum
1677+
* time idle time is one minute which makes tests take a long
1678+
* time.
1679+
*/
1680+
#ifdefUSE_INJECTION_POINTS
1681+
if (IS_INJECTION_POINT_ATTACHED("slot-timeout-inval"))
1682+
{
1683+
*inactive_since=0;/* since the beginning of time */
1684+
returnRS_INVAL_IDLE_TIMEOUT;
1685+
}
1686+
#endif
1687+
1688+
/*
1689+
* Check if the slot needs to be invalidated due to
1690+
* idle_replication_slot_timeout GUC.
1691+
*/
1692+
if (TimestampDifferenceExceedsSeconds(s->inactive_since,now,
1693+
idle_replication_slot_timeout_mins*SECS_PER_MINUTE))
1694+
{
1695+
*inactive_since=s->inactive_since;
1696+
returnRS_INVAL_IDLE_TIMEOUT;
1697+
}
16821698
}
16831699
}
16841700

‎src/test/recovery/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ tests += {
5252
't/041_checkpoint_at_promote.pl',
5353
't/042_low_level_backup.pl',
5454
't/043_no_contrecord_switch.pl',
55+
't/044_invalidate_inactive_slots.pl',
5556
],
5657
},
5758
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Copyright (c) 2025, PostgreSQL Global Development Group
2+
3+
# Test for replication slots invalidation due to idle_timeout
4+
use strict;
5+
use warningsFATAL=>'all';
6+
7+
use PostgreSQL::Test::Utils;
8+
use PostgreSQL::Test::Cluster;
9+
use Test::More;
10+
11+
# This test depends on injection point that forces slot invalidation
12+
# due to idle_timeout.
13+
# https://www.postgresql.org/docs/current/xfunc-c.html#XFUNC-ADDIN-INJECTION-POINTS
14+
if ($ENV{enable_injection_points}ne'yes')
15+
{
16+
planskip_all=>'Injection points not supported by this build';
17+
}
18+
19+
# Wait for slot to first become idle and then get invalidated
20+
subwait_for_slot_invalidation
21+
{
22+
my ($node,$slot_name,$offset) =@_;
23+
my$node_name =$node->name;
24+
25+
# The slot's invalidation should be logged
26+
$node->wait_for_log(
27+
qr/invalidating obsolete replication slot\"$slot_name\"/,$offset);
28+
29+
# Check that the invalidation reason is 'idle_timeout'
30+
$node->poll_query_until(
31+
'postgres',qq[
32+
SELECT COUNT(slot_name) = 1 FROM pg_replication_slots
33+
WHERE slot_name = '$slot_name' AND
34+
invalidation_reason = 'idle_timeout';
35+
])
36+
ordie
37+
"Timed out while waiting for invalidation reason of slot$slot_name to be set on node$node_name";
38+
}
39+
40+
# ========================================================================
41+
# Testcase start
42+
#
43+
# Test invalidation of physical replication slot and logical replication slot
44+
# due to idle timeout.
45+
46+
# Initialize the node
47+
my$node = PostgreSQL::Test::Cluster->new('node');
48+
$node->init(allows_streaming=>'logical');
49+
50+
# Avoid unpredictability
51+
$node->append_conf(
52+
'postgresql.conf',qq{
53+
checkpoint_timeout = 1h
54+
idle_replication_slot_timeout = 1min
55+
});
56+
$node->start;
57+
58+
# Check if the 'injection_points' extension is available, as it may be
59+
# possible that this script is run with installcheck, where the module
60+
# would not be installed by default.
61+
if (!$node->check_extension('injection_points'))
62+
{
63+
planskip_all=>'Extension injection_points not installed';
64+
}
65+
66+
# Create both physical and logical replication slots
67+
$node->safe_psql(
68+
'postgres',qq[
69+
SELECT pg_create_physical_replication_slot(slot_name := 'physical_slot', immediately_reserve := true);
70+
SELECT pg_create_logical_replication_slot('logical_slot', 'test_decoding');
71+
]);
72+
73+
my$log_offset =-s$node->logfile;
74+
75+
# Register an injection point on the node to forcibly cause a slot
76+
# invalidation due to idle_timeout
77+
$node->safe_psql('postgres','CREATE EXTENSION injection_points;');
78+
79+
$node->safe_psql('postgres',
80+
"SELECT injection_points_attach('slot-timeout-inval', 'error');");
81+
82+
# Slot invalidation occurs during a checkpoint, so perform a checkpoint to
83+
# invalidate the slots.
84+
$node->safe_psql('postgres',"CHECKPOINT");
85+
86+
# Wait for slots to become inactive. Since nobody has acquired the slot yet,
87+
# it can only be due to the idle timeout mechanism.
88+
wait_for_slot_invalidation($node,'physical_slot',$log_offset);
89+
wait_for_slot_invalidation($node,'logical_slot',$log_offset);
90+
91+
# Check that the invalidated slot cannot be acquired
92+
my ($result,$stdout,$stderr);
93+
($result,$stdout,$stderr) =$node->psql(
94+
'postgres',qq[
95+
SELECT pg_replication_slot_advance('logical_slot', '0/1');
96+
]);
97+
ok($stderr =~/can no longer access replication slot "logical_slot"/,
98+
"detected error upon trying to acquire invalidated slot on node")
99+
ordie
100+
"could not detect error upon trying to acquire invalidated slot\"logical_slot\" on node";
101+
102+
# Testcase end
103+
# =============================================================================
104+
105+
done_testing();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp