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

Commit6d9fa52

Browse files
committed
pg_receivewal: Add --endpos option
This is primarily useful for making tests of this utility moredeterministic, to avoid the complexity of starting pg_receivewal as adeamon in TAP tests.While this is less useful than the equivalent pg_recvlogical option,users can as well use it for example to enforce WAL streaming up to aend-of-backup position, to save only a minimal amount of WAL.Use this new option to stream WAL data in a deterministic way within anew set of TAP tests.Author: Michael Paquier <michael.paquier@gmail.com>
1 parentc1898c3 commit6d9fa52

File tree

3 files changed

+91
-8
lines changed

3 files changed

+91
-8
lines changed

‎doc/src/sgml/ref/pg_receivewal.sgml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,22 @@ PostgreSQL documentation
9898
</listitem>
9999
</varlistentry>
100100

101+
<varlistentry>
102+
<term><option>-E <replaceable>lsn</replaceable></option></term>
103+
<term><option>--endpos=<replaceable>lsn</replaceable></option></term>
104+
<listitem>
105+
<para>
106+
Automatically stop replication and exit with normal exit status 0 when
107+
receiving reaches the specified LSN.
108+
</para>
109+
110+
<para>
111+
If there is a record with LSN exactly equal to <replaceable>lsn</>,
112+
the record will be processed.
113+
</para>
114+
</listitem>
115+
</varlistentry>
116+
101117
<varlistentry>
102118
<term><option>--if-not-exists</option></term>
103119
<listitem>

‎src/bin/pg_basebackup/pg_receivewal.c

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,13 @@ static intverbose = 0;
3636
staticintcompresslevel=0;
3737
staticintnoloop=0;
3838
staticintstandby_message_timeout=10*1000;/* 10 sec = default */
39-
staticvolatilebooltime_to_abort= false;
39+
staticvolatilebooltime_to_stop= false;
4040
staticbooldo_create_slot= false;
4141
staticboolslot_exists_ok= false;
4242
staticbooldo_drop_slot= false;
4343
staticboolsynchronous= false;
4444
staticchar*replication_slot=NULL;
45+
staticXLogRecPtrendpos=InvalidXLogRecPtr;
4546

4647

4748
staticvoidusage(void);
@@ -77,6 +78,7 @@ usage(void)
7778
printf(_(" %s [OPTION]...\n"),progname);
7879
printf(_("\nOptions:\n"));
7980
printf(_(" -D, --directory=DIR receive write-ahead log files into this directory\n"));
81+
printf(_(" -E, --endpos=LSN exit after receiving the specified LSN\n"));
8082
printf(_(" --if-not-exists do not error if slot already exists when creating a slot\n"));
8183
printf(_(" -n, --no-loop do not loop on connection lost\n"));
8284
printf(_(" -s, --status-interval=SECS\n"
@@ -112,6 +114,16 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished)
112114
progname, (uint32) (xlogpos >>32), (uint32)xlogpos,
113115
timeline);
114116

117+
if (!XLogRecPtrIsInvalid(endpos)&&endpos<xlogpos)
118+
{
119+
if (verbose)
120+
fprintf(stderr,_("%s: stopped streaming at %X/%X (timeline %u)\n"),
121+
progname, (uint32) (xlogpos >>32), (uint32)xlogpos,
122+
timeline);
123+
time_to_stop= true;
124+
return true;
125+
}
126+
115127
/*
116128
* Note that we report the previous, not current, position here. After a
117129
* timeline switch, xlogpos points to the beginning of the segment because
@@ -128,7 +140,7 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished)
128140
prevtimeline=timeline;
129141
prevpos=xlogpos;
130142

131-
if (time_to_abort)
143+
if (time_to_stop)
132144
{
133145
if (verbose)
134146
fprintf(stderr,_("%s: received interrupt signal, exiting\n"),
@@ -448,7 +460,7 @@ StreamLog(void)
448460
staticvoid
449461
sigint_handler(intsignum)
450462
{
451-
time_to_abort= true;
463+
time_to_stop= true;
452464
}
453465
#endif
454466

@@ -460,6 +472,7 @@ main(int argc, char **argv)
460472
{"version",no_argument,NULL,'V'},
461473
{"directory",required_argument,NULL,'D'},
462474
{"dbname",required_argument,NULL,'d'},
475+
{"endpos",required_argument,NULL,'E'},
463476
{"host",required_argument,NULL,'h'},
464477
{"port",required_argument,NULL,'p'},
465478
{"username",required_argument,NULL,'U'},
@@ -481,6 +494,7 @@ main(int argc, char **argv)
481494
intc;
482495
intoption_index;
483496
char*db_name;
497+
uint32hi,lo;
484498

485499
progname=get_progname(argv[0]);
486500
set_pglocale_pgservice(argv[0],PG_TEXTDOMAIN("pg_basebackup"));
@@ -500,7 +514,7 @@ main(int argc, char **argv)
500514
}
501515
}
502516

503-
while ((c=getopt_long(argc,argv,"D:d:h:p:U:s:S:nwWvZ:",
517+
while ((c=getopt_long(argc,argv,"D:d:E:h:p:U:s:S:nwWvZ:",
504518
long_options,&option_index))!=-1)
505519
{
506520
switch (c)
@@ -544,6 +558,16 @@ main(int argc, char **argv)
544558
case'S':
545559
replication_slot=pg_strdup(optarg);
546560
break;
561+
case'E':
562+
if (sscanf(optarg,"%X/%X",&hi,&lo)!=2)
563+
{
564+
fprintf(stderr,
565+
_("%s: could not parse end position \"%s\"\n"),
566+
progname,optarg);
567+
exit(1);
568+
}
569+
endpos= ((uint64)hi) <<32 |lo;
570+
break;
547571
case'n':
548572
noloop=1;
549573
break;
@@ -714,11 +738,11 @@ main(int argc, char **argv)
714738
while (true)
715739
{
716740
StreamLog();
717-
if (time_to_abort)
741+
if (time_to_stop)
718742
{
719743
/*
720-
* We've been Ctrl-C'ed. That's not an error, so exit without an
721-
*errorcode.
744+
* We've been Ctrl-C'ed or end of streaming position has been
745+
*willingly reached, so exit without an error code.
722746
*/
723747
exit(0);
724748
}
Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,51 @@
11
use strict;
22
use warnings;
33
use TestLib;
4-
use Test::Moretests=> 8;
4+
use PostgresNode;
5+
use Test::Moretests=> 14;
56

67
program_help_ok('pg_receivewal');
78
program_version_ok('pg_receivewal');
89
program_options_handling_ok('pg_receivewal');
10+
11+
my$primary = get_new_node('primary');
12+
$primary->init(allows_streaming=> 1);
13+
$primary->start;
14+
15+
my$stream_dir =$primary->basedir .'/archive_wal';
16+
mkdir($stream_dir);
17+
18+
# Sanity checks for command line options.
19+
$primary->command_fails(['pg_receivewal'],
20+
'pg_receivewal needs target directory specified');
21+
$primary->command_fails(
22+
['pg_receivewal','-D',$stream_dir,'--create-slot','--drop-slot' ],
23+
'failure if both --create-slot and --drop-slot specified');
24+
$primary->command_fails(
25+
['pg_receivewal','-D',$stream_dir,'--create-slot' ],
26+
'failure if --create-slot specified without --slot');
27+
28+
# Slot creation and drop
29+
my$slot_name ='test';
30+
$primary->command_ok(
31+
['pg_receivewal','--slot',$slot_name,'--create-slot' ],
32+
'creating a replication slot');
33+
$primary->command_ok(['pg_receivewal','--slot',$slot_name,'--drop-slot' ],
34+
'dropping a replication slot');
35+
36+
# Generate some WAL. Use --synchronous at the same time to add more
37+
# code coverage. Switch to the next segment first so that subsequent
38+
# restarts of pg_receivewal will see this segment as full..
39+
$primary->psql('postgres','CREATE TABLE test_table(x integer);');
40+
$primary->psql('postgres','SELECT pg_switch_wal();');
41+
my$nextlsn =
42+
$primary->safe_psql('postgres','SELECT pg_current_wal_insert_lsn();');
43+
chomp($nextlsn);
44+
$primary->psql('postgres',
45+
'INSERT INTO test_table VALUES (generate_series(1,100));');
46+
47+
# Stream up to the given position.
48+
$primary->command_ok(
49+
['pg_receivewal','-D',$stream_dir,'--verbose',
50+
'--endpos',$nextlsn,'--synchronous','--no-loop' ],
51+
'streaming some WAL with --synchronous');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp