diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml index a232546b1d0..8ed88334442 100644 --- a/doc/src/sgml/protocol.sgml +++ b/doc/src/sgml/protocol.sgml @@ -2517,7 +2517,7 @@ The commands accepted in replication mode are: - BASE_BACKUP [ LABEL 'label' ] [ PROGRESS ] [ FAST ] [ WAL ] [ NOWAIT ] [ MAX_RATE rate ] [ TABLESPACE_MAP ] [ NOVERIFY_CHECKSUMS ] [ MANIFEST manifest_option ] [ MANIFEST_CHECKSUMS checksum_algorithm ] + BASE_BACKUP [ ( option [, ...] ) ] BASE_BACKUP @@ -2540,52 +2540,55 @@ The commands accepted in replication mode are: - PROGRESS + PROGRESS [ boolean ] - Request information required to generate a progress report. This will - send back an approximate size in the header of each tablespace, which - can be used to calculate how far along the stream is done. This is - calculated by enumerating all the file sizes once before the transfer - is even started, and might as such have a negative impact on the - performance. In particular, it might take longer before the first data + If set to true, request information required to generate a progress + report. This will send back an approximate size in the header of each + tablespace, which can be used to calculate how far along the stream + is done. This is calculated by enumerating all the file sizes once + before the transfer is even started, and might as such have a + negative impact on the performance. In particular, it might take + longer before the first data is streamed. Since the database files can change during the backup, the size is only approximate and might both grow and shrink between the time of approximation and the sending of the actual files. + The default is false. - FAST + CHECKPOINT { 'fast' | 'spread' } - Request a fast checkpoint. + Sets the type of checkpoint to be performed at the beginning of the + base backup. The default is spread. - WAL + WAL [ boolean ] - Include the necessary WAL segments in the backup. This will include - all the files between start and stop backup in the + If set to true, include the necessary WAL segments in the backup. + This will include all the files between start and stop backup in the pg_wal directory of the base directory tar - file. + file. The default is false. - NOWAIT + WAIT [ boolean ] - By default, the backup will wait until the last required WAL + If set to true, the backup will wait until the last required WAL segment has been archived, or emit a warning if log archiving is - not enabled. Specifying NOWAIT disables both - the waiting and the warning, leaving the client responsible for - ensuring the required log is available. + not enabled. If false, the backup will neither wait nor warn, + leaving the client responsible for ensuring the required log is + available. The default is true. @@ -2605,25 +2608,25 @@ The commands accepted in replication mode are: - TABLESPACE_MAP + TABLESPACE_MAP [ boolean ] - Include information about symbolic links present in the directory - pg_tblspc in a file named + If true, include information about symbolic links present in the + directory pg_tblspc in a file named tablespace_map. The tablespace map file includes each symbolic link name as it exists in the directory pg_tblspc/ and the full path of that symbolic link. + The default is false. - NOVERIFY_CHECKSUMS + VERIFY_CHECKSUMS [ boolean ] - By default, checksums are verified during a base backup if they are - enabled. Specifying NOVERIFY_CHECKSUMS disables - this verification. + If true, checksums are verified during a base backup if they are + enabled. If false, this is skipped. The default is true. @@ -2708,6 +2711,7 @@ The commands accepted in replication mode are: + After the second regular result set, one or more CopyOutResponse results will be sent, one for the main data directory and one for each additional tablespace other @@ -2788,6 +2792,17 @@ The commands accepted in replication mode are: + + + BASE_BACKUP [ LABEL 'label' ] [ PROGRESS ] [ FAST ] [ WAL ] [ NOWAIT ] [ MAX_RATE rate ] [ TABLESPACE_MAP ] [ NOVERIFY_CHECKSUMS ] [ MANIFEST manifest_option ] [ MANIFEST_CHECKSUMS checksum_algorithm ] + + + + For compatibility with older releases, this alternative syntax for + the BASE_BACKUP command is still supported. + + + diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index e09108d0ece..4c97ab7b5a7 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" @@ -764,7 +765,7 @@ parse_basebackup_options(List *options, basebackup_options *opt) ListCell *lopt; bool o_label = false; bool o_progress = false; - bool o_fast = false; + bool o_checkpoint = false; bool o_nowait = false; bool o_wal = false; bool o_maxrate = false; @@ -787,7 +788,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) @@ -796,25 +797,35 @@ 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) + else if (strcmp(defel->defname, "checkpoint") == 0) { - if (o_fast) + char *optval = defGetString(defel); + + if (o_checkpoint) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("duplicate option \"%s\"", defel->defname))); - opt->fastcheckpoint = true; - o_fast = true; + if (pg_strcasecmp(optval, "fast") == 0) + opt->fastcheckpoint = true; + else if (pg_strcasecmp(optval, "spread") == 0) + opt->fastcheckpoint = false; + else + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("unrecognized checkpoint type: \"%s\"", + optval))); + o_checkpoint = 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) @@ -823,19 +834,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), @@ -851,21 +862,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) @@ -890,7 +901,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, @@ -905,8 +916,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/repl_gram.y b/src/backend/replication/repl_gram.y index e1e8ec29cc4..3b59d62ed86 100644 --- a/src/backend/replication/repl_gram.y +++ b/src/backend/replication/repl_gram.y @@ -95,13 +95,13 @@ 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 @@ -157,12 +157,24 @@ var_name: IDENT { $$ = $1; } ; /* + * BASE_BACKUP ( option [ 'value' ] [, ...] ) + * + * We also still support the legacy syntax: + * * BASE_BACKUP [LABEL '