Skip to content

Commit

Permalink
Fix build against PG 11.
Browse files Browse the repository at this point in the history
Rest in peace XLogSegSize macro!  Long live wal_segmeng_size!
wal_segment_size's value read from the cluster's control file.  Its
value is set during initdb'ing a cluster and cannot be changed, so
no need to remember it in the backup catalog or checked every time.
  • Loading branch information
amitlan committed Jun 15, 2018
1 parent 4a8bf4d commit 3ef3a09
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 17 deletions.
26 changes: 21 additions & 5 deletions backup.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
#include <time.h>
#include <math.h>

#include "libpq/pqsignal.h"
#include "catalog/pg_control.h"
#include "common/controldata_utils.h"
#include "libpq/pqsignal.h"
#include "pgut/pgut-port.h"

#define TIMEOUT_ARCHIVE 10 /* wait 10 sec until WAL archive complete */
#define XLogSegOffsetBits ((uint32) log2(XLogSegSize))

static bool in_backup = false; /* TODO: more robust logic */
static parray *cleanup_list; /* list of command to execute at error processing for snapshot */
Expand Down Expand Up @@ -72,6 +72,8 @@ static int strCompare(const void *str1, const void *str2);
static void create_file_list(parray *files, const char *root, const char *prefix, bool is_append);
static void check_server_version(void);

static int wal_segment_size = 0;

/*
* Take a backup of database.
*/
Expand Down Expand Up @@ -643,7 +645,8 @@ do_backup_arclog(parray *backup_list)
dir_list_file(files, arclog_path, NULL, true, false);

/* remove WALs archived after pg_stop_backup()/pg_switch_wal() */
xlog_fname(last_wal, lengthof(last_wal), current.tli, &current.stop_lsn);
xlog_fname(last_wal, lengthof(last_wal), current.tli, &current.stop_lsn,
wal_segment_size);
for (i = 0; i < parray_num(files); i++)
{
pgFile *file = (pgFile *) parray_get(files, i);
Expand Down Expand Up @@ -828,6 +831,9 @@ do_backup(pgBackupOption bkupopt)
int keep_data_generations = bkupopt.keep_data_generations;
int keep_data_days = bkupopt.keep_data_days;

ControlFileData *controlFile;
bool crc_ok;

/* PGDATA and BACKUP_MODE are always required */
if (pgdata == NULL)
ereport(ERROR,
Expand Down Expand Up @@ -879,6 +885,14 @@ do_backup(pgBackupOption bkupopt)
}
#endif

controlFile = get_controlfile(pgdata, "pg_rman", &crc_ok);
if (!crc_ok)
ereport(WARNING,
(errmsg("control file appears to be corrupt"),
errdetail("Calculated CRC checksum does not match value stored in file.")));
wal_segment_size = controlFile->xlog_seg_size;
pg_free(controlFile);

/* Check that we're working with the correct database cluster */
check_system_identifier();

Expand Down Expand Up @@ -1308,7 +1322,8 @@ get_lsn(PGresult *res, TimeLineID *timeline, XLogRecPtr *lsn)
PQerrorMessage(connection))));
}

xrecoff += off_upper << XLogSegOffsetBits;
Assert(wal_segment_size > 0);
xrecoff += off_upper << ((uint32) log2(wal_segment_size));

*lsn = (XLogRecPtr) ((uint64) xlogid << 32) | xrecoff;
return;
Expand Down Expand Up @@ -1688,7 +1703,8 @@ delete_old_files(const char *root,

elog(DEBUG, "checking \"%s\"", file->path);
/* Delete completed WALs only. */
if (is_arclog && !xlog_is_complete_wal(file))
Assert(wal_segment_size > 0);
if (is_arclog && !xlog_is_complete_wal(file, wal_segment_size))
{
elog(DEBUG, "this is not complete WAL: \"%s\"", file->path);
continue;
Expand Down
9 changes: 5 additions & 4 deletions pg_rman.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,10 @@ 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 wal_segment_size);
extern bool xlog_logfname2lsn(const char *logfname, XLogRecPtr *lsn);
extern void xlog_fname(char *fname, size_t len, TimeLineID tli, XLogRecPtr *lsn);
extern void xlog_fname(char *fname, size_t len, TimeLineID tli, XLogRecPtr *lsn,
int wal_segment_size);

/* in data.c */
extern bool backup_data_file(const char *from_root, const char *to_root,
Expand Down Expand Up @@ -342,9 +343,9 @@ extern bool is_pg_running(void);
#define PGRMAN_COMP_CRC32(crc, data, len) COMP_CRC32C(crc, data, len)
#define PGRMAN_EQ_CRC32(c1, c2) EQ_CRC32C(c1, c2)

#define NextLogSeg(logId, logSeg) \
#define NextLogSeg(logId, logSeg, wal_segment_size) \
do { \
if ((logSeg) >= XLogSegmentsPerXLogId - 1) \
if ((logSeg) >= XLogSegmentsPerXLogId((wal_segment_size)) - 1) \
{ \
(logId)++; \
(logSeg) = 0; \
Expand Down
26 changes: 23 additions & 3 deletions restore.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include <sys/types.h>
#include <unistd.h>

#include "catalog/pg_control.h"
#include "common/controldata_utils.h"
#include "common/fe_memutils.h"

static void backup_online_files(bool re_recovery);
Expand All @@ -39,6 +41,8 @@ static bool existsTimeLineHistory(TimeLineID probeTLI);
static void print_backup_id(const pgBackup *backup);
static void search_next_wal(const char *path, uint32 *needId, uint32 *needSeg, parray *timelines);

static int wal_segment_size = 0;

int
do_restore(const char *target_time,
const char *target_xid,
Expand All @@ -64,6 +68,9 @@ do_restore(const char *target_time,
uint32 needSeg = 0;
pgRecoveryTarget *rt = NULL;

ControlFileData *controlFile;
bool crc_ok;

/* PGDATA and ARCLOG_PATH are always required */
if (pgdata == NULL)
ereport(ERROR,
Expand Down Expand Up @@ -117,6 +124,14 @@ do_restore(const char *target_time,
(errcode(ERROR_SYSTEM),
errmsg("could not get list of backup already taken")));

controlFile = get_controlfile(pgdata, "pg_rman", &crc_ok);
if (!crc_ok)
ereport(WARNING,
(errmsg("control file appears to be corrupt"),
errdetail("Calculated CRC checksum does not match value stored in file.")));
wal_segment_size = controlFile->xlog_seg_size;
pg_free(controlFile);

cur_tli = get_current_timeline();
elog(DEBUG, "the current timeline ID of database cluster is %d", cur_tli);

Expand Down Expand Up @@ -286,7 +301,7 @@ do_restore(const char *target_time,
{
pgBackup *backup = (pgBackup *) parray_get(backups, last_restored_index);
needId = (uint32) (backup->start_lsn >> 32);
needSeg = (uint32) backup->start_lsn / XLogSegSize;
needSeg = (uint32) backup->start_lsn / wal_segment_size;
}

if (verbose)
Expand Down Expand Up @@ -1112,13 +1127,18 @@ search_next_wal(const char *path, uint32 *needId, uint32 *needSeg, parray *timel
char xlogpath[MAXPGPATH];
struct stat st;

Assert(wal_segment_size > 0);

count = 0;
for (;;)
{
for (i = 0; i < parray_num(timelines); i++)
{
pgTimeLine *timeline = (pgTimeLine *) parray_get(timelines, i);
XLogFileName(xlogfname, timeline->tli, *needId * XLogSegmentsPerXLogId + *needSeg);
XLogFileName(xlogfname,
timeline->tli,
*needId * XLogSegmentsPerXLogId(wal_segment_size) + *needSeg,
wal_segment_size);
join_path_components(xlogpath, path, xlogfname);

if (stat(xlogpath, &st) == 0)
Expand Down Expand Up @@ -1147,7 +1167,7 @@ search_next_wal(const char *path, uint32 *needId, uint32 *needSeg, parray *timel
parray_remove(timelines, i + 1);
/* XXX: should we add a linebreak when we find a timeline? */

NextLogSeg(*needId, *needSeg);
NextLogSeg(*needId, *needSeg, wal_segment_size);
}
}

Expand Down
11 changes: 6 additions & 5 deletions xlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ typedef union XLogPage
* 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 wal_segment_size)
{
FILE *fp;
XLogPage page;
Expand All @@ -56,7 +56,7 @@ xlog_is_complete_wal(const pgFile *file)
return false;
if ((page.header.xlp_info & XLP_LONG_HEADER) == 0)
return false;
if (page.lheader.xlp_seg_size != XLogSegSize)
if (page.lheader.xlp_seg_size != wal_segment_size)
return false;
if (page.lheader.xlp_xlog_blcksz != XLOG_BLCKSZ)
return false;
Expand All @@ -65,7 +65,7 @@ xlog_is_complete_wal(const pgFile *file)
* check size (actual file size, not backup file size)
* TODO: Support pre-compressed xlog. They might have different file sizes.
*/
if (file->size != XLogSegSize)
if (file->size != wal_segment_size)
return false;

return true;
Expand All @@ -75,13 +75,14 @@ xlog_is_complete_wal(const pgFile *file)
* based on XLogFileName() in xlog_internal.h
*/
void
xlog_fname(char *fname, size_t len, TimeLineID tli, XLogRecPtr *lsn)
xlog_fname(char *fname, size_t len, TimeLineID tli, XLogRecPtr *lsn,
int wal_segment_size)
{
uint32 xlogid, xrecoff;

xlogid = (uint32) (*lsn >> 32);
xrecoff = (uint32) *lsn;

snprintf(fname, len, "%08X%08X%08X", tli,
xlogid, xrecoff / XLogSegSize);
xlogid, xrecoff / wal_segment_size);
}

0 comments on commit 3ef3a09

Please sign in to comment.