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

Commiteb2a613

Browse files
Add a pg_recvlogical wrapper to PostgresNode
Allows testing of logical decoding using SQL interface and/or pg_recvlogicalMost logical decoding tests are in contrib/test_decoding. This moduleis for work that doesn't fit well there, like where server restartsare required.Craig Ringer
1 parentd3cc37f commiteb2a613

File tree

2 files changed

+108
-1
lines changed

2 files changed

+108
-1
lines changed

‎src/test/perl/PostgresNode.pm

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,6 +1505,84 @@ sub slot
15051505

15061506
=pod
15071507
1508+
=item$node->pg_recvlogical_upto(self, dbname, slot_name, endpos, timeout_secs, ...)
1509+
1510+
Invoke pg_recvlogical to read from slot_name on dbname until LSN endpos, which
1511+
corresponds to pg_recvlogical --endpos. Gives up after timeout (if nonzero).
1512+
1513+
Disallows pg_recvlogical from internally retrying on error by passing --no-loop.
1514+
1515+
Plugin options are passed as additional keyword arguments.
1516+
1517+
If called in scalar context, returns stdout, and die()s on timeout or nonzero return.
1518+
1519+
If called in array context, returns a tuple of (retval, stdout, stderr, timeout).
1520+
timeout is the IPC::Run::Timeout object whose is_expired method can be tested
1521+
to check for timeout. retval is undef on timeout.
1522+
1523+
=cut
1524+
1525+
subpg_recvlogical_upto
1526+
{
1527+
my ($self,$dbname,$slot_name,$endpos,$timeout_secs,%plugin_options) =@_;
1528+
my ($stdout,$stderr);
1529+
1530+
my$timeout_exception ='pg_recvlogical timed out';
1531+
1532+
die'slot name must be specified'unlessdefined($slot_name);
1533+
die'endpos must be specified'unlessdefined($endpos);
1534+
1535+
my@cmd = ('pg_recvlogical','-S',$slot_name,'--dbname',$self->connstr($dbname));
1536+
push@cmd,'--endpos',$endpos;
1537+
push@cmd,'-f','-','--no-loop','--start';
1538+
1539+
while (my ($k,$v) =each%plugin_options)
1540+
{
1541+
die"= is not permitted to appear in replication option name"if ($k =~qr/=/);
1542+
push@cmd,"-o","$k=$v";
1543+
}
1544+
1545+
my$timeout;
1546+
$timeout = IPC::Run::timeout($timeout_secs,exception=>$timeout_exception )if$timeout_secs;
1547+
my$ret = 0;
1548+
1549+
do {
1550+
local$@;
1551+
eval {
1552+
IPC::Run::run(\@cmd,">", \$stdout,"2>", \$stderr,$timeout);
1553+
$ret =$?;
1554+
};
1555+
my$exc_save =$@;
1556+
if ($exc_save)
1557+
{
1558+
# IPC::Run::run threw an exception. re-throw unless it's a
1559+
# timeout, which we'll handle by testing is_expired
1560+
die$exc_save
1561+
if (blessed($exc_save) ||$exc_save !~qr/$timeout_exception/);
1562+
1563+
$ret =undef;
1564+
1565+
die"Got timeout exception '$exc_save' but timer not expired?!"
1566+
unless$timeout->is_expired;
1567+
1568+
die"$exc_save waiting for endpos$endpos with stdout '$stdout', stderr '$stderr'"
1569+
unlesswantarray;
1570+
}
1571+
};
1572+
1573+
if (wantarray)
1574+
{
1575+
return ($ret,$stdout,$stderr,$timeout);
1576+
}
1577+
else
1578+
{
1579+
die"pg_recvlogical exited with code '$ret', stdout '$stdout' and stderr '$stderr'"if$ret;
1580+
return$stdout;
1581+
}
1582+
}
1583+
1584+
=pod
1585+
15081586
=back
15091587
15101588
=cut

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

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
# Testing of logical decoding using SQL interface and/or pg_recvlogical
2+
#
3+
# Most logical decoding tests are in contrib/test_decoding. This module
4+
# is for work that doesn't fit well there, like where server restarts
5+
# are required.
26
use strict;
37
use warnings;
48
use PostgresNode;
59
use TestLib;
6-
use Test::Moretests=>2;
10+
use Test::Moretests=>5;
711

812
# Initialize master node
913
my$node_master = get_new_node('master');
@@ -35,5 +39,30 @@
3539
chomp($result);
3640
is($result,'','Decoding after fast restart repeats no rows');
3741

42+
# Insert some rows and verify that we get the same results from pg_recvlogical
43+
# and the SQL interface.
44+
$node_master->safe_psql('postgres',qq[INSERT INTO decoding_test(x,y) SELECT s, s::text FROM generate_series(1,4) s;]);
45+
46+
my$expected =q{BEGIN
47+
table public.decoding_test: INSERT: x[integer]:1 y[text]:'1'
48+
table public.decoding_test: INSERT: x[integer]:2 y[text]:'2'
49+
table public.decoding_test: INSERT: x[integer]:3 y[text]:'3'
50+
table public.decoding_test: INSERT: x[integer]:4 y[text]:'4'
51+
COMMIT};
52+
53+
my$stdout_sql =$node_master->safe_psql('postgres',qq[SELECT data FROM pg_logical_slot_peek_changes('test_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');]);
54+
is($stdout_sql,$expected,'got expected output from SQL decoding session');
55+
56+
my$endpos =$node_master->safe_psql('postgres',"SELECT location FROM pg_logical_slot_peek_changes('test_slot', NULL, NULL) ORDER BY location DESC LIMIT 1;");
57+
diag"waiting to replay$endpos";
58+
59+
my$stdout_recv =$node_master->pg_recvlogical_upto('postgres','test_slot',$endpos, 10,'include-xids'=>'0','skip-empty-xacts'=>'1');
60+
chomp($stdout_recv);
61+
is($stdout_recv,$expected,'got same expected output from pg_recvlogical decoding session');
62+
63+
$stdout_recv =$node_master->pg_recvlogical_upto('postgres','test_slot',$endpos, 10,'include-xids'=>'0','skip-empty-xacts'=>'1');
64+
chomp($stdout_recv);
65+
is($stdout_recv,'','pg_recvlogical acknowledged changes, nothing pending on slot');
66+
3867
# done with the node
3968
$node_master->stop;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp