From 787068be3c23308b6fe46fc8c731c6d6ef82f485 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Thu, 11 Jun 2020 15:28:39 -0400 Subject: [PATCH v2 01/11] Flexible options for BASE_BACKUP and CREATE_REPLICATION_SLOT. --- src/backend/replication/basebackup.c | 33 ++--- .../libpqwalreceiver/libpqwalreceiver.c | 8 +- src/backend/replication/repl_gram.y | 115 +++++++++++++++--- src/backend/replication/walsender.c | 15 +-- src/bin/pg_basebackup/pg_basebackup.c | 108 ++++++++++++---- src/bin/pg_basebackup/streamutil.c | 14 ++- 6 files changed, 220 insertions(+), 73 deletions(-) diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index 6064384e32..d43c34e8e9 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -19,6 +19,7 @@ #include "access/xlog_internal.h" /* for pg_start/stop_backup */ #include "catalog/pg_type.h" #include "common/file_perm.h" +#include "commands/defrem.h" #include "commands/progress.h" #include "lib/stringinfo.h" #include "libpq/libpq.h" @@ -777,7 +778,7 @@ parse_basebackup_options(List *options, basebackup_options *opt) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("duplicate option \"%s\"", defel->defname))); - opt->label = strVal(defel->arg); + opt->label = defGetString(defel); o_label = true; } else if (strcmp(defel->defname, "progress") == 0) @@ -786,7 +787,7 @@ parse_basebackup_options(List *options, basebackup_options *opt) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("duplicate option \"%s\"", defel->defname))); - opt->progress = true; + opt->progress = defGetBoolean(defel); o_progress = true; } else if (strcmp(defel->defname, "fast") == 0) @@ -795,16 +796,16 @@ parse_basebackup_options(List *options, basebackup_options *opt) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("duplicate option \"%s\"", defel->defname))); - opt->fastcheckpoint = true; + opt->fastcheckpoint = defGetBoolean(defel); o_fast = true; } - else if (strcmp(defel->defname, "nowait") == 0) + else if (strcmp(defel->defname, "wait") == 0) { if (o_nowait) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("duplicate option \"%s\"", defel->defname))); - opt->nowait = true; + opt->nowait = !defGetBoolean(defel); o_nowait = true; } else if (strcmp(defel->defname, "wal") == 0) @@ -813,19 +814,19 @@ parse_basebackup_options(List *options, basebackup_options *opt) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("duplicate option \"%s\"", defel->defname))); - opt->includewal = true; + opt->includewal = defGetBoolean(defel); o_wal = true; } else if (strcmp(defel->defname, "max_rate") == 0) { - long maxrate; + int64 maxrate; if (o_maxrate) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("duplicate option \"%s\"", defel->defname))); - maxrate = intVal(defel->arg); + maxrate = defGetInt64(defel); if (maxrate < MAX_RATE_LOWER || maxrate > MAX_RATE_UPPER) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), @@ -841,21 +842,21 @@ parse_basebackup_options(List *options, basebackup_options *opt) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("duplicate option \"%s\"", defel->defname))); - opt->sendtblspcmapfile = true; + opt->sendtblspcmapfile = defGetBoolean(defel); o_tablespace_map = true; } - else if (strcmp(defel->defname, "noverify_checksums") == 0) + else if (strcmp(defel->defname, "verify_checksums") == 0) { if (o_noverify_checksums) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("duplicate option \"%s\"", defel->defname))); - noverify_checksums = true; + noverify_checksums = !defGetBoolean(defel); o_noverify_checksums = true; } else if (strcmp(defel->defname, "manifest") == 0) { - char *optval = strVal(defel->arg); + char *optval = defGetString(defel); bool manifest_bool; if (o_manifest) @@ -880,7 +881,7 @@ parse_basebackup_options(List *options, basebackup_options *opt) } else if (strcmp(defel->defname, "manifest_checksums") == 0) { - char *optval = strVal(defel->arg); + char *optval = defGetString(defel); if (o_manifest_checksums) ereport(ERROR, @@ -895,8 +896,10 @@ parse_basebackup_options(List *options, basebackup_options *opt) o_manifest_checksums = true; } else - elog(ERROR, "option \"%s\" not recognized", - defel->defname); + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("option \"%s\" not recognized", + defel->defname)); } if (opt->label == NULL) opt->label = "base backup"; diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index e9057230e4..c381e26143 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -828,19 +828,19 @@ libpqrcv_create_slot(WalReceiverConn *conn, const char *slotname, switch (snapshot_action) { case CRS_EXPORT_SNAPSHOT: - appendStringInfoString(&cmd, " EXPORT_SNAPSHOT"); + appendStringInfoString(&cmd, " (EXPORT_SNAPSHOT TRUE)"); break; case CRS_NOEXPORT_SNAPSHOT: - appendStringInfoString(&cmd, " NOEXPORT_SNAPSHOT"); + appendStringInfoString(&cmd, " (EXPORT_SNAPSHOT FALSE)"); break; case CRS_USE_SNAPSHOT: - appendStringInfoString(&cmd, " USE_SNAPSHOT"); + appendStringInfoString(&cmd, " (USE_SNAPSHOT)"); break; } } else { - appendStringInfoString(&cmd, " PHYSICAL RESERVE_WAL"); + appendStringInfoString(&cmd, " PHYSICAL (RESERVE_WAL)"); } res = libpqrcv_PQexec(conn->streamConn, cmd.data); diff --git a/src/backend/replication/repl_gram.y b/src/backend/replication/repl_gram.y index f93a0de218..8b2109855d 100644 --- a/src/backend/replication/repl_gram.y +++ b/src/backend/replication/repl_gram.y @@ -94,16 +94,16 @@ static SQLCmd *make_sqlcmd(void); %type base_backup start_replication start_logical_replication create_replication_slot drop_replication_slot identify_system timeline_history show sql_cmd -%type base_backup_opt_list -%type base_backup_opt +%type base_backup_legacy_opt_list generic_option_list +%type base_backup_legacy_opt generic_option %type opt_timeline %type plugin_options plugin_opt_list %type plugin_opt_elem %type plugin_opt_arg -%type opt_slot var_name +%type opt_slot var_name ident_or_keyword %type opt_temporary -%type create_slot_opt_list -%type create_slot_opt +%type create_slot_options create_slot_legacy_opt_list +%type create_slot_legacy_opt %% @@ -156,12 +156,24 @@ var_name: IDENT { $$ = $1; } ; /* + * BASE_BACKUP ( option [ 'value' ] [, ...] ) + * + * We also still support the legacy syntax: + * * BASE_BACKUP [LABEL '