Commit e5487f65 authored by Magnus Hagander's avatar Magnus Hagander

Make walsender options order-independent

While doing this, also move base backup options into
a struct instead of increasing the number of parameters
to multiple functions for each new option.
parent 39e911e2
...@@ -32,6 +32,14 @@ ...@@ -32,6 +32,14 @@
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/ps_status.h" #include "utils/ps_status.h"
typedef struct
{
const char *label;
bool progress;
bool fastcheckpoint;
} basebackup_options;
static int64 sendDir(char *path, int basepathlen, bool sizeonly); static int64 sendDir(char *path, int basepathlen, bool sizeonly);
static void sendFile(char *path, int basepathlen, struct stat * statbuf); static void sendFile(char *path, int basepathlen, struct stat * statbuf);
static void _tarWriteHeader(char *filename, char *linktarget, static void _tarWriteHeader(char *filename, char *linktarget,
...@@ -40,7 +48,8 @@ static void send_int8_string(StringInfoData *buf, int64 intval); ...@@ -40,7 +48,8 @@ static void send_int8_string(StringInfoData *buf, int64 intval);
static void SendBackupHeader(List *tablespaces); static void SendBackupHeader(List *tablespaces);
static void SendBackupDirectory(char *location, char *spcoid); static void SendBackupDirectory(char *location, char *spcoid);
static void base_backup_cleanup(int code, Datum arg); static void base_backup_cleanup(int code, Datum arg);
static void perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, bool fastcheckpoint); static void perform_base_backup(basebackup_options *opt, DIR *tblspcdir);
static void parse_basebackup_options(List *options, basebackup_options *opt);
typedef struct typedef struct
{ {
...@@ -67,9 +76,9 @@ base_backup_cleanup(int code, Datum arg) ...@@ -67,9 +76,9 @@ base_backup_cleanup(int code, Datum arg)
* clobbered by longjmp" from stupider versions of gcc. * clobbered by longjmp" from stupider versions of gcc.
*/ */
static void static void
perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, bool fastcheckpoint) perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
{ {
do_pg_start_backup(backup_label, fastcheckpoint); do_pg_start_backup(opt->label, opt->fastcheckpoint);
PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0); PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0);
{ {
...@@ -81,7 +90,7 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo ...@@ -81,7 +90,7 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
/* Add a node for the base directory */ /* Add a node for the base directory */
ti = palloc0(sizeof(tablespaceinfo)); ti = palloc0(sizeof(tablespaceinfo));
ti->size = progress ? sendDir(".", 1, true) : -1; ti->size = opt->progress ? sendDir(".", 1, true) : -1;
tablespaces = lappend(tablespaces, ti); tablespaces = lappend(tablespaces, ti);
/* Collect information about all tablespaces */ /* Collect information about all tablespaces */
...@@ -107,7 +116,7 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo ...@@ -107,7 +116,7 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
ti = palloc(sizeof(tablespaceinfo)); ti = palloc(sizeof(tablespaceinfo));
ti->oid = pstrdup(de->d_name); ti->oid = pstrdup(de->d_name);
ti->path = pstrdup(linkpath); ti->path = pstrdup(linkpath);
ti->size = progress ? sendDir(linkpath, strlen(linkpath), true) : -1; ti->size = opt->progress ? sendDir(linkpath, strlen(linkpath), true) : -1;
tablespaces = lappend(tablespaces, ti); tablespaces = lappend(tablespaces, ti);
} }
...@@ -128,6 +137,58 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo ...@@ -128,6 +137,58 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
do_pg_stop_backup(); do_pg_stop_backup();
} }
/*
* Parse the base backup options passed down by the parser
*/
static void
parse_basebackup_options(List *options, basebackup_options *opt)
{
ListCell *lopt;
bool o_label = false;
bool o_progress = false;
bool o_fast = false;
MemSet(opt, 0, sizeof(opt));
foreach(lopt, options)
{
DefElem *defel = (DefElem *) lfirst(lopt);
if (strcmp(defel->defname, "label") == 0)
{
if (o_label)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("duplicate option \"%s\"", defel->defname)));
opt->label = strVal(defel->arg);
o_label = true;
}
else if (strcmp(defel->defname, "progress") == 0)
{
if (o_progress)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("duplicate option \"%s\"", defel->defname)));
opt->progress = true;
o_progress = true;
}
else if (strcmp(defel->defname, "fast") == 0)
{
if (o_fast)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("duplicate option \"%s\"", defel->defname)));
opt->fastcheckpoint = true;
o_fast = true;
}
else
elog(ERROR, "option \"%s\" not recognized",
defel->defname);
}
if (opt->label == NULL)
opt->label = "base backup";
}
/* /*
* SendBaseBackup() - send a complete base backup. * SendBaseBackup() - send a complete base backup.
* *
...@@ -135,11 +196,14 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo ...@@ -135,11 +196,14 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
* pg_stop_backup() for the user. * pg_stop_backup() for the user.
*/ */
void void
SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint) SendBaseBackup(BaseBackupCmd *cmd)
{ {
DIR *dir; DIR *dir;
MemoryContext backup_context; MemoryContext backup_context;
MemoryContext old_context; MemoryContext old_context;
basebackup_options opt;
parse_basebackup_options(cmd->options, &opt);
backup_context = AllocSetContextCreate(CurrentMemoryContext, backup_context = AllocSetContextCreate(CurrentMemoryContext,
"Streaming base backup context", "Streaming base backup context",
...@@ -150,15 +214,12 @@ SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint) ...@@ -150,15 +214,12 @@ SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint)
WalSndSetState(WALSNDSTATE_BACKUP); WalSndSetState(WALSNDSTATE_BACKUP);
if (backup_label == NULL)
backup_label = "base backup";
if (update_process_title) if (update_process_title)
{ {
char activitymsg[50]; char activitymsg[50];
snprintf(activitymsg, sizeof(activitymsg), "sending backup \"%s\"", snprintf(activitymsg, sizeof(activitymsg), "sending backup \"%s\"",
backup_label); opt.label);
set_ps_display(activitymsg, false); set_ps_display(activitymsg, false);
} }
...@@ -168,7 +229,7 @@ SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint) ...@@ -168,7 +229,7 @@ SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint)
ereport(ERROR, ereport(ERROR,
(errmsg("unable to open directory pg_tblspc: %m"))); (errmsg("unable to open directory pg_tblspc: %m")));
perform_base_backup(backup_label, progress, dir, fastcheckpoint); perform_base_backup(&opt, dir);
FreeDir(dir); FreeDir(dir);
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include "postgres.h" #include "postgres.h"
#include "nodes/makefuncs.h"
#include "nodes/parsenodes.h"
#include "replication/replnodes.h" #include "replication/replnodes.h"
#include "replication/walsender.h" #include "replication/walsender.h"
...@@ -55,6 +57,8 @@ Node *replication_parse_result; ...@@ -55,6 +57,8 @@ Node *replication_parse_result;
XLogRecPtr recptr; XLogRecPtr recptr;
Node *node; Node *node;
List *list;
DefElem *defelt;
} }
/* Non-keyword tokens */ /* Non-keyword tokens */
...@@ -71,9 +75,8 @@ Node *replication_parse_result; ...@@ -71,9 +75,8 @@ Node *replication_parse_result;
%type <node> command %type <node> command
%type <node> base_backup start_replication identify_system %type <node> base_backup start_replication identify_system
%type <boolval> opt_progress opt_fast %type <list> base_backup_opt_list
%type <str> opt_label %type <defelt> base_backup_opt
%% %%
firstcmd: command opt_semicolon firstcmd: command opt_semicolon
...@@ -106,28 +109,34 @@ identify_system: ...@@ -106,28 +109,34 @@ identify_system:
* BASE_BACKUP [LABEL <label>] [PROGRESS] [FAST] * BASE_BACKUP [LABEL <label>] [PROGRESS] [FAST]
*/ */
base_backup: base_backup:
K_BASE_BACKUP opt_label opt_progress opt_fast K_BASE_BACKUP base_backup_opt_list
{ {
BaseBackupCmd *cmd = (BaseBackupCmd *) makeNode(BaseBackupCmd); BaseBackupCmd *cmd = (BaseBackupCmd *) makeNode(BaseBackupCmd);
cmd->options = $2;
cmd->label = $2;
cmd->progress = $3;
cmd->fastcheckpoint = $4;
$$ = (Node *) cmd; $$ = (Node *) cmd;
} }
; ;
opt_label: K_LABEL SCONST { $$ = $2; } base_backup_opt_list: base_backup_opt_list base_backup_opt { $$ = lappend($1, $2); }
| /* EMPTY */ { $$ = NULL; } | /* EMPTY */ { $$ = NIL; }
;
base_backup_opt:
K_LABEL SCONST
{
$$ = makeDefElem("label",
(Node *)makeString($2));
}
| K_PROGRESS
{
$$ = makeDefElem("progress",
(Node *)makeInteger(TRUE));
}
| K_FAST
{
$$ = makeDefElem("fast",
(Node *)makeInteger(TRUE));
}
opt_progress: K_PROGRESS { $$ = true; }
| /* EMPTY */ { $$ = false; }
;
opt_fast: K_FAST { $$ = true; }
| /* EMPTY */ { $$ = false; }
;
/* /*
* START_REPLICATION %X/%X * START_REPLICATION %X/%X
......
...@@ -399,17 +399,13 @@ HandleReplicationCommand(const char *cmd_string) ...@@ -399,17 +399,13 @@ HandleReplicationCommand(const char *cmd_string)
break; break;
case T_BaseBackupCmd: case T_BaseBackupCmd:
{ SendBaseBackup((BaseBackupCmd *) cmd_node);
BaseBackupCmd *cmd = (BaseBackupCmd *) cmd_node;
SendBaseBackup(cmd->label, cmd->progress, cmd->fastcheckpoint);
/* Send CommandComplete and ReadyForQuery messages */ /* Send CommandComplete and ReadyForQuery messages */
EndCommand("SELECT", DestRemote); EndCommand("SELECT", DestRemote);
ReadyForQuery(DestRemote); ReadyForQuery(DestRemote);
/* ReadyForQuery did pq_flush for us */ /* ReadyForQuery did pq_flush for us */
break; break;
}
default: default:
ereport(FATAL, ereport(FATAL,
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#ifndef _BASEBACKUP_H #ifndef _BASEBACKUP_H
#define _BASEBACKUP_H #define _BASEBACKUP_H
extern void SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint); #include "replication/replnodes.h"
extern void SendBaseBackup(BaseBackupCmd *cmd);
#endif /* _BASEBACKUP_H */ #endif /* _BASEBACKUP_H */
...@@ -45,9 +45,7 @@ typedef struct IdentifySystemCmd ...@@ -45,9 +45,7 @@ typedef struct IdentifySystemCmd
typedef struct BaseBackupCmd typedef struct BaseBackupCmd
{ {
NodeTag type; NodeTag type;
char *label; List *options;
bool progress;
bool fastcheckpoint;
} BaseBackupCmd; } BaseBackupCmd;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment