mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2024-11-28 09:33:54 +02:00
Begin cleanup of version-related code
Due to changes in XlogRecPtr in 9.3, older version of pg_rman are already incompatible either way, and it is a pain to maintain code duplicated from past versions of Postgres, so rely a maximum on the core structures.
This commit is contained in:
parent
83462de39b
commit
5bc716415a
68
backup.c
68
backup.c
@ -20,17 +20,23 @@
|
||||
#include "libpq/pqsignal.h"
|
||||
#include "pgut/pgut-port.h"
|
||||
|
||||
#define TIMEOUT_ARCHIVE 10 /* wait 10 sec until WAL archive complete */
|
||||
/* wait 10 sec until WAL archive complete */
|
||||
#define TIMEOUT_ARCHIVE 10
|
||||
|
||||
/* Server version */
|
||||
static int server_version = 0;
|
||||
|
||||
static bool in_backup = false; /* TODO: more robust logic */
|
||||
static parray *cleanup_list; /* list of command to execute at error processing for snapshot */
|
||||
/* List of commands to execute at error processing for snapshot */
|
||||
static parray *cleanup_list;
|
||||
|
||||
/*
|
||||
* 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, int server_version, bool is_arclog);
|
||||
static void delete_old_files(const char *root,
|
||||
parray *files, int keep_files,
|
||||
int keep_days, bool is_arclog);
|
||||
static void backup_files(const char *from_root, const char *to_root,
|
||||
parray *files, parray *prev_files, const XLogRecPtr *lsn, bool compress, const char *prefix);
|
||||
static parray *do_backup_database(parray *backup_list, pgBackupOption bkupopt);
|
||||
@ -710,7 +716,6 @@ do_backup(pgBackupOption bkupopt)
|
||||
parray *files_database;
|
||||
parray *files_arclog;
|
||||
parray *files_srvlog;
|
||||
int server_version;
|
||||
int ret;
|
||||
|
||||
/* repack the necesary options */
|
||||
@ -745,7 +750,7 @@ do_backup(pgBackupOption bkupopt)
|
||||
#endif
|
||||
|
||||
/* confirm data block size and xlog block size are compatible */
|
||||
server_version = get_server_version();
|
||||
check_server_version();
|
||||
|
||||
/* setup cleanup callback function */
|
||||
in_backup = true;
|
||||
@ -837,10 +842,10 @@ do_backup(pgBackupOption bkupopt)
|
||||
*/
|
||||
if (HAVE_ARCLOG(¤t))
|
||||
delete_old_files(arclog_path, files_arclog, keep_arclog_files,
|
||||
keep_arclog_days, server_version, true);
|
||||
keep_arclog_days, true);
|
||||
if (current.with_serverlog)
|
||||
delete_old_files(srvlog_path, files_srvlog, keep_srvlog_files,
|
||||
keep_srvlog_days, server_version, false);
|
||||
keep_srvlog_days, false);
|
||||
|
||||
/* Delete old backup files after all backup operation. */
|
||||
pgBackupDelete(keep_data_generations, keep_data_days);
|
||||
@ -951,15 +956,14 @@ make_backup_label(parray *backup_list)
|
||||
/*
|
||||
* get server version and confirm block sizes.
|
||||
*/
|
||||
int
|
||||
get_server_version(void)
|
||||
void
|
||||
check_server_version(void)
|
||||
{
|
||||
static int server_version = 0;
|
||||
bool my_conn;
|
||||
|
||||
/* return cached server version */
|
||||
/* Leave if server has already been checked */
|
||||
if (server_version > 0)
|
||||
return server_version;
|
||||
return;
|
||||
|
||||
my_conn = (connection == NULL);
|
||||
|
||||
@ -968,22 +972,19 @@ get_server_version(void)
|
||||
|
||||
/* confirm server version */
|
||||
server_version = PQserverVersion(connection);
|
||||
if (server_version < 80200)
|
||||
if (server_version != PG_VERSION_NUM)
|
||||
elog(ERROR_PG_INCOMPATIBLE,
|
||||
_("server version is %d.%d.%d, but must be 8.2 or higher."),
|
||||
server_version / 10000,
|
||||
(server_version / 100) % 100,
|
||||
server_version % 100);
|
||||
_("server version is %d.%d.%d, must be %s or higher."),
|
||||
server_version / 10000,
|
||||
(server_version / 100) % 100,
|
||||
server_version % 100, PG_MAJORVERSION);
|
||||
|
||||
/* confirm block_size (BLCKSZ) and wal_block_size (XLOG_BLCKSZ) */
|
||||
confirm_block_size("block_size", BLCKSZ);
|
||||
if (server_version >= 80400)
|
||||
confirm_block_size("wal_block_size", XLOG_BLCKSZ);
|
||||
confirm_block_size("wal_block_size", XLOG_BLCKSZ);
|
||||
|
||||
if (my_conn)
|
||||
disconnect();
|
||||
|
||||
return server_version;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1013,25 +1014,15 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
|
||||
{
|
||||
PGresult *res;
|
||||
const char *params[2];
|
||||
int server_version;
|
||||
|
||||
params[0] = label;
|
||||
|
||||
reconnect();
|
||||
server_version = get_server_version();
|
||||
if (server_version >= 80400)
|
||||
{
|
||||
/* 2nd argument is 'fast'*/
|
||||
params[1] = smooth ? "false" : "true";
|
||||
res = execute("SELECT * from pg_xlogfile_name_offset(pg_start_backup($1, $2))", 2, params);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* v8.3 always uses smooth checkpoint */
|
||||
if (!smooth && server_version >= 80300)
|
||||
command("CHECKPOINT", 0, NULL);
|
||||
res = execute("SELECT * from pg_xlogfile_name_offset(pg_start_backup($1))", 1, params);
|
||||
}
|
||||
|
||||
/* 2nd argument is 'fast'*/
|
||||
params[1] = smooth ? "false" : "true";
|
||||
res = execute("SELECT * from pg_xlogfile_name_offset(pg_start_backup($1, $2))", 2, params);
|
||||
|
||||
if (backup != NULL)
|
||||
get_lsn(res, &backup->tli, &backup->start_lsn);
|
||||
PQclear(res);
|
||||
@ -1419,7 +1410,6 @@ delete_old_files(const char *root,
|
||||
parray *files,
|
||||
int keep_files,
|
||||
int keep_days,
|
||||
int server_version,
|
||||
bool is_arclog)
|
||||
{
|
||||
int i;
|
||||
@ -1460,7 +1450,7 @@ delete_old_files(const char *root,
|
||||
|
||||
elog(LOG, "%s() %s", __FUNCTION__, file->path);
|
||||
/* Delete completed WALs only. */
|
||||
if (is_arclog && !xlog_is_complete_wal(file, server_version))
|
||||
if (is_arclog && !xlog_is_complete_wal(file))
|
||||
{
|
||||
elog(LOG, "%s() not complete WAL", __FUNCTION__);
|
||||
continue;
|
||||
|
79
data.c
79
data.c
@ -18,10 +18,6 @@
|
||||
#include "storage/block.h"
|
||||
#include "storage/bufpage.h"
|
||||
|
||||
#if PG_VERSION_NUM < 80300
|
||||
#define XLogRecPtrIsInvalid(r) ((r).xrecoff == 0)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
#include <zlib.h>
|
||||
|
||||
@ -156,10 +152,6 @@ doInflate(z_stream *zp, size_t in_size, size_t out_size,void *inbuf,
|
||||
}
|
||||
#endif
|
||||
|
||||
#define PG_PAGE_LAYOUT_VERSION_v80 2 /* 8.0 */
|
||||
#define PG_PAGE_LAYOUT_VERSION_v81 3 /* 8.1 - 8.2 */
|
||||
#define PG_PAGE_LAYOUT_VERSION_v83 4 /* 8.3 - */
|
||||
|
||||
/* 80000 <= PG_VERSION_NUM < 80300 */
|
||||
typedef struct PageHeaderData_v80
|
||||
{
|
||||
@ -201,9 +193,8 @@ typedef struct PageHeaderData_v83
|
||||
|
||||
typedef union DataPage
|
||||
{
|
||||
PageHeaderData_v80 v80; /* 8.0 - 8.2 */
|
||||
PageHeaderData_v83 v83; /* 8.3 - */
|
||||
char data[BLCKSZ];
|
||||
PageHeaderData page_data;
|
||||
char data[BLCKSZ];
|
||||
} DataPage;
|
||||
|
||||
typedef struct BackupPageHeader
|
||||
@ -214,56 +205,27 @@ typedef struct BackupPageHeader
|
||||
} BackupPageHeader;
|
||||
|
||||
static bool
|
||||
parse_page(const DataPage *page, int server_version,
|
||||
parse_page(const DataPage *page,
|
||||
XLogRecPtr *lsn, uint16 *offset, uint16 *length)
|
||||
{
|
||||
uint16 page_layout_version;
|
||||
const PageHeaderData *page_data = &page->page_data;
|
||||
|
||||
/* Determine page layout version */
|
||||
if (server_version < 80100)
|
||||
page_layout_version = PG_PAGE_LAYOUT_VERSION_v80;
|
||||
else if (server_version < 80300)
|
||||
page_layout_version = PG_PAGE_LAYOUT_VERSION_v81;
|
||||
else
|
||||
page_layout_version = PG_PAGE_LAYOUT_VERSION_v83;
|
||||
/* Get lsn from page header */
|
||||
*lsn = PageXLogRecPtrGet(page_data->pd_lsn);
|
||||
|
||||
/* Check normal case */
|
||||
if (server_version < 80300)
|
||||
if (PageGetPageSize(page_data) == BLCKSZ &&
|
||||
PageGetPageLayoutVersion(page_data) == PG_PAGE_LAYOUT_VERSION &&
|
||||
(page_data->pd_flags & ~PD_VALID_FLAG_BITS) == 0 &&
|
||||
page_data->pd_lower >= SizeOfPageHeaderData &&
|
||||
page_data->pd_lower <= page_data->pd_upper &&
|
||||
page_data->pd_upper <= page_data->pd_special &&
|
||||
page_data->pd_special <= BLCKSZ &&
|
||||
page_data->pd_special == MAXALIGN(page_data->pd_special) &&
|
||||
!XLogRecPtrIsInvalid(*lsn))
|
||||
{
|
||||
const PageHeaderData_v80 *v80 = &page->v80;
|
||||
|
||||
if (PageGetPageSize_v80(v80) == BLCKSZ &&
|
||||
PageGetPageLayoutVersion_v80(v80) == page_layout_version &&
|
||||
v80->pd_lower >= SizeOfPageHeaderData_v80 &&
|
||||
v80->pd_lower <= v80->pd_upper &&
|
||||
v80->pd_upper <= v80->pd_special &&
|
||||
v80->pd_special <= BLCKSZ &&
|
||||
v80->pd_special == MAXALIGN(v80->pd_special) &&
|
||||
!XLogRecPtrIsInvalid(*lsn = v80->pd_lsn))
|
||||
{
|
||||
*offset = v80->pd_lower;
|
||||
*length = v80->pd_upper - v80->pd_lower;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const PageHeaderData_v83 *v83 = &page->v83;
|
||||
|
||||
if (PageGetPageSize_v83(v83) == BLCKSZ &&
|
||||
PageGetPageLayoutVersion_v83(v83) == page_layout_version &&
|
||||
(v83->pd_flags & ~PD_VALID_FLAG_BITS_v83) == 0 &&
|
||||
v83->pd_lower >= SizeOfPageHeaderData_v83 &&
|
||||
v83->pd_lower <= v83->pd_upper &&
|
||||
v83->pd_upper <= v83->pd_special &&
|
||||
v83->pd_special <= BLCKSZ &&
|
||||
v83->pd_special == MAXALIGN(v83->pd_special) &&
|
||||
!XLogRecPtrIsInvalid(*lsn = v83->pd_lsn))
|
||||
{
|
||||
*offset = v83->pd_lower;
|
||||
*length = v83->pd_upper - v83->pd_lower;
|
||||
return true;
|
||||
}
|
||||
*offset = page_data->pd_lower;
|
||||
*length = page_data->pd_upper - page_data->pd_lower;
|
||||
return true;
|
||||
}
|
||||
|
||||
*offset = *length = 0;
|
||||
@ -289,7 +251,6 @@ backup_data_file(const char *from_root, const char *to_root,
|
||||
size_t read_len;
|
||||
int errno_tmp;
|
||||
pg_crc32 crc;
|
||||
int server_version;
|
||||
#ifdef HAVE_LIBZ
|
||||
z_stream z;
|
||||
char outbuf[zlibOutSize];
|
||||
@ -351,7 +312,7 @@ backup_data_file(const char *from_root, const char *to_root,
|
||||
#endif
|
||||
|
||||
/* confirm server version */
|
||||
server_version = get_server_version();
|
||||
check_server_version();
|
||||
|
||||
/* read each page and write the page excluding hole */
|
||||
for (blknum = 0;
|
||||
@ -368,7 +329,7 @@ backup_data_file(const char *from_root, const char *to_root,
|
||||
* If a invalid data page was found, fallback to simple copy to ensure
|
||||
* all pages in the file don't have BackupPageHeader.
|
||||
*/
|
||||
if (!parse_page(&page, server_version, &page_lsn,
|
||||
if (!parse_page(&page, &page_lsn,
|
||||
&header.hole_offset, &header.hole_length))
|
||||
{
|
||||
elog(LOG, "%s fall back to simple copy", file->path);
|
||||
|
14
pg_rman.h
14
pg_rman.h
@ -20,16 +20,8 @@
|
||||
#include "utils/pg_crc.h"
|
||||
#include "parray.h"
|
||||
|
||||
#if PG_VERSION_NUM < 80200
|
||||
#define XLOG_BLCKSZ BLCKSZ
|
||||
#endif
|
||||
|
||||
#if PG_VERSION_NUM < 80300
|
||||
#define TXID_CURRENT_SQL "SELECT transactionid FROM pg_locks WHERE locktype = 'transactionid' AND pid = pg_backend_pid();"
|
||||
#include <sys/stat.h>
|
||||
#else
|
||||
/* Query to fetch current transaction ID */
|
||||
#define TXID_CURRENT_SQL "SELECT txid_current();"
|
||||
#endif
|
||||
|
||||
/* Directory/File names */
|
||||
#define DATABASE_DIR "database"
|
||||
@ -241,7 +233,7 @@ extern const char *pgdata_exclude[];
|
||||
/* in backup.c */
|
||||
extern int do_backup(pgBackupOption bkupopt);
|
||||
extern BackupMode parse_backup_mode(const char *value, int elevel);
|
||||
extern int get_server_version(void);
|
||||
extern void check_server_version(void);
|
||||
extern bool fileExists(const char *path);
|
||||
|
||||
/* in restore.c */
|
||||
@ -306,7 +298,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, int server_version);
|
||||
extern bool xlog_is_complete_wal(const pgFile *file);
|
||||
extern void xlog_fname(char *fname, size_t len, TimeLineID tli, XLogRecPtr *lsn);
|
||||
|
||||
/* in data.c */
|
||||
|
6
xlog.c
6
xlog.c
@ -14,10 +14,8 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if PG_VERSION_NUM >= 80400
|
||||
typedef unsigned long Datum;
|
||||
typedef struct MemoryContextData *MemoryContext;
|
||||
#endif
|
||||
|
||||
#include "access/xlog_internal.h"
|
||||
|
||||
@ -37,7 +35,7 @@ typedef union XLogPage
|
||||
* based on ValidXLOGHeader() in src/backend/access/transam/xlog.c.
|
||||
*/
|
||||
bool
|
||||
xlog_is_complete_wal(const pgFile *file, int server_version)
|
||||
xlog_is_complete_wal(const pgFile *file)
|
||||
{
|
||||
FILE *fp;
|
||||
XLogPage page;
|
||||
@ -61,7 +59,7 @@ xlog_is_complete_wal(const pgFile *file, int server_version)
|
||||
return false;
|
||||
if (page.lheader.xlp_seg_size != XLogSegSize)
|
||||
return false;
|
||||
if (server_version >= 80300 && page.lheader.xlp_xlog_blcksz != XLOG_BLCKSZ)
|
||||
if (page.lheader.xlp_xlog_blcksz != XLOG_BLCKSZ)
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user