Skip to content

Commit e4ba69f

Browse files
committed
Allow extensions to add new backup targets.
Commit 3500ccc allowed for base backup targets, meaning that we could do something with the backup other than send it to the client, but all of those targets had to be baked in to the core code. This commit makes it possible for extensions to define additional backup targets. Patch by me, reviewed by Abhijit Menon-Sen. Discussion: http://postgr.es/m/CA+TgmoaqvdT-u3nt+_kkZ7bgDAyqDB0i-+XOMmr5JN2Rd37hxw@mail.gmail.com
1 parent 75eae09 commit e4ba69f

File tree

5 files changed

+381
-55
lines changed

5 files changed

+381
-55
lines changed

src/backend/replication/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ OBJS = \
2424
basebackup_progress.o \
2525
basebackup_server.o \
2626
basebackup_sink.o \
27+
basebackup_target.o \
2728
basebackup_throttle.o \
2829
repl_gram.o \
2930
slot.o \

src/backend/replication/Makefile.orig

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#-------------------------------------------------------------------------
2+
#
3+
# Makefile--
4+
# Makefile for src/backend/replication
5+
#
6+
# IDENTIFICATION
7+
# src/backend/replication/Makefile
8+
#
9+
#-------------------------------------------------------------------------
10+
11+
subdir = src/backend/replication
12+
top_builddir = ../../..
13+
include $(top_builddir)/src/Makefile.global
14+
15+
override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS)
16+
17+
OBJS = \
18+
backup_manifest.o \
19+
basebackup.o \
20+
basebackup_copy.o \
21+
basebackup_gzip.o \
22+
basebackup_lz4.o \
23+
basebackup_zstd.o \
24+
basebackup_progress.o \
25+
basebackup_server.o \
26+
basebackup_sink.o \
27+
basebackup_throttle.o \
28+
repl_gram.o \
29+
slot.o \
30+
slotfuncs.o \
31+
syncrep.o \
32+
syncrep_gram.o \
33+
walreceiver.o \
34+
walreceiverfuncs.o \
35+
walsender.o
36+
37+
SUBDIRS = logical
38+
39+
include $(top_srcdir)/src/backend/common.mk
40+
41+
# repl_scanner is compiled as part of repl_gram
42+
repl_gram.o: repl_scanner.c
43+
44+
# syncrep_scanner is compiled as part of syncrep_gram
45+
syncrep_gram.o: syncrep_scanner.c
46+
47+
# repl_gram.c, repl_scanner.c, syncrep_gram.c and syncrep_scanner.c
48+
# are in the distribution tarball, so they are not cleaned here.
49+
# (Our parent Makefile takes care of them during maintainer-clean.)

src/backend/replication/basebackup.c

+27-55
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "postmaster/syslogger.h"
2929
#include "replication/basebackup.h"
3030
#include "replication/basebackup_sink.h"
31+
#include "replication/basebackup_target.h"
3132
#include "replication/backup_manifest.h"
3233
#include "replication/walsender.h"
3334
#include "replication/walsender_private.h"
@@ -53,13 +54,6 @@
5354
*/
5455
#define SINK_BUFFER_LENGTH Max(32768, BLCKSZ)
5556

56-
typedef enum
57-
{
58-
BACKUP_TARGET_BLACKHOLE,
59-
BACKUP_TARGET_CLIENT,
60-
BACKUP_TARGET_SERVER
61-
} backup_target_type;
62-
6357
typedef enum
6458
{
6559
BACKUP_COMPRESSION_NONE,
@@ -77,8 +71,9 @@ typedef struct
7771
bool includewal;
7872
uint32 maxrate;
7973
bool sendtblspcmapfile;
80-
backup_target_type target;
81-
char *target_detail;
74+
bool send_to_client;
75+
bool use_copytblspc;
76+
BaseBackupTargetHandle *target_handle;
8277
backup_manifest_option manifest;
8378
basebackup_compression_type compression;
8479
int compression_level;
@@ -715,12 +710,12 @@ parse_basebackup_options(List *options, basebackup_options *opt)
715710
bool o_manifest_checksums = false;
716711
bool o_target = false;
717712
bool o_target_detail = false;
718-
char *target_str = "compat"; /* placate compiler */
713+
char *target_str = NULL;
714+
char *target_detail_str = NULL;
719715
bool o_compression = false;
720716
bool o_compression_level = false;
721717

722718
MemSet(opt, 0, sizeof(*opt));
723-
opt->target = BACKUP_TARGET_CLIENT;
724719
opt->manifest = MANIFEST_OPTION_NO;
725720
opt->manifest_checksum_type = CHECKSUM_TYPE_CRC32C;
726721
opt->compression = BACKUP_COMPRESSION_NONE;
@@ -864,22 +859,11 @@ parse_basebackup_options(List *options, basebackup_options *opt)
864859
}
865860
else if (strcmp(defel->defname, "target") == 0)
866861
{
867-
target_str = defGetString(defel);
868-
869862
if (o_target)
870863
ereport(ERROR,
871864
(errcode(ERRCODE_SYNTAX_ERROR),
872865
errmsg("duplicate option \"%s\"", defel->defname)));
873-
if (strcmp(target_str, "blackhole") == 0)
874-
opt->target = BACKUP_TARGET_BLACKHOLE;
875-
else if (strcmp(target_str, "client") == 0)
876-
opt->target = BACKUP_TARGET_CLIENT;
877-
else if (strcmp(target_str, "server") == 0)
878-
opt->target = BACKUP_TARGET_SERVER;
879-
else
880-
ereport(ERROR,
881-
(errcode(ERRCODE_SYNTAX_ERROR),
882-
errmsg("unrecognized target: \"%s\"", target_str)));
866+
target_str = defGetString(defel);
883867
o_target = true;
884868
}
885869
else if (strcmp(defel->defname, "target_detail") == 0)
@@ -890,7 +874,7 @@ parse_basebackup_options(List *options, basebackup_options *opt)
890874
ereport(ERROR,
891875
(errcode(ERRCODE_SYNTAX_ERROR),
892876
errmsg("duplicate option \"%s\"", defel->defname)));
893-
opt->target_detail = optval;
877+
target_detail_str = optval;
894878
o_target_detail = true;
895879
}
896880
else if (strcmp(defel->defname, "compression") == 0)
@@ -942,22 +926,28 @@ parse_basebackup_options(List *options, basebackup_options *opt)
942926
errmsg("manifest checksums require a backup manifest")));
943927
opt->manifest_checksum_type = CHECKSUM_TYPE_NONE;
944928
}
945-
if (opt->target == BACKUP_TARGET_SERVER)
929+
930+
if (target_str == NULL)
946931
{
947-
if (opt->target_detail == NULL)
932+
if (target_detail_str != NULL)
948933
ereport(ERROR,
949934
(errcode(ERRCODE_SYNTAX_ERROR),
950-
errmsg("target '%s' requires a target detail",
951-
target_str)));
935+
errmsg("target detail cannot be used without target")));
936+
opt->use_copytblspc = true;
937+
opt->send_to_client = true;
952938
}
953-
else
939+
else if (strcmp(target_str, "client") == 0)
954940
{
955-
if (opt->target_detail != NULL)
941+
if (target_detail_str != NULL)
956942
ereport(ERROR,
957943
(errcode(ERRCODE_SYNTAX_ERROR),
958944
errmsg("target '%s' does not accept a target detail",
959945
target_str)));
946+
opt->send_to_client = true;
960947
}
948+
else
949+
opt->target_handle =
950+
BaseBackupGetTargetHandle(target_str, target_detail_str);
961951

962952
if (o_compression_level && !o_compression)
963953
ereport(ERROR,
@@ -993,32 +983,14 @@ SendBaseBackup(BaseBackupCmd *cmd)
993983
}
994984

995985
/*
996-
* If the TARGET option was specified, then we can use the new copy-stream
997-
* protocol. If the target is specifically 'client' then set up to stream
998-
* the backup to the client; otherwise, it's being sent someplace else and
999-
* should not be sent to the client.
1000-
*/
1001-
if (opt.target == BACKUP_TARGET_CLIENT)
1002-
sink = bbsink_copystream_new(true);
1003-
else
1004-
sink = bbsink_copystream_new(false);
1005-
1006-
/*
1007-
* If a non-default backup target is in use, arrange to send the data
1008-
* wherever it needs to go.
986+
* If the target is specifically 'client' then set up to stream the backup
987+
* to the client; otherwise, it's being sent someplace else and should not
988+
* be sent to the client. BaseBackupGetSink has the job of setting up a
989+
* sink to send the backup data wherever it needs to go.
1009990
*/
1010-
switch (opt.target)
1011-
{
1012-
case BACKUP_TARGET_BLACKHOLE:
1013-
/* Nothing to do, just discard data. */
1014-
break;
1015-
case BACKUP_TARGET_CLIENT:
1016-
/* Nothing to do, handling above is sufficient. */
1017-
break;
1018-
case BACKUP_TARGET_SERVER:
1019-
sink = bbsink_server_new(sink, opt.target_detail);
1020-
break;
1021-
}
991+
sink = bbsink_copystream_new(opt.send_to_client);
992+
if (opt.target_handle != NULL)
993+
sink = BaseBackupGetSink(opt.target_handle, sink);
1022994

1023995
/* Set up network throttling, if client requested it */
1024996
if (opt.maxrate > 0)

0 commit comments

Comments
 (0)