mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2025-04-22 13:07:55 +02:00
PGPRO-533: Allow to show backup list in json format
This commit is contained in:
parent
37ced690ad
commit
ceaa2ce9cd
24
src/backup.c
24
src/backup.c
@ -633,7 +633,7 @@ do_backup_instance(void)
|
|||||||
* For backup from master wait for previous segment.
|
* For backup from master wait for previous segment.
|
||||||
* For backup from replica wait for current segment.
|
* For backup from replica wait for current segment.
|
||||||
*/
|
*/
|
||||||
!from_replica, backup_files_list);
|
!current.from_replica, backup_files_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current.backup_mode == BACKUP_MODE_DIFF_PTRACK)
|
if (current.backup_mode == BACKUP_MODE_DIFF_PTRACK)
|
||||||
@ -815,11 +815,15 @@ do_backup(time_t start_time)
|
|||||||
pgut_atexit_push(backup_disconnect, NULL);
|
pgut_atexit_push(backup_disconnect, NULL);
|
||||||
|
|
||||||
current.primary_conninfo = pgut_get_conninfo_string(backup_conn);
|
current.primary_conninfo = pgut_get_conninfo_string(backup_conn);
|
||||||
|
|
||||||
|
current.compress_alg = compress_alg;
|
||||||
|
current.compress_level = compress_level;
|
||||||
|
|
||||||
/* Confirm data block size and xlog block size are compatible */
|
/* Confirm data block size and xlog block size are compatible */
|
||||||
confirm_block_size("block_size", BLCKSZ);
|
confirm_block_size("block_size", BLCKSZ);
|
||||||
confirm_block_size("wal_block_size", XLOG_BLCKSZ);
|
confirm_block_size("wal_block_size", XLOG_BLCKSZ);
|
||||||
|
|
||||||
from_replica = pg_is_in_recovery();
|
current.from_replica = pg_is_in_recovery();
|
||||||
|
|
||||||
/* Confirm that this server version is supported */
|
/* Confirm that this server version is supported */
|
||||||
check_server_version();
|
check_server_version();
|
||||||
@ -859,7 +863,7 @@ do_backup(time_t start_time)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (from_replica)
|
if (current.from_replica)
|
||||||
{
|
{
|
||||||
/* Check master connection options */
|
/* Check master connection options */
|
||||||
if (master_host == NULL)
|
if (master_host == NULL)
|
||||||
@ -956,7 +960,7 @@ check_server_version(void)
|
|||||||
"server version is %s, must be %s or higher",
|
"server version is %s, must be %s or higher",
|
||||||
server_version_str, "9.5");
|
server_version_str, "9.5");
|
||||||
|
|
||||||
if (from_replica && server_version < 90600)
|
if (current.from_replica && server_version < 90600)
|
||||||
elog(ERROR,
|
elog(ERROR,
|
||||||
"server version is %s, must be %s or higher for backup from replica",
|
"server version is %s, must be %s or higher for backup from replica",
|
||||||
server_version_str, "9.6");
|
server_version_str, "9.6");
|
||||||
@ -1061,7 +1065,7 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
|
|||||||
params[0] = label;
|
params[0] = label;
|
||||||
|
|
||||||
/* For replica we call pg_start_backup() on master */
|
/* For replica we call pg_start_backup() on master */
|
||||||
conn = (from_replica) ? master_conn : backup_conn;
|
conn = (backup->from_replica) ? master_conn : backup_conn;
|
||||||
|
|
||||||
/* 2nd argument is 'fast'*/
|
/* 2nd argument is 'fast'*/
|
||||||
params[1] = smooth ? "false" : "true";
|
params[1] = smooth ? "false" : "true";
|
||||||
@ -1106,7 +1110,7 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for start_lsn to be replayed by replica */
|
/* Wait for start_lsn to be replayed by replica */
|
||||||
if (from_replica)
|
if (backup->from_replica)
|
||||||
wait_replica_wal_lsn(backup->start_lsn, true);
|
wait_replica_wal_lsn(backup->start_lsn, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1554,8 +1558,6 @@ wait_replica_wal_lsn(XLogRecPtr lsn, bool is_start_backup)
|
|||||||
{
|
{
|
||||||
uint32 try_count = 0;
|
uint32 try_count = 0;
|
||||||
|
|
||||||
Assert(from_replica);
|
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
PGresult *res;
|
PGresult *res;
|
||||||
@ -1650,7 +1652,7 @@ pg_stop_backup(pgBackup *backup)
|
|||||||
elog(FATAL, "backup is not in progress");
|
elog(FATAL, "backup is not in progress");
|
||||||
|
|
||||||
/* For replica we call pg_stop_backup() on master */
|
/* For replica we call pg_stop_backup() on master */
|
||||||
conn = (from_replica) ? master_conn : backup_conn;
|
conn = (current.from_replica) ? master_conn : backup_conn;
|
||||||
|
|
||||||
/* Remove annoying NOTICE messages generated by backend */
|
/* Remove annoying NOTICE messages generated by backend */
|
||||||
res = pgut_execute(conn, "SET client_min_messages = warning;",
|
res = pgut_execute(conn, "SET client_min_messages = warning;",
|
||||||
@ -1663,7 +1665,7 @@ pg_stop_backup(pgBackup *backup)
|
|||||||
const char *params[1];
|
const char *params[1];
|
||||||
char name[1024];
|
char name[1024];
|
||||||
|
|
||||||
if (!from_replica)
|
if (!current.from_replica)
|
||||||
snprintf(name, lengthof(name), "pg_probackup, backup_id %s",
|
snprintf(name, lengthof(name), "pg_probackup, backup_id %s",
|
||||||
base36enc(backup->start_time));
|
base36enc(backup->start_time));
|
||||||
else
|
else
|
||||||
@ -1891,7 +1893,7 @@ pg_stop_backup(pgBackup *backup)
|
|||||||
stream_xlog_path[MAXPGPATH];
|
stream_xlog_path[MAXPGPATH];
|
||||||
|
|
||||||
/* Wait for stop_lsn to be received by replica */
|
/* Wait for stop_lsn to be received by replica */
|
||||||
if (from_replica)
|
if (backup->from_replica)
|
||||||
wait_replica_wal_lsn(stop_backup_lsn, false);
|
wait_replica_wal_lsn(stop_backup_lsn, false);
|
||||||
/*
|
/*
|
||||||
* Wait for stop_lsn to be archived or streamed.
|
* Wait for stop_lsn to be archived or streamed.
|
||||||
|
@ -385,10 +385,11 @@ pgBackupWriteControl(FILE *out, pgBackup *backup)
|
|||||||
|
|
||||||
fprintf(out, "#Configuration\n");
|
fprintf(out, "#Configuration\n");
|
||||||
fprintf(out, "backup-mode = %s\n", pgBackupGetBackupMode(backup));
|
fprintf(out, "backup-mode = %s\n", pgBackupGetBackupMode(backup));
|
||||||
fprintf(out, "stream = %s\n", backup->stream?"true":"false");
|
fprintf(out, "stream = %s\n", backup->stream ? "true" : "false");
|
||||||
fprintf(out, "compress-alg = %s\n", deparse_compress_alg(compress_alg));
|
fprintf(out, "compress-alg = %s\n",
|
||||||
fprintf(out, "compress-level = %d\n", compress_level);
|
deparse_compress_alg(backup->compress_alg));
|
||||||
fprintf(out, "from-replica = %s\n", from_replica?"true":"false");
|
fprintf(out, "compress-level = %d\n", backup->compress_level);
|
||||||
|
fprintf(out, "from-replica = %s\n", backup->from_replica ? "true" : "false");
|
||||||
|
|
||||||
fprintf(out, "\n#Compatibility\n");
|
fprintf(out, "\n#Compatibility\n");
|
||||||
fprintf(out, "block-size = %u\n", backup->block_size);
|
fprintf(out, "block-size = %u\n", backup->block_size);
|
||||||
@ -429,7 +430,7 @@ pgBackupWriteControl(FILE *out, pgBackup *backup)
|
|||||||
if (backup->data_bytes != BYTES_INVALID)
|
if (backup->data_bytes != BYTES_INVALID)
|
||||||
fprintf(out, "data-bytes = " INT64_FORMAT "\n", backup->data_bytes);
|
fprintf(out, "data-bytes = " INT64_FORMAT "\n", backup->data_bytes);
|
||||||
|
|
||||||
if (backup->data_bytes != BYTES_INVALID)
|
if (backup->wal_bytes != BYTES_INVALID)
|
||||||
fprintf(out, "wal-bytes = " INT64_FORMAT "\n", backup->wal_bytes);
|
fprintf(out, "wal-bytes = " INT64_FORMAT "\n", backup->wal_bytes);
|
||||||
|
|
||||||
fprintf(out, "status = %s\n", status2str(backup->status));
|
fprintf(out, "status = %s\n", status2str(backup->status));
|
||||||
@ -475,10 +476,8 @@ readBackupControlFile(const char *path)
|
|||||||
char *stop_lsn = NULL;
|
char *stop_lsn = NULL;
|
||||||
char *status = NULL;
|
char *status = NULL;
|
||||||
char *parent_backup = NULL;
|
char *parent_backup = NULL;
|
||||||
char *compress_alg = NULL;
|
|
||||||
char *server_version = NULL;
|
char *server_version = NULL;
|
||||||
int *compress_level;
|
char *compress_alg = NULL;
|
||||||
bool *from_replica;
|
|
||||||
|
|
||||||
pgut_option options[] =
|
pgut_option options[] =
|
||||||
{
|
{
|
||||||
@ -500,8 +499,8 @@ readBackupControlFile(const char *path)
|
|||||||
{'s', 0, "status", &status, SOURCE_FILE_STRICT},
|
{'s', 0, "status", &status, SOURCE_FILE_STRICT},
|
||||||
{'s', 0, "parent-backup-id", &parent_backup, SOURCE_FILE_STRICT},
|
{'s', 0, "parent-backup-id", &parent_backup, SOURCE_FILE_STRICT},
|
||||||
{'s', 0, "compress-alg", &compress_alg, SOURCE_FILE_STRICT},
|
{'s', 0, "compress-alg", &compress_alg, SOURCE_FILE_STRICT},
|
||||||
{'u', 0, "compress-level", &compress_level, SOURCE_FILE_STRICT},
|
{'u', 0, "compress-level", &backup->compress_level, SOURCE_FILE_STRICT},
|
||||||
{'b', 0, "from-replica", &from_replica, SOURCE_FILE_STRICT},
|
{'b', 0, "from-replica", &backup->from_replica, SOURCE_FILE_STRICT},
|
||||||
{'s', 0, "primary-conninfo", &backup->primary_conninfo, SOURCE_FILE_STRICT},
|
{'s', 0, "primary-conninfo", &backup->primary_conninfo, SOURCE_FILE_STRICT},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
@ -578,6 +577,9 @@ readBackupControlFile(const char *path)
|
|||||||
pfree(server_version);
|
pfree(server_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (compress_alg)
|
||||||
|
backup->compress_alg = parse_compress_alg(compress_alg);
|
||||||
|
|
||||||
return backup;
|
return backup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,6 +628,48 @@ deparse_backup_mode(BackupMode mode)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompressAlg
|
||||||
|
parse_compress_alg(const char *arg)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
/* Skip all spaces detected */
|
||||||
|
while (isspace((unsigned char)*arg))
|
||||||
|
arg++;
|
||||||
|
len = strlen(arg);
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
elog(ERROR, "compress algrorithm is empty");
|
||||||
|
|
||||||
|
if (pg_strncasecmp("zlib", arg, len) == 0)
|
||||||
|
return ZLIB_COMPRESS;
|
||||||
|
else if (pg_strncasecmp("pglz", arg, len) == 0)
|
||||||
|
return PGLZ_COMPRESS;
|
||||||
|
else if (pg_strncasecmp("none", arg, len) == 0)
|
||||||
|
return NONE_COMPRESS;
|
||||||
|
else
|
||||||
|
elog(ERROR, "invalid compress algorithm value \"%s\"", arg);
|
||||||
|
|
||||||
|
return NOT_DEFINED_COMPRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*
|
||||||
|
deparse_compress_alg(int alg)
|
||||||
|
{
|
||||||
|
switch (alg)
|
||||||
|
{
|
||||||
|
case NONE_COMPRESS:
|
||||||
|
case NOT_DEFINED_COMPRESS:
|
||||||
|
return "none";
|
||||||
|
case ZLIB_COMPRESS:
|
||||||
|
return "zlib";
|
||||||
|
case PGLZ_COMPRESS:
|
||||||
|
return "pglz";
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* free pgBackup object */
|
/* free pgBackup object */
|
||||||
void
|
void
|
||||||
pgBackupFree(void *backup)
|
pgBackupFree(void *backup)
|
||||||
|
@ -128,6 +128,7 @@ help_pg_probackup(void)
|
|||||||
|
|
||||||
printf(_("\n %s show -B backup-dir\n"), PROGRAM_NAME);
|
printf(_("\n %s show -B backup-dir\n"), PROGRAM_NAME);
|
||||||
printf(_(" [--instance=instance_name [-i backup-id]]\n"));
|
printf(_(" [--instance=instance_name [-i backup-id]]\n"));
|
||||||
|
printf(_(" [--format=format]\n"));
|
||||||
|
|
||||||
printf(_("\n %s delete -B backup-dir --instance=instance_name\n"), PROGRAM_NAME);
|
printf(_("\n %s delete -B backup-dir --instance=instance_name\n"), PROGRAM_NAME);
|
||||||
printf(_(" [--wal] [-i backup-id | --expired]\n"));
|
printf(_(" [--wal] [-i backup-id | --expired]\n"));
|
||||||
@ -362,6 +363,7 @@ help_show(void)
|
|||||||
printf(_(" -B, --backup-path=backup-path location of the backup storage area\n"));
|
printf(_(" -B, --backup-path=backup-path location of the backup storage area\n"));
|
||||||
printf(_(" --instance=instance_name show info about specific intstance\n"));
|
printf(_(" --instance=instance_name show info about specific intstance\n"));
|
||||||
printf(_(" -i, --backup-id=backup-id show info about specific backups\n"));
|
printf(_(" -i, --backup-id=backup-id show info about specific backups\n"));
|
||||||
|
printf(_(" --format=format show format=PLAIN|JSON\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -47,7 +47,6 @@ char *replication_slot = NULL;
|
|||||||
/* backup options */
|
/* backup options */
|
||||||
bool backup_logs = false;
|
bool backup_logs = false;
|
||||||
bool smooth_checkpoint;
|
bool smooth_checkpoint;
|
||||||
bool from_replica = false;
|
|
||||||
bool is_remote_backup = false;
|
bool is_remote_backup = false;
|
||||||
/* Wait timeout for WAL segment archiving */
|
/* Wait timeout for WAL segment archiving */
|
||||||
uint32 archive_timeout = 300; /* default is 300 seconds */
|
uint32 archive_timeout = 300; /* default is 300 seconds */
|
||||||
@ -94,6 +93,9 @@ static char *wal_file_path;
|
|||||||
static char *wal_file_name;
|
static char *wal_file_name;
|
||||||
static bool file_overwrite = false;
|
static bool file_overwrite = false;
|
||||||
|
|
||||||
|
/* show options */
|
||||||
|
ShowFormat show_format = SHOW_PLAIN;
|
||||||
|
|
||||||
/* current settings */
|
/* current settings */
|
||||||
pgBackup current;
|
pgBackup current;
|
||||||
ProbackupSubcmd backup_subcmd;
|
ProbackupSubcmd backup_subcmd;
|
||||||
@ -104,6 +106,7 @@ static void opt_backup_mode(pgut_option *opt, const char *arg);
|
|||||||
static void opt_log_level_console(pgut_option *opt, const char *arg);
|
static void opt_log_level_console(pgut_option *opt, const char *arg);
|
||||||
static void opt_log_level_file(pgut_option *opt, const char *arg);
|
static void opt_log_level_file(pgut_option *opt, const char *arg);
|
||||||
static void opt_compress_alg(pgut_option *opt, const char *arg);
|
static void opt_compress_alg(pgut_option *opt, const char *arg);
|
||||||
|
static void opt_show_format(pgut_option *opt, const char *arg);
|
||||||
|
|
||||||
static void compress_init(void);
|
static void compress_init(void);
|
||||||
|
|
||||||
@ -178,6 +181,8 @@ static pgut_option options[] =
|
|||||||
{ 's', 160, "wal-file-path", &wal_file_path, SOURCE_CMDLINE },
|
{ 's', 160, "wal-file-path", &wal_file_path, SOURCE_CMDLINE },
|
||||||
{ 's', 161, "wal-file-name", &wal_file_name, SOURCE_CMDLINE },
|
{ 's', 161, "wal-file-name", &wal_file_name, SOURCE_CMDLINE },
|
||||||
{ 'b', 162, "overwrite", &file_overwrite, SOURCE_CMDLINE },
|
{ 'b', 162, "overwrite", &file_overwrite, SOURCE_CMDLINE },
|
||||||
|
/* show options */
|
||||||
|
{ 'f', 170, "format", opt_show_format, SOURCE_CMDLINE },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -517,49 +522,31 @@ opt_log_level_file(pgut_option *opt, const char *arg)
|
|||||||
log_level_file = parse_log_level(arg);
|
log_level_file = parse_log_level(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompressAlg
|
static void
|
||||||
parse_compress_alg(const char *arg)
|
opt_show_format(pgut_option *opt, const char *arg)
|
||||||
{
|
{
|
||||||
|
const char *v = arg;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
/* Skip all spaces detected */
|
/* Skip all spaces detected */
|
||||||
while (isspace((unsigned char)*arg))
|
while (IsSpace(*v))
|
||||||
arg++;
|
v++;
|
||||||
len = strlen(arg);
|
len = strlen(v);
|
||||||
|
|
||||||
if (len == 0)
|
if (len > 0)
|
||||||
elog(ERROR, "compress algrorithm is empty");
|
|
||||||
|
|
||||||
if (pg_strncasecmp("zlib", arg, len) == 0)
|
|
||||||
return ZLIB_COMPRESS;
|
|
||||||
else if (pg_strncasecmp("pglz", arg, len) == 0)
|
|
||||||
return PGLZ_COMPRESS;
|
|
||||||
else if (pg_strncasecmp("none", arg, len) == 0)
|
|
||||||
return NONE_COMPRESS;
|
|
||||||
else
|
|
||||||
elog(ERROR, "invalid compress algorithm value \"%s\"", arg);
|
|
||||||
|
|
||||||
return NOT_DEFINED_COMPRESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char*
|
|
||||||
deparse_compress_alg(int alg)
|
|
||||||
{
|
|
||||||
switch (alg)
|
|
||||||
{
|
{
|
||||||
case NONE_COMPRESS:
|
if (pg_strncasecmp("plain", v, len) == 0)
|
||||||
case NOT_DEFINED_COMPRESS:
|
show_format = SHOW_PLAIN;
|
||||||
return "none";
|
else if (pg_strncasecmp("json", v, len) == 0)
|
||||||
case ZLIB_COMPRESS:
|
show_format = SHOW_JSON;
|
||||||
return "zlib";
|
else
|
||||||
case PGLZ_COMPRESS:
|
elog(ERROR, "Invalid show format \"%s\"", arg);
|
||||||
return "pglz";
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return NULL;
|
elog(ERROR, "Invalid show format \"%s\"", arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
opt_compress_alg(pgut_option *opt, const char *arg)
|
opt_compress_alg(pgut_option *opt, const char *arg)
|
||||||
{
|
{
|
||||||
compress_alg = parse_compress_alg(arg);
|
compress_alg = parse_compress_alg(arg);
|
||||||
@ -568,8 +555,8 @@ opt_compress_alg(pgut_option *opt, const char *arg)
|
|||||||
/*
|
/*
|
||||||
* Initialize compress and sanity checks for compress.
|
* Initialize compress and sanity checks for compress.
|
||||||
*/
|
*/
|
||||||
static
|
static void
|
||||||
void compress_init(void)
|
compress_init(void)
|
||||||
{
|
{
|
||||||
/* Default algorithm is zlib */
|
/* Default algorithm is zlib */
|
||||||
if (compress_shortcut)
|
if (compress_shortcut)
|
||||||
|
@ -149,6 +149,12 @@ typedef enum ProbackupSubcmd
|
|||||||
SHOW_CONFIG
|
SHOW_CONFIG
|
||||||
} ProbackupSubcmd;
|
} ProbackupSubcmd;
|
||||||
|
|
||||||
|
typedef enum ShowFormat
|
||||||
|
{
|
||||||
|
SHOW_PLAIN,
|
||||||
|
SHOW_JSON
|
||||||
|
} ShowFormat;
|
||||||
|
|
||||||
|
|
||||||
/* special values of pgBackup fields */
|
/* special values of pgBackup fields */
|
||||||
#define INVALID_BACKUP_ID 0 /* backup ID is not provided by user */
|
#define INVALID_BACKUP_ID 0 /* backup ID is not provided by user */
|
||||||
@ -214,6 +220,9 @@ typedef struct pgBackup
|
|||||||
/* Size of WAL files in archive needed to restore this backup */
|
/* Size of WAL files in archive needed to restore this backup */
|
||||||
int64 wal_bytes;
|
int64 wal_bytes;
|
||||||
|
|
||||||
|
CompressAlg compress_alg;
|
||||||
|
int compress_level;
|
||||||
|
|
||||||
/* Fields needed for compatibility check */
|
/* Fields needed for compatibility check */
|
||||||
uint32 block_size;
|
uint32 block_size;
|
||||||
uint32 wal_block_size;
|
uint32 wal_block_size;
|
||||||
@ -223,6 +232,7 @@ typedef struct pgBackup
|
|||||||
|
|
||||||
bool stream; /* Was this backup taken in stream mode?
|
bool stream; /* Was this backup taken in stream mode?
|
||||||
* i.e. does it include all needed WAL files? */
|
* i.e. does it include all needed WAL files? */
|
||||||
|
bool from_replica; /* Was this backup taken from replica */
|
||||||
time_t parent_backup; /* Identifier of the previous backup.
|
time_t parent_backup; /* Identifier of the previous backup.
|
||||||
* Which is basic backup for this
|
* Which is basic backup for this
|
||||||
* incremental backup. */
|
* incremental backup. */
|
||||||
@ -310,7 +320,6 @@ extern char *replication_slot;
|
|||||||
/* backup options */
|
/* backup options */
|
||||||
extern bool smooth_checkpoint;
|
extern bool smooth_checkpoint;
|
||||||
extern uint32 archive_timeout;
|
extern uint32 archive_timeout;
|
||||||
extern bool from_replica;
|
|
||||||
extern bool is_remote_backup;
|
extern bool is_remote_backup;
|
||||||
extern const char *master_db;
|
extern const char *master_db;
|
||||||
extern const char *master_host;
|
extern const char *master_host;
|
||||||
@ -348,6 +357,9 @@ extern const char* deparse_compress_alg(int alg);
|
|||||||
extern char *instance_name;
|
extern char *instance_name;
|
||||||
extern uint64 system_identifier;
|
extern uint64 system_identifier;
|
||||||
|
|
||||||
|
/* show options */
|
||||||
|
extern ShowFormat show_format;
|
||||||
|
|
||||||
/* current settings */
|
/* current settings */
|
||||||
extern pgBackup current;
|
extern pgBackup current;
|
||||||
extern ProbackupSubcmd backup_subcmd;
|
extern ProbackupSubcmd backup_subcmd;
|
||||||
|
462
src/show.c
462
src/show.c
@ -3,28 +3,38 @@
|
|||||||
* show.c: show backup information.
|
* show.c: show backup information.
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 2009-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
* Portions Copyright (c) 2009-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||||
* Portions Copyright (c) 2015-2017, Postgres Professional
|
* Portions Copyright (c) 2015-2018, Postgres Professional
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pg_probackup.h"
|
#include "pg_probackup.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "pqexpbuffer.h"
|
||||||
|
|
||||||
static void show_backup_list(FILE *out, parray *backup_list);
|
|
||||||
static void show_backup_detail(FILE *out, pgBackup *backup);
|
static void show_instance_start(void);
|
||||||
static int do_show_instance(time_t requested_backup_id);
|
static void show_instance_end(void);
|
||||||
|
static void show_instance(time_t requested_backup_id, bool show_name);
|
||||||
|
static int show_backup(time_t requested_backup_id);
|
||||||
|
|
||||||
|
static void show_instance_plain(parray *backup_list, bool show_name);
|
||||||
|
static void show_instance_json(parray *backup_list);
|
||||||
|
|
||||||
|
static PQExpBufferData show_buf;
|
||||||
|
static bool first_instance = true;
|
||||||
|
static uint8 json_level = 0;
|
||||||
|
|
||||||
int
|
int
|
||||||
do_show(time_t requested_backup_id)
|
do_show(time_t requested_backup_id)
|
||||||
{
|
{
|
||||||
|
if (instance_name == NULL &&
|
||||||
if (instance_name == NULL
|
requested_backup_id != INVALID_BACKUP_ID)
|
||||||
&& requested_backup_id != INVALID_BACKUP_ID)
|
|
||||||
elog(ERROR, "You must specify --instance to use --backup_id option");
|
elog(ERROR, "You must specify --instance to use --backup_id option");
|
||||||
|
|
||||||
if (instance_name == NULL)
|
if (instance_name == NULL)
|
||||||
@ -38,10 +48,12 @@ do_show(time_t requested_backup_id)
|
|||||||
join_path_components(path, backup_path, BACKUPS_DIR);
|
join_path_components(path, backup_path, BACKUPS_DIR);
|
||||||
dir = opendir(path);
|
dir = opendir(path);
|
||||||
if (dir == NULL)
|
if (dir == NULL)
|
||||||
elog(ERROR, "cannot open directory \"%s\": %s", path, strerror(errno));
|
elog(ERROR, "Cannot open directory \"%s\": %s",
|
||||||
|
path, strerror(errno));
|
||||||
|
|
||||||
errno = 0;
|
show_instance_start();
|
||||||
while ((dent = readdir(dir)))
|
|
||||||
|
while (errno = 0, (dent = readdir(dir)) != NULL)
|
||||||
{
|
{
|
||||||
char child[MAXPGPATH];
|
char child[MAXPGPATH];
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@ -54,67 +66,41 @@ do_show(time_t requested_backup_id)
|
|||||||
join_path_components(child, path, dent->d_name);
|
join_path_components(child, path, dent->d_name);
|
||||||
|
|
||||||
if (lstat(child, &st) == -1)
|
if (lstat(child, &st) == -1)
|
||||||
elog(ERROR, "cannot stat file \"%s\": %s", child, strerror(errno));
|
elog(ERROR, "Cannot stat file \"%s\": %s",
|
||||||
|
child, strerror(errno));
|
||||||
|
|
||||||
if (!S_ISDIR(st.st_mode))
|
if (!S_ISDIR(st.st_mode))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
instance_name = dent->d_name;
|
instance_name = dent->d_name;
|
||||||
sprintf(backup_instance_path, "%s/%s/%s", backup_path, BACKUPS_DIR, instance_name);
|
sprintf(backup_instance_path, "%s/%s/%s", backup_path, BACKUPS_DIR, instance_name);
|
||||||
fprintf(stdout, "\nBACKUP INSTANCE '%s'\n", instance_name);
|
|
||||||
do_show_instance(0);
|
show_instance(INVALID_BACKUP_ID, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (errno)
|
||||||
|
elog(ERROR, "Cannot read directory \"%s\": %s",
|
||||||
|
path, strerror(errno));
|
||||||
|
|
||||||
|
if (closedir(dir))
|
||||||
|
elog(ERROR, "Cannot close directory \"%s\": %s",
|
||||||
|
path, strerror(errno));
|
||||||
|
|
||||||
|
show_instance_end();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (requested_backup_id == INVALID_BACKUP_ID ||
|
||||||
|
show_format == SHOW_JSON)
|
||||||
|
{
|
||||||
|
show_instance_start();
|
||||||
|
show_instance(requested_backup_id, false);
|
||||||
|
show_instance_end();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return do_show_instance(requested_backup_id);
|
return show_backup(requested_backup_id);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If 'requested_backup_id' is INVALID_BACKUP_ID, show brief meta information
|
|
||||||
* about all backups in the backup instance.
|
|
||||||
* If valid backup id is passed, show detailed meta information
|
|
||||||
* about specified backup.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
do_show_instance(time_t requested_backup_id)
|
|
||||||
{
|
|
||||||
if (requested_backup_id != INVALID_BACKUP_ID)
|
|
||||||
{
|
|
||||||
pgBackup *backup;
|
|
||||||
|
|
||||||
backup = read_backup(requested_backup_id);
|
|
||||||
if (backup == NULL)
|
|
||||||
{
|
|
||||||
elog(INFO, "Requested backup \"%s\" is not found.",
|
|
||||||
/* We do not need free base36enc's result, we exit anyway */
|
|
||||||
base36enc(requested_backup_id));
|
|
||||||
/* This is not error */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
show_backup_detail(stdout, backup);
|
|
||||||
|
|
||||||
/* cleanup */
|
|
||||||
pgBackupFree(backup);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
parray *backup_list;
|
|
||||||
|
|
||||||
backup_list = catalog_get_backup_list(INVALID_BACKUP_ID);
|
|
||||||
if (backup_list == NULL)
|
|
||||||
elog(ERROR, "Failed to get backup list.");
|
|
||||||
|
|
||||||
show_backup_list(stdout, backup_list);
|
|
||||||
|
|
||||||
/* cleanup */
|
|
||||||
parray_walk(backup_list, pgBackupFree);
|
|
||||||
parray_free(backup_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -219,16 +205,113 @@ get_parent_tli(TimeLineID child_tli)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize instance visualization.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
show_backup_list(FILE *out, parray *backup_list)
|
show_instance_start(void)
|
||||||
|
{
|
||||||
|
initPQExpBuffer(&show_buf);
|
||||||
|
|
||||||
|
if (show_format == SHOW_PLAIN)
|
||||||
|
return;
|
||||||
|
|
||||||
|
first_instance = true;
|
||||||
|
json_level = 0;
|
||||||
|
|
||||||
|
appendPQExpBufferChar(&show_buf, '[');
|
||||||
|
json_level++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Finalize instance visualization.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
show_instance_end(void)
|
||||||
|
{
|
||||||
|
if (show_format == SHOW_JSON)
|
||||||
|
appendPQExpBufferStr(&show_buf, "\n]\n");
|
||||||
|
|
||||||
|
fputs(show_buf.data, stdout);
|
||||||
|
termPQExpBuffer(&show_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show brief meta information about all backups in the backup instance.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
show_instance(time_t requested_backup_id, bool show_name)
|
||||||
|
{
|
||||||
|
parray *backup_list;
|
||||||
|
|
||||||
|
backup_list = catalog_get_backup_list(requested_backup_id);
|
||||||
|
if (backup_list == NULL)
|
||||||
|
elog(ERROR, "Failed to get backup list.");
|
||||||
|
|
||||||
|
if (show_format == SHOW_PLAIN)
|
||||||
|
show_instance_plain(backup_list, show_name);
|
||||||
|
else if (show_format == SHOW_JSON)
|
||||||
|
show_instance_json(backup_list);
|
||||||
|
else
|
||||||
|
elog(ERROR, "Invalid show format %d", (int) show_format);
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
parray_walk(backup_list, pgBackupFree);
|
||||||
|
parray_free(backup_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show detailed meta information about specified backup.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
show_backup(time_t requested_backup_id)
|
||||||
|
{
|
||||||
|
pgBackup *backup;
|
||||||
|
|
||||||
|
backup = read_backup(requested_backup_id);
|
||||||
|
if (backup == NULL)
|
||||||
|
{
|
||||||
|
elog(INFO, "Requested backup \"%s\" is not found.",
|
||||||
|
/* We do not need free base36enc's result, we exit anyway */
|
||||||
|
base36enc(requested_backup_id));
|
||||||
|
/* This is not error */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (show_format == SHOW_PLAIN)
|
||||||
|
pgBackupWriteControl(stdout, backup);
|
||||||
|
else
|
||||||
|
elog(ERROR, "Invalid show format %d", (int) show_format);
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
pgBackupFree(backup);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Plain output.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show instance backups in plain format.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
show_instance_plain(parray *backup_list, bool show_name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (show_name)
|
||||||
|
printfPQExpBuffer(&show_buf, "\nBACKUP INSTANCE '%s'\n", instance_name);
|
||||||
|
|
||||||
/* if you add new fields here, fix the header */
|
/* if you add new fields here, fix the header */
|
||||||
/* show header */
|
/* show header */
|
||||||
fputs("============================================================================================================================================\n", out);
|
appendPQExpBufferStr(&show_buf,
|
||||||
fputs(" Instance Version ID Recovery time Mode WAL Current/Parent TLI Time Data Start LSN Stop LSN Status \n", out);
|
"============================================================================================================================================\n");
|
||||||
fputs("============================================================================================================================================\n", out);
|
appendPQExpBufferStr(&show_buf,
|
||||||
|
" Instance Version ID Recovery time Mode WAL Current/Parent TLI Time Data Start LSN Stop LSN Status \n");
|
||||||
|
appendPQExpBufferStr(&show_buf,
|
||||||
|
"============================================================================================================================================\n");
|
||||||
|
|
||||||
for (i = 0; i < parray_num(backup_list); i++)
|
for (i = 0; i < parray_num(backup_list); i++)
|
||||||
{
|
{
|
||||||
@ -255,7 +338,8 @@ show_backup_list(FILE *out, parray *backup_list)
|
|||||||
/* Get parent timeline before printing */
|
/* Get parent timeline before printing */
|
||||||
parent_tli = get_parent_tli(backup->tli);
|
parent_tli = get_parent_tli(backup->tli);
|
||||||
|
|
||||||
fprintf(out, " %-11s %-8s %-6s %-22s %-6s %-7s %3d / %-3d %5s %6s %2X/%-8X %2X/%-8X %-8s\n",
|
appendPQExpBuffer(&show_buf,
|
||||||
|
" %-11s %-8s %-6s %-22s %-6s %-7s %3d / %-3d %5s %6s %2X/%-8X %2X/%-8X %-8s\n",
|
||||||
instance_name,
|
instance_name,
|
||||||
(backup->server_version[0] ? backup->server_version : "----"),
|
(backup->server_version[0] ? backup->server_version : "----"),
|
||||||
base36enc(backup->start_time),
|
base36enc(backup->start_time),
|
||||||
@ -274,8 +358,250 @@ show_backup_list(FILE *out, parray *backup_list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Json output.
|
||||||
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
show_backup_detail(FILE *out, pgBackup *backup)
|
json_add_indent(PQExpBuffer buf)
|
||||||
{
|
{
|
||||||
pgBackupWriteControl(out, backup);
|
uint8 i;
|
||||||
|
|
||||||
|
if (json_level == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
appendPQExpBufferChar(buf, '\n');
|
||||||
|
for (i = 0; i < json_level; i++)
|
||||||
|
appendPQExpBufferStr(buf, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
JT_BEGIN_ARRAY,
|
||||||
|
JT_END_ARRAY,
|
||||||
|
JT_BEGIN_OBJECT,
|
||||||
|
JT_END_OBJECT
|
||||||
|
} JsonToken;
|
||||||
|
|
||||||
|
static void
|
||||||
|
json_add(PQExpBuffer buf, JsonToken type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case JT_BEGIN_ARRAY:
|
||||||
|
appendPQExpBufferChar(buf, '[');
|
||||||
|
json_level++;
|
||||||
|
break;
|
||||||
|
case JT_END_ARRAY:
|
||||||
|
json_level--;
|
||||||
|
if (json_level == 0)
|
||||||
|
appendPQExpBufferChar(buf, '\n');
|
||||||
|
else
|
||||||
|
json_add_indent(buf);
|
||||||
|
appendPQExpBufferChar(buf, ']');
|
||||||
|
break;
|
||||||
|
case JT_BEGIN_OBJECT:
|
||||||
|
json_add_indent(buf);
|
||||||
|
appendPQExpBufferChar(buf, '{');
|
||||||
|
json_level++;
|
||||||
|
break;
|
||||||
|
case JT_END_OBJECT:
|
||||||
|
json_level--;
|
||||||
|
if (json_level == 0)
|
||||||
|
appendPQExpBufferChar(buf, '\n');
|
||||||
|
else
|
||||||
|
json_add_indent(buf);
|
||||||
|
appendPQExpBufferChar(buf, '}');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
json_add_escaped(PQExpBuffer buf, const char *str)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
appendPQExpBufferChar(buf, '"');
|
||||||
|
for (p = str; *p; p++)
|
||||||
|
{
|
||||||
|
switch (*p)
|
||||||
|
{
|
||||||
|
case '\b':
|
||||||
|
appendPQExpBufferStr(buf, "\\b");
|
||||||
|
break;
|
||||||
|
case '\f':
|
||||||
|
appendPQExpBufferStr(buf, "\\f");
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
appendPQExpBufferStr(buf, "\\n");
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
appendPQExpBufferStr(buf, "\\r");
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
appendPQExpBufferStr(buf, "\\t");
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
appendPQExpBufferStr(buf, "\\\"");
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
appendPQExpBufferStr(buf, "\\\\");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((unsigned char) *p < ' ')
|
||||||
|
appendPQExpBuffer(buf, "\\u%04x", (int) *p);
|
||||||
|
else
|
||||||
|
appendPQExpBufferChar(buf, *p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appendPQExpBufferChar(buf, '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
json_add_key(PQExpBuffer buf, const char *name, bool add_comma)
|
||||||
|
{
|
||||||
|
if (add_comma)
|
||||||
|
appendPQExpBufferChar(buf, ',');
|
||||||
|
json_add_indent(buf);
|
||||||
|
|
||||||
|
json_add_escaped(buf, name);
|
||||||
|
appendPQExpBufferStr(buf, ": ");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
json_add_value(PQExpBuffer buf, const char *name, const char *value,
|
||||||
|
bool add_comma)
|
||||||
|
{
|
||||||
|
json_add_key(buf, name, add_comma);
|
||||||
|
json_add_escaped(buf, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show instance backups in json format.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
show_instance_json(parray *backup_list)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
PQExpBuffer buf = &show_buf;
|
||||||
|
|
||||||
|
if (!first_instance)
|
||||||
|
appendPQExpBufferChar(buf, ',');
|
||||||
|
|
||||||
|
/* Begin of instance object */
|
||||||
|
json_add(buf, JT_BEGIN_OBJECT);
|
||||||
|
|
||||||
|
json_add_value(buf, "instance-name", instance_name, false);
|
||||||
|
|
||||||
|
json_add_key(buf, "backups", true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List backups.
|
||||||
|
*/
|
||||||
|
json_add(buf, JT_BEGIN_ARRAY);
|
||||||
|
|
||||||
|
for (i = 0; i < parray_num(backup_list); i++)
|
||||||
|
{
|
||||||
|
pgBackup *backup = parray_get(backup_list, i);
|
||||||
|
TimeLineID parent_tli;
|
||||||
|
char timestamp[100] = "----";
|
||||||
|
char duration[20] = "----";
|
||||||
|
char data_bytes_str[10] = "----";
|
||||||
|
char lsn[20];
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
appendPQExpBufferChar(buf, ',');
|
||||||
|
|
||||||
|
json_add(buf, JT_BEGIN_OBJECT);
|
||||||
|
|
||||||
|
json_add_value(buf, "id", base36enc(backup->start_time), true);
|
||||||
|
|
||||||
|
if (backup->parent_backup != 0)
|
||||||
|
json_add_value(buf, "parent-backup-id",
|
||||||
|
base36enc(backup->parent_backup), true);
|
||||||
|
|
||||||
|
json_add_value(buf, "backup-mode", pgBackupGetBackupMode(backup), false);
|
||||||
|
|
||||||
|
json_add_value(buf, "wal", backup->stream ? "STREAM": "ARCHIVE", true);
|
||||||
|
|
||||||
|
json_add_value(buf, "compress-alg",
|
||||||
|
deparse_compress_alg(backup->compress_alg), true);
|
||||||
|
|
||||||
|
json_add_key(buf, "compress-level", true);
|
||||||
|
appendPQExpBuffer(buf, "%d", backup->compress_level);
|
||||||
|
|
||||||
|
json_add_value(buf, "from-replica",
|
||||||
|
backup->from_replica ? "true" : "false", true);
|
||||||
|
|
||||||
|
json_add_key(buf, "block-size", true);
|
||||||
|
appendPQExpBuffer(buf, "%u", backup->block_size);
|
||||||
|
|
||||||
|
json_add_key(buf, "xlog-block-size", true);
|
||||||
|
appendPQExpBuffer(buf, "%u", backup->wal_block_size);
|
||||||
|
|
||||||
|
json_add_key(buf, "checksum-version", true);
|
||||||
|
appendPQExpBuffer(buf, "%u", backup->checksum_version);
|
||||||
|
|
||||||
|
json_add_value(buf, "server-version", backup->server_version, true);
|
||||||
|
|
||||||
|
json_add_key(buf, "current-tli", true);
|
||||||
|
appendPQExpBuffer(buf, "%d", backup->tli);
|
||||||
|
|
||||||
|
json_add_key(buf, "parent-tli", true);
|
||||||
|
parent_tli = get_parent_tli(backup->tli);
|
||||||
|
appendPQExpBuffer(buf, "%u", parent_tli);
|
||||||
|
|
||||||
|
snprintf(lsn, lengthof(lsn), "%X/%X",
|
||||||
|
(uint32) (backup->start_lsn >> 32), (uint32) backup->start_lsn);
|
||||||
|
json_add_value(buf, "start-lsn", lsn, true);
|
||||||
|
|
||||||
|
snprintf(lsn, lengthof(lsn), "%X/%X",
|
||||||
|
(uint32) (backup->stop_lsn >> 32), (uint32) backup->stop_lsn);
|
||||||
|
json_add_value(buf, "stop-lsn", lsn, true);
|
||||||
|
|
||||||
|
time2iso(timestamp, lengthof(timestamp), backup->start_time);
|
||||||
|
json_add_value(buf, "start-time", timestamp, true);
|
||||||
|
|
||||||
|
time2iso(timestamp, lengthof(timestamp), backup->end_time);
|
||||||
|
json_add_value(buf, "end-time", timestamp, true);
|
||||||
|
|
||||||
|
json_add_key(buf, "recovery-xid", true);
|
||||||
|
appendPQExpBuffer(buf, XID_FMT, backup->recovery_xid);
|
||||||
|
|
||||||
|
time2iso(timestamp, lengthof(timestamp), backup->recovery_time);
|
||||||
|
json_add_value(buf, "recovery-time", timestamp, true);
|
||||||
|
|
||||||
|
pretty_size(backup->data_bytes, data_bytes_str,
|
||||||
|
lengthof(data_bytes_str));
|
||||||
|
json_add_value(buf, "data-bytes", data_bytes_str, true);
|
||||||
|
|
||||||
|
pretty_size(backup->wal_bytes, data_bytes_str,
|
||||||
|
lengthof(data_bytes_str));
|
||||||
|
json_add_value(buf, "wal-bytes", data_bytes_str, true);
|
||||||
|
|
||||||
|
if (backup->end_time != (time_t) 0)
|
||||||
|
{
|
||||||
|
snprintf(duration, lengthof(duration), "%.*lfs", 0,
|
||||||
|
difftime(backup->end_time, backup->start_time));
|
||||||
|
json_add_value(buf, "time", duration, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backup->primary_conninfo)
|
||||||
|
json_add_value(buf, "primary_conninfo", backup->primary_conninfo, true);
|
||||||
|
|
||||||
|
json_add_value(buf, "status", status2str(backup->status), true);
|
||||||
|
|
||||||
|
json_add(buf, JT_END_OBJECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End of backups */
|
||||||
|
json_add(buf, JT_END_ARRAY);
|
||||||
|
|
||||||
|
/* End of instance object */
|
||||||
|
json_add(buf, JT_END_OBJECT);
|
||||||
|
|
||||||
|
first_instance = false;
|
||||||
}
|
}
|
||||||
|
@ -310,10 +310,19 @@ pgBackup_init(pgBackup *backup)
|
|||||||
backup->end_time = (time_t) 0;
|
backup->end_time = (time_t) 0;
|
||||||
backup->recovery_xid = 0;
|
backup->recovery_xid = 0;
|
||||||
backup->recovery_time = (time_t) 0;
|
backup->recovery_time = (time_t) 0;
|
||||||
|
|
||||||
backup->data_bytes = BYTES_INVALID;
|
backup->data_bytes = BYTES_INVALID;
|
||||||
|
backup->wal_bytes = BYTES_INVALID;
|
||||||
|
|
||||||
|
backup->compress_alg = NOT_DEFINED_COMPRESS;
|
||||||
|
backup->compress_level = 0;
|
||||||
|
|
||||||
backup->block_size = BLCKSZ;
|
backup->block_size = BLCKSZ;
|
||||||
backup->wal_block_size = XLOG_BLCKSZ;
|
backup->wal_block_size = XLOG_BLCKSZ;
|
||||||
|
backup->checksum_version = 0;
|
||||||
|
|
||||||
backup->stream = false;
|
backup->stream = false;
|
||||||
|
backup->from_replica = false;
|
||||||
backup->parent_backup = 0;
|
backup->parent_backup = 0;
|
||||||
backup->primary_conninfo = NULL;
|
backup->primary_conninfo = NULL;
|
||||||
backup->server_version[0] = '\0';
|
backup->server_version[0] = '\0';
|
||||||
|
@ -59,7 +59,7 @@ typedef enum pgut_optsrc
|
|||||||
typedef struct pgut_option
|
typedef struct pgut_option
|
||||||
{
|
{
|
||||||
char type;
|
char type;
|
||||||
char sname; /* short name */
|
uint8 sname; /* short name */
|
||||||
const char *lname; /* long name */
|
const char *lname; /* long name */
|
||||||
void *var; /* pointer to variable */
|
void *var; /* pointer to variable */
|
||||||
pgut_optsrc allowed; /* allowed source */
|
pgut_optsrc allowed; /* allowed source */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user