mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +03:00
Move frontend-side archive APIs from src/common/ to src/fe_utils/
fe_archive.c was compiled only for the frontend in src/common/, but as it will never share anything with the backend, it makes most sense to move this file to src/fe_utils/. Reported-by: Peter Eisentraut Discussion: https://postgr.es/m/e9766d71-8655-ac86-bdf6-77e0e7169977@2ndquadrant.com Backpatch-through: 13
This commit is contained in:
@ -20,6 +20,7 @@ include $(top_builddir)/src/Makefile.global
|
||||
override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
|
||||
|
||||
OBJS = \
|
||||
archive.o \
|
||||
cancel.o \
|
||||
conditional.o \
|
||||
mbprint.o \
|
||||
|
124
src/fe_utils/archive.c
Normal file
124
src/fe_utils/archive.c
Normal file
@ -0,0 +1,124 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* archive.c
|
||||
* Routines to access WAL archives from frontend
|
||||
*
|
||||
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/fe_utils/archive.c
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres_fe.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "access/xlog_internal.h"
|
||||
#include "common/archive.h"
|
||||
#include "common/logging.h"
|
||||
#include "fe_utils/archive.h"
|
||||
|
||||
|
||||
/*
|
||||
* RestoreArchivedFile
|
||||
*
|
||||
* Attempt to retrieve the specified file from off-line archival storage.
|
||||
* If successful, return a file descriptor of the restored file, else
|
||||
* return -1.
|
||||
*
|
||||
* For fixed-size files, the caller may pass the expected size as an
|
||||
* additional crosscheck on successful recovery. If the file size is not
|
||||
* known, set expectedSize = 0.
|
||||
*/
|
||||
int
|
||||
RestoreArchivedFile(const char *path, const char *xlogfname,
|
||||
off_t expectedSize, const char *restoreCommand)
|
||||
{
|
||||
char xlogpath[MAXPGPATH];
|
||||
char *xlogRestoreCmd;
|
||||
int rc;
|
||||
struct stat stat_buf;
|
||||
|
||||
snprintf(xlogpath, MAXPGPATH, "%s/" XLOGDIR "/%s", path, xlogfname);
|
||||
|
||||
xlogRestoreCmd = BuildRestoreCommand(restoreCommand, xlogpath,
|
||||
xlogfname, NULL);
|
||||
if (xlogRestoreCmd == NULL)
|
||||
{
|
||||
pg_log_fatal("could not use restore_command with %%r alias");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute restore_command, which should copy the missing file from
|
||||
* archival storage.
|
||||
*/
|
||||
rc = system(xlogRestoreCmd);
|
||||
pfree(xlogRestoreCmd);
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
/*
|
||||
* Command apparently succeeded, but let's make sure the file is
|
||||
* really there now and has the correct size.
|
||||
*/
|
||||
if (stat(xlogpath, &stat_buf) == 0)
|
||||
{
|
||||
if (expectedSize > 0 && stat_buf.st_size != expectedSize)
|
||||
{
|
||||
pg_log_fatal("unexpected file size for \"%s\": %lu instead of %lu",
|
||||
xlogfname, (unsigned long) stat_buf.st_size,
|
||||
(unsigned long) expectedSize);
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int xlogfd = open(xlogpath, O_RDONLY | PG_BINARY, 0);
|
||||
|
||||
if (xlogfd < 0)
|
||||
{
|
||||
pg_log_fatal("could not open file \"%s\" restored from archive: %m",
|
||||
xlogpath);
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
return xlogfd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
pg_log_fatal("could not stat file \"%s\": %m",
|
||||
xlogpath);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the failure was due to a signal, then it would be misleading to
|
||||
* return with a failure at restoring the file. So just bail out and
|
||||
* exit. Hard shell errors such as "command not found" are treated as
|
||||
* fatal too.
|
||||
*/
|
||||
if (wait_result_is_any_signal(rc, true))
|
||||
{
|
||||
pg_log_fatal("restore_command failed due to the signal: %s",
|
||||
wait_result_to_str(rc));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* The file is not available, so just let the caller decide what to do
|
||||
* next.
|
||||
*/
|
||||
pg_log_error("could not restore file \"%s\" from archive",
|
||||
xlogfname);
|
||||
return -1;
|
||||
}
|
Reference in New Issue
Block a user