1
0
mirror of https://github.com/postgrespro/pg_probackup.git synced 2024-11-24 08:52:38 +02:00

Implement remote backup though SSH

This commit is contained in:
Konstantin Knizhnik 2018-11-02 20:24:09 +03:00
parent bf1c8797ae
commit 050d0150d0
11 changed files with 162 additions and 138 deletions

View File

@ -2,7 +2,7 @@ PROGRAM = pg_probackup
# utils
OBJS = src/utils/json.o src/utils/logger.o src/utils/parray.o \
src/utils/pgut.o src/utils/thread.o
src/utils/pgut.o src/utils/thread.o src/utils/remote.o src/utils/file.o
OBJS += src/archive.o src/backup.o src/catalog.o src/configure.o src/data.o \
src/delete.o src/dir.o src/fetch.o src/help.o src/init.o src/merge.o \

View File

@ -22,6 +22,7 @@
#include <unistd.h>
#include "utils/thread.h"
#include "utils/file.h"
#define PG_STOP_BACKUP_TIMEOUT 300
@ -572,7 +573,7 @@ do_backup_instance(void)
if (stream_wal)
{
join_path_components(dst_backup_path, database_path, PG_XLOG_DIR);
dir_create_dir(dst_backup_path, DIR_PERMISSION);
fio_mkdir(dst_backup_path, DIR_PERMISSION, FIO_BACKUP_HOST);
stream_thread_arg.basedir = dst_backup_path;
@ -689,7 +690,7 @@ do_backup_instance(void)
DATABASE_DIR);
join_path_components(dirpath, database_path, dir_name);
dir_create_dir(dirpath, DIR_PERMISSION);
fio_mkdir(dirpath, DIR_PERMISSION, FIO_BACKUP_HOST);
}
/* setup threads */
@ -1847,16 +1848,15 @@ pg_stop_backup(pgBackup *backup)
/* Write backup_label */
join_path_components(backup_label, path, PG_BACKUP_LABEL_FILE);
fp = fopen(backup_label, PG_BINARY_W);
fp = fio_open(backup_label, PG_BINARY_W, FIO_BACKUP_HOST);
if (fp == NULL)
elog(ERROR, "can't open backup label file \"%s\": %s",
backup_label, strerror(errno));
len = strlen(PQgetvalue(res, 0, 3));
if (fwrite(PQgetvalue(res, 0, 3), 1, len, fp) != len ||
fflush(fp) != 0 ||
fsync(fileno(fp)) != 0 ||
fclose(fp))
if (fio_write(fp, PQgetvalue(res, 0, 3), len) != len ||
fio_flush(fp) != 0 ||
fio_close(fp))
elog(ERROR, "can't write backup label file \"%s\": %s",
backup_label, strerror(errno));
@ -1895,16 +1895,15 @@ pg_stop_backup(pgBackup *backup)
char tablespace_map[MAXPGPATH];
join_path_components(tablespace_map, path, PG_TABLESPACE_MAP_FILE);
fp = fopen(tablespace_map, PG_BINARY_W);
fp = fio_open(tablespace_map, PG_BINARY_W, FIO_BACKUP_HOST);
if (fp == NULL)
elog(ERROR, "can't open tablespace map file \"%s\": %s",
tablespace_map, strerror(errno));
len = strlen(val);
if (fwrite(val, 1, len, fp) != len ||
fflush(fp) != 0 ||
fsync(fileno(fp)) != 0 ||
fclose(fp))
if (fio_write(fp, val, len) != len ||
fio_flush(fp) != 0 ||
fio_close(fp))
elog(ERROR, "can't write tablespace map file \"%s\": %s",
tablespace_map, strerror(errno));

View File

@ -8,13 +8,14 @@
*-------------------------------------------------------------------------
*/
#include "pg_probackup.h"
#include <dirent.h>
#include <signal.h>
#include <sys/stat.h>
#include <unistd.h>
#include "pg_probackup.h"
#include "utils/file.h"
static const char *backupModes[] = {"", "PAGE", "PTRACK", "DELTA", "FULL"};
static pgBackup *readBackupControlFile(const char *path);
@ -413,13 +414,13 @@ pgBackupCreateDir(pgBackup *backup)
if (!dir_is_empty(path))
elog(ERROR, "backup destination is not empty \"%s\"", path);
dir_create_dir(path, DIR_PERMISSION);
fio_mkdir(path, DIR_PERMISSION, FIO_BACKUP_HOST);
/* create directories for actual backup files */
for (i = 0; subdirs[i]; i++)
{
pgBackupGetPath(backup, path, lengthof(path), subdirs[i]);
dir_create_dir(path, DIR_PERMISSION);
fio_mkdir(path, DIR_PERMISSION, FIO_BACKUP_HOST);
}
return 0;
@ -433,46 +434,46 @@ pgBackupWriteControl(FILE *out, pgBackup *backup)
{
char timestamp[100];
fprintf(out, "#Configuration\n");
fprintf(out, "backup-mode = %s\n", pgBackupGetBackupMode(backup));
fprintf(out, "stream = %s\n", backup->stream ? "true" : "false");
fprintf(out, "compress-alg = %s\n",
fio_printf(out, "#Configuration\n");
fio_printf(out, "backup-mode = %s\n", pgBackupGetBackupMode(backup));
fio_printf(out, "stream = %s\n", backup->stream ? "true" : "false");
fio_printf(out, "compress-alg = %s\n",
deparse_compress_alg(backup->compress_alg));
fprintf(out, "compress-level = %d\n", backup->compress_level);
fprintf(out, "from-replica = %s\n", backup->from_replica ? "true" : "false");
fio_printf(out, "compress-level = %d\n", backup->compress_level);
fio_printf(out, "from-replica = %s\n", backup->from_replica ? "true" : "false");
fprintf(out, "\n#Compatibility\n");
fprintf(out, "block-size = %u\n", backup->block_size);
fprintf(out, "xlog-block-size = %u\n", backup->wal_block_size);
fprintf(out, "checksum-version = %u\n", backup->checksum_version);
fio_printf(out, "\n#Compatibility\n");
fio_printf(out, "block-size = %u\n", backup->block_size);
fio_printf(out, "xlog-block-size = %u\n", backup->wal_block_size);
fio_printf(out, "checksum-version = %u\n", backup->checksum_version);
if (backup->program_version[0] != '\0')
fprintf(out, "program-version = %s\n", backup->program_version);
fio_printf(out, "program-version = %s\n", backup->program_version);
if (backup->server_version[0] != '\0')
fprintf(out, "server-version = %s\n", backup->server_version);
fio_printf(out, "server-version = %s\n", backup->server_version);
fprintf(out, "\n#Result backup info\n");
fprintf(out, "timelineid = %d\n", backup->tli);
fio_printf(out, "\n#Result backup info\n");
fio_printf(out, "timelineid = %d\n", backup->tli);
/* LSN returned by pg_start_backup */
fprintf(out, "start-lsn = %X/%X\n",
fio_printf(out, "start-lsn = %X/%X\n",
(uint32) (backup->start_lsn >> 32),
(uint32) backup->start_lsn);
/* LSN returned by pg_stop_backup */
fprintf(out, "stop-lsn = %X/%X\n",
fio_printf(out, "stop-lsn = %X/%X\n",
(uint32) (backup->stop_lsn >> 32),
(uint32) backup->stop_lsn);
time2iso(timestamp, lengthof(timestamp), backup->start_time);
fprintf(out, "start-time = '%s'\n", timestamp);
fio_printf(out, "start-time = '%s'\n", timestamp);
if (backup->end_time > 0)
{
time2iso(timestamp, lengthof(timestamp), backup->end_time);
fprintf(out, "end-time = '%s'\n", timestamp);
fio_printf(out, "end-time = '%s'\n", timestamp);
}
fprintf(out, "recovery-xid = " XID_FMT "\n", backup->recovery_xid);
fio_printf(out, "recovery-xid = " XID_FMT "\n", backup->recovery_xid);
if (backup->recovery_time > 0)
{
time2iso(timestamp, lengthof(timestamp), backup->recovery_time);
fprintf(out, "recovery-time = '%s'\n", timestamp);
fio_printf(out, "recovery-time = '%s'\n", timestamp);
}
/*
@ -480,20 +481,20 @@ pgBackupWriteControl(FILE *out, pgBackup *backup)
* WAL segments in archive 'wal' directory.
*/
if (backup->data_bytes != BYTES_INVALID)
fprintf(out, "data-bytes = " INT64_FORMAT "\n", backup->data_bytes);
fio_printf(out, "data-bytes = " INT64_FORMAT "\n", backup->data_bytes);
if (backup->wal_bytes != BYTES_INVALID)
fprintf(out, "wal-bytes = " INT64_FORMAT "\n", backup->wal_bytes);
fio_printf(out, "wal-bytes = " INT64_FORMAT "\n", backup->wal_bytes);
fprintf(out, "status = %s\n", status2str(backup->status));
fio_printf(out, "status = %s\n", status2str(backup->status));
/* 'parent_backup' is set if it is incremental backup */
if (backup->parent_backup != 0)
fprintf(out, "parent-backup-id = '%s'\n", base36enc(backup->parent_backup));
fio_printf(out, "parent-backup-id = '%s'\n", base36enc(backup->parent_backup));
/* print connection info except password */
if (backup->primary_conninfo)
fprintf(out, "primary_conninfo = '%s'\n", backup->primary_conninfo);
fio_printf(out, "primary_conninfo = '%s'\n", backup->primary_conninfo);
}
/*
@ -506,14 +507,14 @@ write_backup(pgBackup *backup)
char conf_path[MAXPGPATH];
pgBackupGetPath(backup, conf_path, lengthof(conf_path), BACKUP_CONTROL_FILE);
fp = fopen(conf_path, "wt");
fp = fio_open(conf_path, PG_BINARY_W, FIO_BACKUP_HOST);
if (fp == NULL)
elog(ERROR, "Cannot open configuration file \"%s\": %s", conf_path,
strerror(errno));
pgBackupWriteControl(fp, backup);
fclose(fp);
fio_close(fp);
}
/*
@ -527,16 +528,15 @@ pgBackupWriteFileList(pgBackup *backup, parray *files, const char *root)
pgBackupGetPath(backup, path, lengthof(path), DATABASE_FILE_LIST);
fp = fopen(path, "wt");
fp = fio_open(path, PG_BINARY_W, FIO_BACKUP_HOST);
if (fp == NULL)
elog(ERROR, "cannot open file list \"%s\": %s", path,
strerror(errno));
print_file_list(fp, files, root);
if (fflush(fp) != 0 ||
fsync(fileno(fp)) != 0 ||
fclose(fp))
if (fio_flush(fp) != 0 ||
fio_close(fp))
elog(ERROR, "cannot write file list \"%s\": %s", path, strerror(errno));
}

View File

@ -13,7 +13,7 @@
#include "storage/checksum.h"
#include "storage/checksum_impl.h"
#include <common/pg_lzcompress.h>
#include "utils/file.h"
#include <sys/stat.h>
#ifdef HAVE_LIBZ
@ -419,12 +419,12 @@ compress_and_backup_page(pgFile *file, BlockNumber blknum,
COMP_TRADITIONAL_CRC32(*crc, write_buffer, write_buffer_size);
/* write data page */
if(fwrite(write_buffer, 1, write_buffer_size, out) != write_buffer_size)
if (fio_write(out, write_buffer, write_buffer_size) != write_buffer_size)
{
int errno_tmp = errno;
fclose(in);
fclose(out);
fio_close(out);
elog(ERROR, "File: %s, cannot write backup at block %u : %s",
file->path, blknum, strerror(errno_tmp));
}
@ -512,7 +512,7 @@ backup_data_file(backup_files_arg* arguments,
nblocks = file->size/BLCKSZ;
/* open backup file for write */
out = fopen(to_path, PG_BINARY_W);
out = fio_open(to_path, PG_BINARY_W, FIO_BACKUP_HOST);
if (out == NULL)
{
int errno_tmp = errno;
@ -571,18 +571,17 @@ backup_data_file(backup_files_arg* arguments,
}
/* update file permission */
if (chmod(to_path, FILE_PERMISSION) == -1)
if (fio_chmod(to_path, FILE_PERMISSION, FIO_BACKUP_HOST) == -1)
{
int errno_tmp = errno;
fclose(in);
fclose(out);
fio_close(out);
elog(ERROR, "cannot change mode of \"%s\": %s", file->path,
strerror(errno_tmp));
}
if (fflush(out) != 0 ||
fsync(fileno(out)) != 0 ||
fclose(out))
if (fio_flush(out) != 0 ||
fio_close(out))
elog(ERROR, "cannot write backup file \"%s\": %s",
to_path, strerror(errno));
fclose(in);
@ -639,9 +638,7 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate,
* modified pages for differential restore. If the file does not exist,
* re-open it with "w" to create an empty file.
*/
out = fopen(to_path, PG_BINARY_R "+");
if (out == NULL && errno == ENOENT)
out = fopen(to_path, PG_BINARY_W);
out = fio_open(to_path, PG_BINARY_W "+", FIO_DB_HOST);
if (out == NULL)
{
int errno_tmp = errno;
@ -737,27 +734,27 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate,
/*
* Seek and write the restored page.
*/
if (fseek(out, write_pos, SEEK_SET) < 0)
if (fio_seek(out, write_pos) < 0)
elog(ERROR, "cannot seek block %u of \"%s\": %s",
blknum, to_path, strerror(errno));
if (write_header)
{
if (fwrite(&header, 1, sizeof(header), out) != sizeof(header))
if (fio_write(out, &header, sizeof(header)) != sizeof(header))
elog(ERROR, "cannot write header of block %u of \"%s\": %s",
blknum, file->path, strerror(errno));
}
if (header.compressed_size < BLCKSZ)
{
if (fwrite(page.data, 1, BLCKSZ, out) != BLCKSZ)
if (fio_write(out, page.data, BLCKSZ) != BLCKSZ)
elog(ERROR, "cannot write block %u of \"%s\": %s",
blknum, file->path, strerror(errno));
}
else
{
/* if page wasn't compressed, we've read full block */
if (fwrite(compressed_page.data, 1, BLCKSZ, out) != BLCKSZ)
if (fio_write(out, compressed_page.data, BLCKSZ) != BLCKSZ)
elog(ERROR, "cannot write block %u of \"%s\": %s",
blknum, file->path, strerror(errno));
}
@ -775,7 +772,7 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate,
size_t file_size = 0;
/* get file current size */
fseek(out, 0, SEEK_END);
fio_seek(out, 0);
file_size = ftell(out);
if (file_size > file->n_blocks * BLCKSZ)
@ -795,7 +792,7 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate,
/*
* Truncate file to this length.
*/
if (ftruncate(fileno(out), write_pos) != 0)
if (fio_truncate(out, write_pos) != 0)
elog(ERROR, "cannot truncate \"%s\": %s",
file->path, strerror(errno));
elog(VERBOSE, "Delta truncate file %s to block %u",
@ -803,20 +800,19 @@ restore_data_file(const char *to_path, pgFile *file, bool allow_truncate,
}
/* update file permission */
if (chmod(to_path, file->mode) == -1)
if (fio_chmod(to_path, file->mode, FIO_DB_HOST) == -1)
{
int errno_tmp = errno;
if (in)
fclose(in);
fclose(out);
fio_close(out);
elog(ERROR, "cannot change mode of \"%s\": %s", to_path,
strerror(errno_tmp));
}
if (fflush(out) != 0 ||
fsync(fileno(out)) != 0 ||
fclose(out))
if (fio_flush(out) != 0 ||
fio_close(out))
elog(ERROR, "cannot write \"%s\": %s", to_path, strerror(errno));
if (in)
fclose(in);
@ -862,7 +858,7 @@ copy_file(const char *from_root, const char *to_root, pgFile *file)
/* open backup file for write */
join_path_components(to_path, to_root, file->path + strlen(from_root) + 1);
out = fopen(to_path, PG_BINARY_W);
out = fio_open(to_path, PG_BINARY_W, FIO_BACKUP_HOST);
if (out == NULL)
{
int errno_tmp = errno;
@ -875,7 +871,7 @@ copy_file(const char *from_root, const char *to_root, pgFile *file)
if (fstat(fileno(in), &st) == -1)
{
fclose(in);
fclose(out);
fio_close(out);
elog(ERROR, "cannot stat \"%s\": %s", file->path,
strerror(errno));
}
@ -888,12 +884,12 @@ copy_file(const char *from_root, const char *to_root, pgFile *file)
if ((read_len = fread(buf, 1, sizeof(buf), in)) != sizeof(buf))
break;
if (fwrite(buf, 1, read_len, out) != read_len)
if (fio_write(out, buf, read_len) != read_len)
{
errno_tmp = errno;
/* oops */
fclose(in);
fclose(out);
fio_close(out);
elog(ERROR, "cannot write to \"%s\": %s", to_path,
strerror(errno_tmp));
}
@ -907,7 +903,7 @@ copy_file(const char *from_root, const char *to_root, pgFile *file)
if (!feof(in))
{
fclose(in);
fclose(out);
fio_close(out);
elog(ERROR, "cannot read backup mode file \"%s\": %s",
file->path, strerror(errno_tmp));
}
@ -915,12 +911,12 @@ copy_file(const char *from_root, const char *to_root, pgFile *file)
/* copy odd part. */
if (read_len > 0)
{
if (fwrite(buf, 1, read_len, out) != read_len)
if (fio_write(out, buf, read_len) != read_len)
{
errno_tmp = errno;
/* oops */
fclose(in);
fclose(out);
fio_close(out);
elog(ERROR, "cannot write to \"%s\": %s", to_path,
strerror(errno_tmp));
}
@ -936,18 +932,17 @@ copy_file(const char *from_root, const char *to_root, pgFile *file)
file->crc = crc;
/* update file permission */
if (chmod(to_path, st.st_mode) == -1)
if (fio_chmod(to_path, st.st_mode, FIO_BACKUP_HOST) == -1)
{
errno_tmp = errno;
fclose(in);
fclose(out);
fio_close(out);
elog(ERROR, "cannot change mode of \"%s\": %s", to_path,
strerror(errno_tmp));
}
if (fflush(out) != 0 ||
fsync(fileno(out)) != 0 ||
fclose(out))
if (fio_flush(out) != 0 ||
fio_close(out))
elog(ERROR, "cannot write \"%s\": %s", to_path, strerror(errno));
fclose(in);
@ -992,7 +987,7 @@ get_gz_error(gzFile gzf, int errnum)
* Copy file attributes
*/
static void
copy_meta(const char *from_path, const char *to_path, bool unlink_on_error)
copy_meta(const char *from_path, const char *to_path, bool unlink_on_error, fio_location location)
{
struct stat st;
@ -1004,7 +999,7 @@ copy_meta(const char *from_path, const char *to_path, bool unlink_on_error)
from_path, strerror(errno));
}
if (chmod(to_path, st.st_mode) == -1)
if (fio_chmod(to_path, st.st_mode, location) == -1)
{
if (unlink_on_error)
unlink(to_path);
@ -1064,7 +1059,7 @@ push_wal_file(const char *from_path, const char *to_path, bool is_compress,
snprintf(to_path_temp, sizeof(to_path_temp), "%s.partial", to_path);
out = fopen(to_path_temp, PG_BINARY_W);
out = fio_open(to_path_temp, PG_BINARY_W, FIO_BACKUP_HOST);
if (out == NULL)
elog(ERROR, "Cannot open destination WAL file \"%s\": %s",
to_path_temp, strerror(errno));
@ -1102,7 +1097,7 @@ push_wal_file(const char *from_path, const char *to_path, bool is_compress,
else
#endif
{
if (fwrite(buf, 1, read_len, out) != read_len)
if (fio_write(out, buf, read_len) != read_len)
{
errno_temp = errno;
unlink(to_path_temp);
@ -1130,9 +1125,8 @@ push_wal_file(const char *from_path, const char *to_path, bool is_compress,
else
#endif
{
if (fflush(out) != 0 ||
fsync(fileno(out)) != 0 ||
fclose(out))
if (fio_flush(out) != 0 ||
fio_close(out))
{
errno_temp = errno;
unlink(to_path_temp);
@ -1150,9 +1144,9 @@ push_wal_file(const char *from_path, const char *to_path, bool is_compress,
}
/* update file permission. */
copy_meta(from_path, to_path_temp, true);
copy_meta(from_path, to_path_temp, true, FIO_BACKUP_HOST);
if (rename(to_path_temp, to_path_p) < 0)
if (fio_rename(to_path_temp, to_path_p, FIO_BACKUP_HOST) < 0)
{
errno_temp = errno;
unlink(to_path_temp);
@ -1223,7 +1217,7 @@ get_wal_file(const char *from_path, const char *to_path)
/* open backup file for write */
snprintf(to_path_temp, sizeof(to_path_temp), "%s.partial", to_path);
out = fopen(to_path_temp, PG_BINARY_W);
out = fio_open(to_path_temp, PG_BINARY_W, FIO_DB_HOST);
if (out == NULL)
elog(ERROR, "Cannot open destination WAL file \"%s\": %s",
to_path_temp, strerror(errno));
@ -1260,7 +1254,7 @@ get_wal_file(const char *from_path, const char *to_path)
if (read_len > 0)
{
if (fwrite(buf, 1, read_len, out) != read_len)
if (fio_write(out, buf, read_len) != read_len)
{
errno_temp = errno;
unlink(to_path_temp);
@ -1284,9 +1278,8 @@ get_wal_file(const char *from_path, const char *to_path)
}
}
if (fflush(out) != 0 ||
fsync(fileno(out)) != 0 ||
fclose(out))
if (fio_flush(out) != 0 ||
fio_close(out))
{
errno_temp = errno;
unlink(to_path_temp);
@ -1318,9 +1311,9 @@ get_wal_file(const char *from_path, const char *to_path)
}
/* update file permission. */
copy_meta(from_path_p, to_path_temp, true);
copy_meta(from_path_p, to_path_temp, true, FIO_DB_HOST);
if (rename(to_path_temp, to_path) < 0)
if (fio_rename(to_path_temp, to_path, FIO_DB_HOST) < 0)
{
errno_temp = errno;
unlink(to_path_temp);

View File

@ -9,6 +9,8 @@
*/
#include "pg_probackup.h"
#include "utils/file.h"
#if PG_VERSION_NUM < 110000
#include "catalog/catalog.h"
@ -926,7 +928,7 @@ opt_tablespace_map(pgut_option *opt, const char *arg)
*/
void
create_data_directories(const char *data_dir, const char *backup_dir,
bool extract_tablespaces)
bool extract_tablespaces, fio_location location)
{
parray *dirs,
*links = NULL;
@ -1026,11 +1028,11 @@ create_data_directories(const char *data_dir, const char *backup_dir,
linked_path, relative_ptr);
/* Firstly, create linked directory */
dir_create_dir(linked_path, DIR_PERMISSION);
fio_mkdir(linked_path, DIR_PERMISSION, location);
join_path_components(to_path, data_dir, PG_TBLSPC_DIR);
/* Create pg_tblspc directory just in case */
dir_create_dir(to_path, DIR_PERMISSION);
fio_mkdir(to_path, DIR_PERMISSION, location);
/* Secondly, create link */
join_path_components(to_path, to_path, link_name);
@ -1057,7 +1059,7 @@ create_directory:
/* This is not symlink, create directory */
join_path_components(to_path, data_dir, relative_ptr);
dir_create_dir(to_path, DIR_PERMISSION);
fio_mkdir(to_path, DIR_PERMISSION, location);
}
if (extract_tablespaces)
@ -1204,7 +1206,7 @@ print_file_list(FILE *out, const parray *files, const char *root)
if (root && strstr(path, root) == path)
path = GetRelativePath(path, root);
fprintf(out, "{\"path\":\"%s\", \"size\":\"" INT64_FORMAT "\", "
fio_printf(out, "{\"path\":\"%s\", \"size\":\"" INT64_FORMAT "\", "
"\"mode\":\"%u\", \"is_datafile\":\"%u\", "
"\"is_cfs\":\"%u\", \"crc\":\"%u\", "
"\"compress_alg\":\"%s\"",
@ -1213,19 +1215,19 @@ print_file_list(FILE *out, const parray *files, const char *root)
deparse_compress_alg(file->compress_alg));
if (file->is_datafile)
fprintf(out, ",\"segno\":\"%d\"", file->segno);
fio_printf(out, ",\"segno\":\"%d\"", file->segno);
#ifndef WIN32
if (S_ISLNK(file->mode))
#else
if (pgwin32_is_junction(file->path))
#endif
fprintf(out, ",\"linked\":\"%s\"", file->linked);
fio_printf(out, ",\"linked\":\"%s\"", file->linked);
if (file->n_blocks != BLOCKNUM_INVALID)
fprintf(out, ",\"n_blocks\":\"%i\"", file->n_blocks);
fio_printf(out, ",\"n_blocks\":\"%i\"", file->n_blocks);
fprintf(out, "}\n");
fio_printf(out, "}\n");
}
}

View File

@ -93,7 +93,7 @@ do_add_instance(void)
dir_create_dir(arclog_path, DIR_PERMISSION);
/*
* Wite initial config. system-identifier and pgdata are set in
* Write initial config. system-identifier and pgdata are set in
* init subcommand and will never be updated.
*/
pgBackupConfigInit(config);

View File

@ -182,7 +182,7 @@ merge_backups(pgBackup *to_backup, pgBackup *from_backup)
pgBackupGetPath(from_backup, from_database_path, lengthof(from_database_path),
DATABASE_DIR);
create_data_directories(to_database_path, from_backup_path, false);
create_data_directories(to_database_path, from_backup_path, false, FIO_BACKUP_HOST);
/*
* Get list of files which will be modified or removed.

View File

@ -12,6 +12,7 @@
#include "pg_getopt.h"
#include "streamutil.h"
#include "utils/file.h"
#include <sys/stat.h>
@ -65,7 +66,6 @@ char *replication_slot = NULL;
/* backup options */
bool backup_logs = false;
bool smooth_checkpoint;
bool is_remote_backup = false;
/* Wait timeout for WAL segment archiving */
uint32 archive_timeout = ARCHIVE_TIMEOUT_DEFAULT;
const char *master_db = NULL;
@ -73,6 +73,10 @@ const char *master_host = NULL;
const char *master_port= NULL;
const char *master_user = NULL;
uint32 replica_timeout = REPLICA_TIMEOUT_DEFAULT;
char *ssh_host;
char *ssh_port;
bool is_remote_agent;
bool is_remote_backup;
/* restore options */
static char *target_time;
@ -165,17 +169,19 @@ static pgut_option options[] =
{ 's', 16, "master-port", &master_port, SOURCE_CMDLINE, },
{ 's', 17, "master-user", &master_user, SOURCE_CMDLINE, },
{ 'u', 18, "replica-timeout", &replica_timeout, SOURCE_CMDLINE, SOURCE_DEFAULT, OPTION_UNIT_S },
/* TODO not completed feature. Make it unavailiable from user level
{ 'b', 18, "remote", &is_remote_backup, SOURCE_CMDLINE, }, */
{ 's', 19, "ssh-host", &ssh_host, SOURCE_CMDLINE, },
{ 's', 20, "ssh-port", &ssh_port, SOURCE_CMDLINE, },
{ 'b', 21, "agent", &is_remote_agent, SOURCE_CMDLINE, },
{ 'b', 22, "remote", &is_remote_backup, SOURCE_CMDLINE, },
/* restore options */
{ 's', 20, "time", &target_time, SOURCE_CMDLINE },
{ 's', 21, "xid", &target_xid, SOURCE_CMDLINE },
{ 's', 22, "inclusive", &target_inclusive, SOURCE_CMDLINE },
{ 'u', 23, "timeline", &target_tli, SOURCE_CMDLINE },
{ 's', 30, "time", &target_time, SOURCE_CMDLINE },
{ 's', 31, "xid", &target_xid, SOURCE_CMDLINE },
{ 's', 32, "inclusive", &target_inclusive, SOURCE_CMDLINE },
{ 'u', 33, "timeline", &target_tli, SOURCE_CMDLINE },
{ 'f', 'T', "tablespace-mapping", opt_tablespace_map, SOURCE_CMDLINE },
{ 'b', 24, "immediate", &target_immediate, SOURCE_CMDLINE },
{ 's', 25, "recovery-target-name", &target_name, SOURCE_CMDLINE },
{ 's', 26, "recovery-target-action", &target_action, SOURCE_CMDLINE },
{ 'b', 34, "immediate", &target_immediate, SOURCE_CMDLINE },
{ 's', 35, "recovery-target-name", &target_name, SOURCE_CMDLINE },
{ 's', 36, "recovery-target-action", &target_action, SOURCE_CMDLINE },
{ 'b', 'R', "restore-as-replica", &restore_as_replica, SOURCE_CMDLINE },
{ 'b', 27, "no-validate", &restore_no_validate, SOURCE_CMDLINE },
{ 's', 28, "lsn", &target_lsn, SOURCE_CMDLINE },
@ -372,10 +378,28 @@ main(int argc, char *argv[])
if (!is_absolute_path(backup_path))
elog(ERROR, "-B, --backup-path must be an absolute path");
/* Ensure that backup_path is a path to a directory */
rc = stat(backup_path, &stat_buf);
if (rc != -1 && !S_ISDIR(stat_buf.st_mode))
elog(ERROR, "-B, --backup-path must be a path to directory");
if (ssh_host != NULL &&
(backup_subcmd == BACKUP_CMD || backup_subcmd == ADD_INSTANCE_CMD || backup_subcmd == RESTORE_CMD))
{
if (is_remote_agent) {
if (backup_subcmd != BACKUP_CMD) {
fio_communicate(STDIN_FILENO, STDOUT_FILENO);
return 0;
}
fio_redirect(STDIN_FILENO, STDOUT_FILENO);
} else {
/* Execute remote probackup */
remote_execute(argc, argv, backup_subcmd == BACKUP_CMD);
}
}
if (!is_remote_agent)
{
/* Ensure that backup_path is a path to a directory */
rc = stat(backup_path, &stat_buf);
if (rc != -1 && !S_ISDIR(stat_buf.st_mode))
elog(ERROR, "-B, --backup-path must be a path to directory");
}
/* command was initialized for a few commands */
if (command)
@ -409,7 +433,7 @@ main(int argc, char *argv[])
* for all commands except init, which doesn't take this parameter
* and add-instance which creates new instance.
*/
if (backup_subcmd != INIT_CMD && backup_subcmd != ADD_INSTANCE_CMD)
if (backup_subcmd != INIT_CMD && backup_subcmd != ADD_INSTANCE_CMD && !is_remote_agent)
{
if (access(backup_instance_path, F_OK) != 0)
elog(ERROR, "Instance '%s' does not exist in this backup catalog",
@ -523,7 +547,7 @@ main(int argc, char *argv[])
elog(INFO, "Backup start, pg_probackup version: %s, backup ID: %s, backup mode: %s, instance: %s, stream: %s, remote: %s",
PROGRAM_VERSION, base36enc(start_time), backup_mode, instance_name,
stream_wal ? "true" : "false", is_remote_backup ? "true" : "false");
stream_wal ? "true" : "false", ssh_host ? "true" : "false");
return do_backup(start_time);
}

View File

@ -10,23 +10,23 @@
#ifndef PG_PROBACKUP_H
#define PG_PROBACKUP_H
#include "postgres_fe.h"
#include "libpq-fe.h"
#include "access/xlog_internal.h"
#include "utils/pg_crc.h"
#include <postgres_fe.h>
#include <libpq-fe.h>
#include <access/xlog_internal.h>
#include <utils/pg_crc.h>
#ifdef FRONTEND
#undef FRONTEND
#include "port/atomics.h"
#include <port/atomics.h>
#define FRONTEND
#else
#include "port/atomics.h"
#include <port/atomics.h>
#endif
#include "utils/logger.h"
#include "utils/parray.h"
#include "utils/pgut.h"
#include "utils/file.h"
#include "datapagemap.h"
@ -325,11 +325,14 @@ extern char *replication_slot;
extern bool smooth_checkpoint;
#define ARCHIVE_TIMEOUT_DEFAULT 300
extern uint32 archive_timeout;
extern bool is_remote_backup;
extern char *ssh_port;
extern char *ssh_host;
extern const char *master_db;
extern const char *master_host;
extern const char *master_port;
extern const char *master_user;
extern bool is_remote_backup;
extern bool is_remote_agent;
#define REPLICA_TIMEOUT_DEFAULT 300
extern uint32 replica_timeout;
@ -472,6 +475,7 @@ extern pgBackup* find_parent_full_backup(pgBackup *current_backup);
extern int scan_parent_chain(pgBackup *current_backup, pgBackup **result_backup);
extern bool is_parent(time_t parent_backup_time, pgBackup *child_backup, bool inclusive);
extern int get_backup_index_number(parray *backup_list, pgBackup *backup);
extern void remote_execute(int argc, char *argv[], bool do_backup);
#define COMPRESS_ALG_DEFAULT NOT_DEFINED_COMPRESS
#define COMPRESS_LEVEL_DEFAULT 1
@ -484,7 +488,8 @@ extern void dir_list_file(parray *files, const char *root, bool exclude,
bool omit_symlink, bool add_root);
extern void create_data_directories(const char *data_dir,
const char *backup_dir,
bool extract_tablespaces);
bool extract_tablespaces,
fio_location location);
extern void read_tablespace_map(parray *files, const char *backup_dir);
extern void opt_tablespace_map(pgut_option *opt, const char *arg);

View File

@ -445,7 +445,7 @@ restore_backup(pgBackup *backup)
* this_backup_path = $BACKUP_PATH/backups/instance_name/backup_id
*/
pgBackupGetPath(backup, this_backup_path, lengthof(this_backup_path), NULL);
create_data_directories(pgdata, this_backup_path, true);
create_data_directories(pgdata, this_backup_path, true, FIO_DB_HOST);
/*
* Get list of files which need to be restored.

View File

@ -19,6 +19,7 @@
#include "pgut.h"
#include "logger.h"
#include "file.h"
#define MAX_TZDISP_HOUR 15 /* maximum allowed hour part */
#define SECS_PER_MINUTE 60
@ -1147,7 +1148,7 @@ pgut_readopt(const char *path, pgut_option options[], int elevel, bool strict)
if (!options)
return parsed_options;
if ((fp = pgut_fopen(path, "rt", true)) == NULL)
if ((fp = fio_open_stream(path, FIO_BACKUP_HOST)) == NULL)
return parsed_options;
while (fgets(buf, lengthof(buf), fp))
@ -1181,7 +1182,7 @@ pgut_readopt(const char *path, pgut_option options[], int elevel, bool strict)
}
}
fclose(fp);
fio_close_stream(fp);
return parsed_options;
}