1
0
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:
itagaki.takahiro 2009-12-18 02:26:19 +00:00
parent f0d7a1254e
commit 8863b7944b
9 changed files with 105 additions and 48 deletions

View File

@ -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(&current))
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;

View File

@ -56,8 +56,6 @@ parray_expand(parray *array, size_t newsize)
array->alloced = newsize;
array->data = p;
return;
}
void

View File

@ -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"
@ -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);

View File

@ -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);

89
xlog.c
View File

@ -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);
/* check header */
if (header->xlp_magic != XLOG_PAGE_MAGIC)
return false;
if ((header->xlp_info & ~XLP_ALL_FLAGS) != 0)
return false;
/* 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;
if (header->xlp_info & XLP_LONG_HEADER)
/* check header */
if (page.header.xlp_magic != xlog_page_magic)
return false;
if ((page.header.xlp_info & ~XLP_ALL_FLAGS) != 0)
return false;
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;
}