mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-22 14:46:29 +00:00
Integration of pgbackupapi
This commit is contained in:
@@ -22,7 +22,7 @@ GIT_WORK_TREE=${repmgr_abs_srcdir}
|
||||
GIT_DIR=${repmgr_abs_srcdir}/.git
|
||||
export GIT_DIR
|
||||
export GIT_WORK_TREE
|
||||
|
||||
PG_LDFLAGS=-lcurl -ljson-c
|
||||
include $(PGXS)
|
||||
|
||||
-include ${repmgr_abs_srcdir}/Makefile.custom
|
||||
|
||||
@@ -66,7 +66,7 @@ REPMGR_CLIENT_OBJS = repmgr-client.o \
|
||||
repmgr-action-primary.o repmgr-action-standby.o repmgr-action-witness.o \
|
||||
repmgr-action-cluster.o repmgr-action-node.o repmgr-action-service.o repmgr-action-daemon.o \
|
||||
configdata.o configfile.o configfile-scan.o log.o strutil.o controldata.o dirutil.o compat.o \
|
||||
dbutils.o sysutils.o
|
||||
dbutils.o sysutils.o pgbackupapi.o
|
||||
REPMGRD_OBJS = repmgrd.o repmgrd-physical.o configdata.o configfile.o configfile-scan.o log.o \
|
||||
dbutils.o strutil.o controldata.o compat.o sysutils.o
|
||||
|
||||
|
||||
40
configdata.c
40
configdata.c
@@ -291,6 +291,46 @@ struct ConfigFileSetting config_file_settings[] =
|
||||
{},
|
||||
{}
|
||||
},
|
||||
/* pg_backupapi_backup_id*/
|
||||
{
|
||||
"pg_backupapi_backup_id",
|
||||
CONFIG_STRING,
|
||||
{ .strptr = config_file_options.pg_backupapi_backup_id },
|
||||
{ .strdefault = "" },
|
||||
{},
|
||||
{ .strmaxlen = sizeof(config_file_options.pg_backupapi_backup_id) },
|
||||
{}
|
||||
},
|
||||
/* pg_backupapi_host*/
|
||||
{
|
||||
"pg_backupapi_host",
|
||||
CONFIG_STRING,
|
||||
{ .strptr = config_file_options.pg_backupapi_host },
|
||||
{ .strdefault = "" },
|
||||
{},
|
||||
{ .strmaxlen = sizeof(config_file_options.pg_backupapi_host) },
|
||||
{}
|
||||
},
|
||||
/* pg_backupapi_node_name */
|
||||
{
|
||||
"pg_backupapi_node_name",
|
||||
CONFIG_STRING,
|
||||
{ .strptr = config_file_options.pg_backupapi_node_name },
|
||||
{ .strdefault = "" },
|
||||
{},
|
||||
{ .strmaxlen = sizeof(config_file_options.pg_backupapi_node_name) },
|
||||
{}
|
||||
},
|
||||
/* pg_backupapi_remote_ssh_command */
|
||||
{
|
||||
"pg_backupapi_remote_ssh_command",
|
||||
CONFIG_STRING,
|
||||
{ .strptr = config_file_options.pg_backupapi_remote_ssh_command },
|
||||
{ .strdefault = "" },
|
||||
{},
|
||||
{ .strmaxlen = sizeof(config_file_options.pg_backupapi_remote_ssh_command) },
|
||||
{}
|
||||
},
|
||||
|
||||
/* =======================
|
||||
* standby follow settings
|
||||
|
||||
@@ -164,6 +164,10 @@ typedef struct
|
||||
char archive_cleanup_command[MAXLEN];
|
||||
bool use_primary_conninfo_password;
|
||||
char passfile[MAXPGPATH];
|
||||
char pg_backupapi_backup_id[NAMEDATALEN];
|
||||
char pg_backupapi_host[NAMEDATALEN];
|
||||
char pg_backupapi_node_name[NAMEDATALEN];
|
||||
char pg_backupapi_remote_ssh_command[MAXLEN];
|
||||
|
||||
/* standby promote settings */
|
||||
int promote_check_timeout;
|
||||
|
||||
@@ -49,5 +49,6 @@
|
||||
#define ERR_NODE_STATUS 25
|
||||
#define ERR_REPMGRD_PAUSE 26
|
||||
#define ERR_REPMGRD_SERVICE 27
|
||||
#define ERR_PGBACKUPAPI_SERVICE 28
|
||||
|
||||
#endif /* _ERRCODE_H_ */
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "repmgr.h"
|
||||
#include "dirutil.h"
|
||||
@@ -29,7 +30,7 @@
|
||||
|
||||
#include "repmgr-client-global.h"
|
||||
#include "repmgr-action-standby.h"
|
||||
|
||||
#include "pgbackupapi.h"
|
||||
|
||||
typedef struct TablespaceDataListCell
|
||||
{
|
||||
@@ -113,6 +114,7 @@ static void check_recovery_type(PGconn *conn);
|
||||
static void initialise_direct_clone(t_node_info *local_node_record, t_node_info *upstream_node_record);
|
||||
static int run_basebackup(t_node_info *node_record);
|
||||
static int run_file_backup(t_node_info *node_record);
|
||||
static int run_pg_backupapi(t_node_info *node_record);
|
||||
|
||||
static void copy_configuration_files(bool delete_after_copy);
|
||||
|
||||
@@ -687,19 +689,18 @@ do_standby_clone(void)
|
||||
exit(SUCCESS);
|
||||
}
|
||||
|
||||
if (mode != barman)
|
||||
{
|
||||
initialise_direct_clone(&local_node_record, &upstream_node_record);
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case pg_basebackup:
|
||||
initialise_direct_clone(&local_node_record, &upstream_node_record);
|
||||
log_notice(_("starting backup (using pg_basebackup)..."));
|
||||
break;
|
||||
case barman:
|
||||
log_notice(_("retrieving backup from Barman..."));
|
||||
break;
|
||||
case pg_backupapi:
|
||||
log_notice(_("starting backup (using pg_backupapi)..."));
|
||||
break;
|
||||
default:
|
||||
/* should never reach here */
|
||||
log_error(_("unknown clone mode"));
|
||||
@@ -721,6 +722,9 @@ do_standby_clone(void)
|
||||
case barman:
|
||||
r = run_file_backup(&local_node_record);
|
||||
break;
|
||||
case pg_backupapi:
|
||||
r = run_pg_backupapi(&local_node_record);
|
||||
break;
|
||||
default:
|
||||
/* should never reach here */
|
||||
log_error(_("unknown clone mode"));
|
||||
@@ -814,7 +818,6 @@ do_standby_clone(void)
|
||||
}
|
||||
|
||||
/* Write the recovery.conf file */
|
||||
|
||||
if (create_recovery_file(&local_node_record,
|
||||
&recovery_conninfo,
|
||||
source_server_version_num,
|
||||
@@ -846,6 +849,9 @@ do_standby_clone(void)
|
||||
case barman:
|
||||
log_notice(_("standby clone (from Barman) complete"));
|
||||
break;
|
||||
case pg_backupapi:
|
||||
log_notice(_("standby clone (from pg_backupapi) complete"));
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -937,6 +943,9 @@ do_standby_clone(void)
|
||||
case barman:
|
||||
appendPQExpBufferStr(&event_details, "barman");
|
||||
break;
|
||||
case pg_backupapi:
|
||||
appendPQExpBufferStr(&event_details, "pg_backupapi");
|
||||
break;
|
||||
}
|
||||
|
||||
appendPQExpBuffer(&event_details,
|
||||
@@ -7770,6 +7779,86 @@ stop_backup:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform a call to pg_backupapi endpoint to ask barman to write the backup
|
||||
* for us. This will ensure that no matter the format on-disk of new backups,
|
||||
* barman will always find a way how to read and write them.
|
||||
* From repmgr 4 this is only used for Barman backups.
|
||||
*/
|
||||
static int
|
||||
run_pg_backupapi(t_node_info *local_node_record)
|
||||
{
|
||||
int r = ERR_PGBACKUPAPI_SERVICE;
|
||||
long http_return_code = 0;
|
||||
short seconds_to_sleep = 3;
|
||||
operation_task *task = malloc(sizeof(operation_task));
|
||||
CURL *curl = curl_easy_init();
|
||||
CURLcode ret;
|
||||
|
||||
|
||||
task->host = malloc(strlen(config_file_options.pg_backupapi_host)+1);
|
||||
task->remote_ssh_command = malloc(strlen(config_file_options.pg_backupapi_remote_ssh_command)+1);
|
||||
task->node_name = malloc(strlen(config_file_options.pg_backupapi_node_name)+1);
|
||||
task->operation_type = malloc(strlen(DEFAULT_STANDBY_PG_BACKUPAPI_OP_TYPE)+1);
|
||||
task->backup_id = malloc(strlen(config_file_options.pg_backupapi_backup_id)+1);
|
||||
task->destination_directory = malloc(strlen(local_data_directory)+1);
|
||||
|
||||
task->operation_id = malloc(MAX_BUFFER_LENGTH);
|
||||
task->operation_status = malloc(MAX_BUFFER_LENGTH);
|
||||
|
||||
strcpy(task->host, config_file_options.pg_backupapi_host);
|
||||
strcpy(task->remote_ssh_command, config_file_options.pg_backupapi_remote_ssh_command);
|
||||
strcpy(task->node_name, config_file_options.pg_backupapi_node_name);
|
||||
strcpy(task->operation_type, DEFAULT_STANDBY_PG_BACKUPAPI_OP_TYPE);
|
||||
strcpy(task->backup_id, config_file_options.pg_backupapi_backup_id);
|
||||
strcpy(task->destination_directory, local_data_directory);
|
||||
strcpy(task->operation_id, "\0");
|
||||
|
||||
ret = create_new_task(curl, task);
|
||||
|
||||
if ((ret != CURLE_OK) || (strlen(task->operation_id) == 0)) {
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_return_code);
|
||||
if (499 > http_return_code && http_return_code >= 400) {
|
||||
log_error("Cannot find backup '%s' for node '%s'.", task->backup_id, task->node_name);
|
||||
} else {
|
||||
log_error("whilst reaching out pg_backup service: %s\n", curl_easy_strerror(ret));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info("Success creating the task: operation id '%s'", task->operation_id);
|
||||
|
||||
//We call init again because previous call included POST calls
|
||||
curl_easy_cleanup(curl);
|
||||
curl = curl_easy_init();
|
||||
while (true)
|
||||
{
|
||||
ret = get_status_of_operation(curl, task);
|
||||
if (strlen(task->operation_status) == 0) {
|
||||
log_info("Retrying...");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_info("status %s", task->operation_status);
|
||||
}
|
||||
if (strcmp(task->operation_status, "FAILED") == 0) {
|
||||
break;
|
||||
}
|
||||
if (strcmp(task->operation_status, "DONE") == 0) {
|
||||
r = SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
sleep(seconds_to_sleep);
|
||||
}
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
free(task);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
make_barman_ssh_command(char *buf)
|
||||
{
|
||||
|
||||
@@ -193,7 +193,8 @@ typedef struct
|
||||
typedef enum
|
||||
{
|
||||
barman,
|
||||
pg_basebackup
|
||||
pg_basebackup,
|
||||
pg_backupapi
|
||||
} standy_clone_mode;
|
||||
|
||||
typedef enum
|
||||
|
||||
@@ -3096,9 +3096,14 @@ get_standby_clone_mode(void)
|
||||
|
||||
if (*config_file_options.barman_host != '\0' && runtime_options.without_barman == false)
|
||||
mode = barman;
|
||||
else
|
||||
mode = pg_basebackup;
|
||||
|
||||
else {
|
||||
if (*config_file_options.pg_backupapi_host != '\0') {
|
||||
log_info("Attempting to use `pg_backupapi` new restore mode");
|
||||
mode = pg_backupapi;
|
||||
}
|
||||
else
|
||||
mode = pg_basebackup;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user