mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2024-11-28 09:33:54 +02:00
Adjust to be able to build on 8.3 or older versions.
git-svn-id: http://pg-rman.googlecode.com/svn/trunk@22 182aca00-e38e-11de-a668-6fd11605f5ce
This commit is contained in:
parent
f0d7a1254e
commit
8863b7944b
36
backup.c
36
backup.c
@ -27,7 +27,8 @@ static bool in_backup = false; /* TODO: more robust logic */
|
||||
* Backup routines
|
||||
*/
|
||||
static void backup_cleanup(bool fatal, void *userdata);
|
||||
static void delete_old_files(const char *root, parray *files, int keep_files, int keep_days, bool is_arclog);
|
||||
static void delete_old_files(const char *root, parray *files, int keep_files,
|
||||
int keep_days, int server_version, bool is_arclog);
|
||||
static void backup_files(const char *from_root, const char *to_root,
|
||||
parray *files, parray *prev_files, XLogRecPtr *lsn, bool compress_data);
|
||||
static parray *do_backup_database(parray *backup_list, bool smooth_checkpoint);
|
||||
@ -432,11 +433,12 @@ do_backup(bool smooth_checkpoint,
|
||||
int keep_data_generations,
|
||||
int keep_data_days)
|
||||
{
|
||||
int ret;
|
||||
parray *backup_list;
|
||||
parray *files_database;
|
||||
parray *files_arclog;
|
||||
parray *files_srvlog;
|
||||
int server_version;
|
||||
int ret;
|
||||
|
||||
/* PGDATA and BACKUP_MODE are always required */
|
||||
if (pgdata == NULL)
|
||||
@ -462,7 +464,7 @@ do_backup(bool smooth_checkpoint,
|
||||
#endif
|
||||
|
||||
/* confirm data block size and xlog block size are compatible */
|
||||
(void) get_server_version();
|
||||
server_version = get_server_version();
|
||||
|
||||
/* setup cleanup callback function */
|
||||
in_backup = true;
|
||||
@ -546,10 +548,10 @@ do_backup(bool smooth_checkpoint,
|
||||
*/
|
||||
if (HAVE_ARCLOG(¤t))
|
||||
delete_old_files(arclog_path, files_arclog, keep_arclog_files,
|
||||
keep_arclog_days, true);
|
||||
keep_arclog_days, server_version, true);
|
||||
if (current.with_serverlog)
|
||||
delete_old_files(srvlog_path, files_srvlog, keep_srvlog_files,
|
||||
keep_srvlog_days, false);
|
||||
keep_srvlog_days, server_version, false);
|
||||
|
||||
/* Delete old backup files after all backup operation. */
|
||||
pgBackupDelete(keep_data_generations, keep_data_days);
|
||||
@ -603,14 +605,17 @@ get_server_version(void)
|
||||
|
||||
/* confirm server version */
|
||||
server_version = PQserverVersion(connection);
|
||||
if (server_version < 80000)
|
||||
if (server_version < 80200)
|
||||
elog(ERROR_PG_INCOMPATIBLE,
|
||||
_("server version is %d, but must be 8.0 or higher."),
|
||||
server_version);
|
||||
_("server version is %d.%d.%d, but must be 8.2 or higher."),
|
||||
server_version / 10000,
|
||||
(server_version / 100) % 100,
|
||||
server_version % 100);
|
||||
|
||||
/* confirm block_size (BLCKSZ) and wal_block_size (XLOG_BLCKSZ) */
|
||||
confirm_block_size("block_size", BLCKSZ);
|
||||
confirm_block_size("wal_block_size", XLOG_BLCKSZ);
|
||||
if (server_version >= 80400)
|
||||
confirm_block_size("wal_block_size", XLOG_BLCKSZ);
|
||||
|
||||
if (my_conn)
|
||||
disconnect();
|
||||
@ -625,9 +630,7 @@ confirm_block_size(const char *name, int blcksz)
|
||||
char *endp;
|
||||
int block_size;
|
||||
|
||||
res = execute(
|
||||
"SELECT setting from pg_settings where name = $1",
|
||||
1, &name);
|
||||
res = execute("SELECT current_setting($1)", 1, &name);
|
||||
if (PQntuples(res) != 1 || PQnfields(res) != 1)
|
||||
elog(ERROR_PG_COMMAND, _("can't get %s: %s"),
|
||||
name, PQerrorMessage(connection));
|
||||
@ -955,7 +958,12 @@ backup_files(const char *from_root, const char *to_root, parray *files,
|
||||
* of newer files exist.
|
||||
*/
|
||||
static void
|
||||
delete_old_files(const char *root, parray *files, int keep_files, int keep_days, bool is_arclog)
|
||||
delete_old_files(const char *root,
|
||||
parray *files,
|
||||
int keep_files,
|
||||
int keep_days,
|
||||
int server_version,
|
||||
bool is_arclog)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
@ -996,7 +1004,7 @@ delete_old_files(const char *root, parray *files, int keep_files, int keep_days,
|
||||
|
||||
elog(LOG, "%s() %s", __FUNCTION__, file->path);
|
||||
/* Delete complete WAL only. */
|
||||
if (is_arclog && !xlog_is_complete_wal(file))
|
||||
if (is_arclog && !xlog_is_complete_wal(file, server_version))
|
||||
{
|
||||
elog(LOG, "%s() not complete WAL", __FUNCTION__);
|
||||
continue;
|
||||
|
@ -311,7 +311,7 @@ catalog_get_last_srvlog_backup(parray *backup_list)
|
||||
/* create backup directory in $BACKUP_PATH */
|
||||
int
|
||||
pgBackupCreateDir(pgBackup *backup)
|
||||
{
|
||||
{
|
||||
int i;
|
||||
char path[MAXPGPATH];
|
||||
char *subdirs[] = { DATABASE_DIR, ARCLOG_DIR, SRVLOG_DIR, NULL };
|
||||
|
2
data.c
2
data.c
@ -432,7 +432,7 @@ backup_data_file(const char *from_root, const char *to_root,
|
||||
{
|
||||
/*
|
||||
* If the odd size page is the 1st page, fallback to simple copy because
|
||||
* the file is not a datafile.
|
||||
* the file is not a datafile.
|
||||
* Otherwise treat the page as a datapage with no hole.
|
||||
*/
|
||||
if (blknum == 0)
|
||||
|
2
delete.c
2
delete.c
@ -177,7 +177,7 @@ pgBackupDeleteFiles(pgBackup *backup)
|
||||
|
||||
/*
|
||||
* update STATUS to BACKUP_STATUS_DELETING in preparation for the case which
|
||||
* the error occurs before deleting all backup files.
|
||||
* the error occurs before deleting all backup files.
|
||||
*/
|
||||
if (!check)
|
||||
{
|
||||
|
2
parray.c
2
parray.c
@ -56,8 +56,6 @@ parray_expand(parray *array, size_t newsize)
|
||||
|
||||
array->alloced = newsize;
|
||||
array->data = p;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -19,6 +19,10 @@
|
||||
#include "utils/pg_crc.h"
|
||||
#include "parray.h"
|
||||
|
||||
#if PG_VERSION_NUM < 80200
|
||||
#define XLOG_BLCKSZ BLCKSZ
|
||||
#endif
|
||||
|
||||
/* Directory/File names */
|
||||
#define DATABASE_DIR "database"
|
||||
#define ARCLOG_DIR "arclog"
|
||||
@ -52,7 +56,7 @@ typedef struct pgFile
|
||||
time_t mtime; /* time of last modification */
|
||||
mode_t mode; /* protection (file type and permission) */
|
||||
size_t size; /* size of the file */
|
||||
size_t read_size; /* size of the portion read (if only some pages are
|
||||
size_t read_size; /* size of the portion read (if only some pages are
|
||||
backed up partially, it's different from size) */
|
||||
size_t write_size; /* size of the backed-up file. BYTES_INVALID means
|
||||
that the file existed but was not backed up
|
||||
@ -241,7 +245,7 @@ extern int pgFileCompareMtime(const void *f1, const void *f2);
|
||||
extern int pgFileCompareMtimeDesc(const void *f1, const void *f2);
|
||||
|
||||
/* in xlog.c */
|
||||
extern bool xlog_is_complete_wal(const pgFile *file);
|
||||
extern bool xlog_is_complete_wal(const pgFile *file, int server_version);
|
||||
extern bool xlog_logfname2lsn(const char *logfname, XLogRecPtr *lsn);
|
||||
extern void xlog_fname(char *fname, size_t len, TimeLineID tli, XLogRecPtr *lsn);
|
||||
|
||||
|
@ -56,7 +56,7 @@ typedef struct REPARSE_DATA
|
||||
ssize_t
|
||||
readlink(const char *path, char *target, size_t size)
|
||||
{
|
||||
HANDLE handle;
|
||||
HANDLE handle;
|
||||
DWORD attr;
|
||||
REPARSE_DATA data;
|
||||
DWORD datasize;
|
||||
@ -68,12 +68,12 @@ readlink(const char *path, char *target, size_t size)
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
_dosmaperr(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0)
|
||||
{
|
||||
errno = EINVAL; /* not a symlink */
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle = CreateFileA(path, 0,
|
||||
@ -83,9 +83,9 @@ readlink(const char *path, char *target, size_t size)
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
_dosmaperr(GetLastError());
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
wpath = NULL;
|
||||
if (DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0,
|
||||
&data, sizeof(data), &datasize, NULL))
|
||||
|
@ -16,10 +16,6 @@
|
||||
|
||||
#include "catalog/pg_control.h"
|
||||
|
||||
#if PG_VERSION_NUM < 80200
|
||||
#define XLOG_BLCKSZ BLCKSZ
|
||||
#endif
|
||||
|
||||
static void backup_online_files(bool re_recovery);
|
||||
static void restore_online_files(void);
|
||||
static void restore_database(pgBackup *backup);
|
||||
|
85
xlog.c
85
xlog.c
@ -21,49 +21,100 @@ typedef struct MemoryContextData *MemoryContext;
|
||||
|
||||
#include "access/xlog_internal.h"
|
||||
|
||||
#define XLOG_PAGE_MAGIC_v80 0xD05C /* 8.0 */
|
||||
#define XLOG_PAGE_MAGIC_v81 0xD05D /* 8.1 */
|
||||
#define XLOG_PAGE_MAGIC_v82 0xD05E /* 8.2 */
|
||||
#define XLOG_PAGE_MAGIC_v83 0xD062 /* 8.3 */
|
||||
#define XLOG_PAGE_MAGIC_v84 0xD063 /* 8.4 */
|
||||
#define XLOG_PAGE_MAGIC_v85 0xD063 /* 8.5 */
|
||||
|
||||
typedef struct XLogLongPageHeaderData_v81
|
||||
{
|
||||
XLogPageHeaderData std;
|
||||
uint64 xlp_sysid;
|
||||
uint32 xlp_seg_size;
|
||||
} XLogLongPageHeaderData_v81, *XLogLongPageHeader_v81;
|
||||
|
||||
typedef struct XLogLongPageHeaderData_v82
|
||||
{
|
||||
XLogPageHeaderData std; /* standard header fields */
|
||||
uint64 xlp_sysid; /* system identifier from pg_control */
|
||||
uint32 xlp_seg_size; /* just as a cross-check */
|
||||
uint32 xlp_xlog_blcksz; /* just as a cross-check */
|
||||
} XLogLongPageHeaderData_v82, *XLogLongPageHeader_v82;
|
||||
|
||||
typedef union XLogPage
|
||||
{
|
||||
XLogPageHeaderData header;
|
||||
XLogLongPageHeaderData_v81 long_v81; /* 8.1 - 8.2 */
|
||||
XLogLongPageHeaderData_v82 long_v82; /* 8.3 - */
|
||||
char data[XLOG_BLCKSZ];
|
||||
} XLogPage;
|
||||
|
||||
/*
|
||||
* Return whether the file is a WAL segment or not.
|
||||
* based on ValidXLOGHeader() in src/backend/access/transam/xlog.c.
|
||||
*/
|
||||
bool
|
||||
xlog_is_complete_wal(const pgFile *file)
|
||||
xlog_is_complete_wal(const pgFile *file, int server_version)
|
||||
{
|
||||
FILE *fp;
|
||||
char page[XLOG_BLCKSZ];
|
||||
XLogPageHeader header = (XLogPageHeader) page;
|
||||
XLogLongPageHeader lheader = (XLogLongPageHeader) page;
|
||||
FILE *fp;
|
||||
XLogPage page;
|
||||
uint16 xlog_page_magic;
|
||||
|
||||
fp = fopen(file->path, "r");
|
||||
if (!fp)
|
||||
return false;
|
||||
if (fread(page, 1, sizeof(page), fp) != XLOG_BLCKSZ)
|
||||
if (fread(&page, 1, sizeof(page), fp) != XLOG_BLCKSZ)
|
||||
{
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
/* xlog_page_magic from server version */
|
||||
if (server_version < 80100)
|
||||
xlog_page_magic = XLOG_PAGE_MAGIC_v80;
|
||||
else if (server_version < 80200)
|
||||
xlog_page_magic = XLOG_PAGE_MAGIC_v81;
|
||||
else if (server_version < 80300)
|
||||
xlog_page_magic = XLOG_PAGE_MAGIC_v82;
|
||||
else if (server_version < 80400)
|
||||
xlog_page_magic = XLOG_PAGE_MAGIC_v83;
|
||||
else if (server_version < 80500)
|
||||
xlog_page_magic = XLOG_PAGE_MAGIC_v84;
|
||||
else
|
||||
xlog_page_magic = XLOG_PAGE_MAGIC_v85;
|
||||
|
||||
/* check header */
|
||||
if (header->xlp_magic != XLOG_PAGE_MAGIC)
|
||||
if (page.header.xlp_magic != xlog_page_magic)
|
||||
return false;
|
||||
if ((header->xlp_info & ~XLP_ALL_FLAGS) != 0)
|
||||
if ((page.header.xlp_info & ~XLP_ALL_FLAGS) != 0)
|
||||
return false;
|
||||
|
||||
if (header->xlp_info & XLP_LONG_HEADER)
|
||||
if (page.header.xlp_info & XLP_LONG_HEADER)
|
||||
{
|
||||
if (lheader->xlp_seg_size != XLogSegSize)
|
||||
if (page.long_v81.xlp_seg_size != XLogSegSize)
|
||||
return false;
|
||||
|
||||
/* compressed WAL (with lesslog) has 0 in lheader->xlp_xlog_blcksz. */
|
||||
if (lheader->xlp_xlog_blcksz != XLOG_BLCKSZ &&
|
||||
lheader->xlp_xlog_blcksz != 0)
|
||||
if (server_version >= 80300)
|
||||
{
|
||||
if (page.long_v82.xlp_xlog_blcksz == XLOG_BLCKSZ)
|
||||
{
|
||||
/* check size (actual file size, not backup file size) */
|
||||
if (file->size != XLogSegSize)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (page.long_v82.xlp_xlog_blcksz != 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (file->size != XLogSegSize)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check size (actual file size, not backup file size) */
|
||||
if (lheader->xlp_xlog_blcksz == XLOG_BLCKSZ && file->size != XLogSegSize)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user