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

Commitd9f38c7

Browse files
committed
Add support for managing physical replication slots to pg_receivexlog.
pg_receivexlog already has the capability to use a replication slot toreserve WAL on the upstream node. But the used slot currently has tobe created via SQL.To allow using slots directly, without involving SQL, add--create-slot and --drop-slot actions, analogous to the logical slotmanipulation support in pg_recvlogical.Author: Michael PaquierDiscussion: CABUevEx+zrOHZOQg+dPapNPFRJdsk59b=TSVf30Z71GnFXhQaw@mail.gmail.com
1 parentc8b6cba commitd9f38c7

File tree

2 files changed

+170
-16
lines changed

2 files changed

+170
-16
lines changed

‎doc/src/sgml/ref/pg_receivexlog.sgml

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,13 +255,42 @@ PostgreSQL documentation
255255
to make sure that <application>pg_receivexlog</> cannot become the
256256
synchronous standby through an incautious setting of
257257
<xref linkend="guc-synchronous-standby-names">; it does not flush
258-
data frequently enough for this to work correctly.
258+
data frequently enough for this to work correctly. In
259+
<option>--create-slot</option> mode, create the slot with this name.
260+
In <option>--drop-slot</option> mode, delete the slot with this name.
259261
</para>
260262
</listitem>
261263
</varlistentry>
262264
</variablelist>
263265
</para>
264266

267+
<para>
268+
<application>pg_receivexlog</application> can perform one of the two
269+
following actions in order to control physical replication slots:
270+
271+
<variablelist>
272+
<varlistentry>
273+
<term><option>--create-slot</option></term>
274+
<listitem>
275+
<para>
276+
Create a new physical replication slot with the name specified in
277+
<option>--slot</option>, then start to stream WAL.
278+
</para>
279+
</listitem>
280+
</varlistentry>
281+
282+
<varlistentry>
283+
<term><option>--drop-slot</option></term>
284+
<listitem>
285+
<para>
286+
Drop the replication slot with the name specified in
287+
<option>--slot</option>, then exit.
288+
</para>
289+
</listitem>
290+
</varlistentry>
291+
</variablelist>
292+
</para>
293+
265294
<para>
266295
Other options are also available:
267296

‎src/bin/pg_basebackup/pg_receivexlog.c

Lines changed: 140 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,15 @@ static intnoloop = 0;
3838
staticintstandby_message_timeout=10*1000;/* 10 sec = default */
3939
staticintfsync_interval=0;/* 0 = default */
4040
staticvolatilebooltime_to_abort= false;
41+
staticbooldo_create_slot= false;
42+
staticbooldo_drop_slot= false;
4143

4244

4345
staticvoidusage(void);
46+
staticDIR*get_destination_dir(char*dest_folder);
47+
staticvoidclose_destination_dir(DIR*dest_dir,char*dest_folder);
4448
staticXLogRecPtrFindStreamingStart(uint32*tli);
45-
staticvoidStreamLog();
49+
staticvoidStreamLog(void);
4650
staticboolstop_streaming(XLogRecPtrsegendpos,uint32timeline,
4751
boolsegment_finished);
4852

@@ -78,6 +82,9 @@ usage(void)
7882
printf(_(" -w, --no-password never prompt for password\n"));
7983
printf(_(" -W, --password force password prompt (should happen automatically)\n"));
8084
printf(_(" -S, --slot=SLOTNAME replication slot to use\n"));
85+
printf(_("\nOptional actions:\n"));
86+
printf(_(" --create-slot create a new replication slot (for the slot's name see --slot)\n"));
87+
printf(_(" --drop-slot drop the replication slot (for the slot's name see --slot)\n"));
8188
printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
8289
}
8390

@@ -118,6 +125,44 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished)
118125
return false;
119126
}
120127

128+
129+
/*
130+
* Get destination directory.
131+
*/
132+
staticDIR*
133+
get_destination_dir(char*dest_folder)
134+
{
135+
DIR*dir;
136+
137+
Assert(dest_folder!=NULL);
138+
dir=opendir(dest_folder);
139+
if (dir==NULL)
140+
{
141+
fprintf(stderr,_("%s: could not open directory \"%s\": %s\n"),
142+
progname,basedir,strerror(errno));
143+
disconnect_and_exit(1);
144+
}
145+
146+
returndir;
147+
}
148+
149+
150+
/*
151+
* Close existing directory.
152+
*/
153+
staticvoid
154+
close_destination_dir(DIR*dest_dir,char*dest_folder)
155+
{
156+
Assert(dest_dir!=NULL&&dest_folder!=NULL);
157+
if (closedir(dest_dir))
158+
{
159+
fprintf(stderr,_("%s: could not close directory \"%s\": %s\n"),
160+
progname,dest_folder,strerror(errno));
161+
disconnect_and_exit(1);
162+
}
163+
}
164+
165+
121166
/*
122167
* Determine starting location for streaming, based on any existing xlog
123168
* segments in the directory. We start at the end of the last one that is
@@ -134,13 +179,7 @@ FindStreamingStart(uint32 *tli)
134179
uint32high_tli=0;
135180
boolhigh_ispartial= false;
136181

137-
dir=opendir(basedir);
138-
if (dir==NULL)
139-
{
140-
fprintf(stderr,_("%s: could not open directory \"%s\": %s\n"),
141-
progname,basedir,strerror(errno));
142-
disconnect_and_exit(1);
143-
}
182+
dir=get_destination_dir(basedir);
144183

145184
while (errno=0, (dirent=readdir(dir))!=NULL)
146185
{
@@ -219,12 +258,7 @@ FindStreamingStart(uint32 *tli)
219258
disconnect_and_exit(1);
220259
}
221260

222-
if (closedir(dir))
223-
{
224-
fprintf(stderr,_("%s: could not close directory \"%s\": %s\n"),
225-
progname,basedir,strerror(errno));
226-
disconnect_and_exit(1);
227-
}
261+
close_destination_dir(dir,basedir);
228262

229263
if (high_segno>0)
230264
{
@@ -344,11 +378,15 @@ main(int argc, char **argv)
344378
{"status-interval",required_argument,NULL,'s'},
345379
{"slot",required_argument,NULL,'S'},
346380
{"verbose",no_argument,NULL,'v'},
381+
/* action */
382+
{"create-slot",no_argument,NULL,1},
383+
{"drop-slot",no_argument,NULL,2},
347384
{NULL,0,NULL,0}
348385
};
349386

350387
intc;
351388
intoption_index;
389+
char*db_name;
352390

353391
progname=get_progname(argv[0]);
354392
set_pglocale_pgservice(argv[0],PG_TEXTDOMAIN("pg_receivexlog"));
@@ -427,6 +465,13 @@ main(int argc, char **argv)
427465
case'v':
428466
verbose++;
429467
break;
468+
/* action */
469+
case1:
470+
do_create_slot= true;
471+
break;
472+
case2:
473+
do_drop_slot= true;
474+
break;
430475
default:
431476

432477
/*
@@ -451,21 +496,101 @@ main(int argc, char **argv)
451496
exit(1);
452497
}
453498

499+
if (replication_slot==NULL&& (do_drop_slot||do_create_slot))
500+
{
501+
fprintf(stderr,_("%s: --create-slot and --drop-slot need a slot to be specified using --slot\n"),progname);
502+
fprintf(stderr,_("Try \"%s --help\" for more information.\n"),
503+
progname);
504+
exit(1);
505+
}
506+
507+
if (do_drop_slot&&do_create_slot)
508+
{
509+
fprintf(stderr,_("%s: cannot use --create-slot together with --drop-slot\n"),progname);
510+
fprintf(stderr,_("Try \"%s --help\" for more information.\n"),
511+
progname);
512+
exit(1);
513+
}
514+
454515
/*
455516
* Required arguments
456517
*/
457-
if (basedir==NULL)
518+
if (basedir==NULL&& !do_drop_slot)
458519
{
459520
fprintf(stderr,_("%s: no target directory specified\n"),progname);
460521
fprintf(stderr,_("Try \"%s --help\" for more information.\n"),
461522
progname);
462523
exit(1);
463524
}
464525

526+
/*
527+
* Check existence of destination folder.
528+
*/
529+
if (!do_drop_slot)
530+
{
531+
DIR*dir=get_destination_dir(basedir);
532+
close_destination_dir(dir,basedir);
533+
}
534+
465535
#ifndefWIN32
466536
pqsignal(SIGINT,sigint_handler);
467537
#endif
468538

539+
/*
540+
* Obtain a connection before doing anything.
541+
*/
542+
conn=GetConnection();
543+
if (!conn)
544+
/* error message already written in GetConnection() */
545+
exit(1);
546+
547+
/*
548+
* Run IDENTIFY_SYSTEM to make sure we've successfully have established a
549+
* replication connection and haven't connected using a database specific
550+
* connection.
551+
*/
552+
if (!RunIdentifySystem(conn,NULL,NULL,NULL,&db_name))
553+
disconnect_and_exit(1);
554+
555+
/*
556+
* Check that there is a database associated with connection, none
557+
* should be defined in this context.
558+
*/
559+
if (db_name)
560+
{
561+
fprintf(stderr,
562+
_("%s: replication connection using slot \"%s\" is unexpectedly database specific\n"),
563+
progname,replication_slot);
564+
disconnect_and_exit(1);
565+
}
566+
567+
/*
568+
* Drop a replication slot.
569+
*/
570+
if (do_drop_slot)
571+
{
572+
if (verbose)
573+
fprintf(stderr,
574+
_("%s: dropping replication slot \"%s\"\n"),
575+
progname,replication_slot);
576+
577+
if (!DropReplicationSlot(conn,replication_slot))
578+
disconnect_and_exit(1);
579+
disconnect_and_exit(0);
580+
}
581+
582+
/* Create a replication slot */
583+
if (do_create_slot)
584+
{
585+
if (verbose)
586+
fprintf(stderr,
587+
_("%s: creating replication slot \"%s\"\n"),
588+
progname,replication_slot);
589+
590+
if (!CreateReplicationSlot(conn,replication_slot,NULL,NULL, true))
591+
disconnect_and_exit(1);
592+
}
593+
469594
while (true)
470595
{
471596
StreamLog();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp