1
0
mirror of https://github.com/postgrespro/pg_probackup.git synced 2025-07-16 07:14:15 +02:00

Fix history file parsing when fetched from archive

History file format has changed from 9.2 to 9.3 to indicate the WAL record
when timeline branched off. In 9.2, the complete WAL file name was used
while in 9.3 the WAL record is used (like 1/4000090). pg_rman contains a
copy of a function of postgres core code to parse the history file that
was not anymore compatible, leading to errors related to timelines.
This commit is contained in:
Michael Paquier
2013-12-10 17:27:51 +09:00
parent 71d019ce56
commit 8aa6b84b98
3 changed files with 23 additions and 40 deletions

View File

@ -306,7 +306,6 @@ 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_logfname2lsn(const char *logfname, XLogRecPtr *lsn);
extern void xlog_fname(char *fname, size_t len, TimeLineID tli, XLogRecPtr *lsn);
/* in data.c */

View File

@ -768,27 +768,40 @@ readTimeLineHistory(TimeLineID targetTLI)
*/
while (fd && fgets(fline, sizeof(fline), fd) != NULL)
{
/* skip leading whitespaces and check for # comment */
char *ptr;
char *endptr;
TimeLineID tli;
uint32 switchpoint_hi;
uint32 switchpoint_lo;
int nfields;
for (ptr = fline; *ptr; ptr++)
{
if (!IsSpace(*ptr))
if (!isspace((unsigned char) *ptr))
break;
}
if (*ptr == '\0' || *ptr == '#')
continue;
/* Parse one entry... */
nfields = sscanf(fline, "%u\t%X/%X", &tli, &switchpoint_hi, &switchpoint_lo);
timeline = pgut_new(pgTimeLine);
timeline->tli = 0;
timeline->end = 0;
/* expect a numeric timeline ID as first field of line */
timeline->tli = (TimeLineID) strtoul(ptr, &endptr, 0);
if (endptr == ptr)
timeline->tli = tli;
if (nfields < 1)
{
/* expect a numeric timeline ID as first field of line */
elog(ERROR_CORRUPTED,
_("syntax error(timeline ID) in history file: %s"),
_("syntax error in history file: %s. Expected a numeric timeline ID."),
fline);
}
if (nfields != 3)
elog(ERROR_CORRUPTED,
_("syntax error in history file: %s. Expected a transaction log switchpoint location."),
fline);
if (last_timeline && timeline->tli <= last_timeline->tli)
@ -799,20 +812,9 @@ readTimeLineHistory(TimeLineID targetTLI)
parray_insert(result, 0, timeline);
last_timeline = timeline;
/* parse end point(logfname, xid) in the timeline */
for (ptr = endptr; *ptr; ptr++)
{
if (!IsSpace(*ptr))
break;
}
if (*ptr == '\0' || *ptr == '#')
elog(ERROR_CORRUPTED,
_("End logfile must follow Timeline ID."));
if (!xlog_logfname2lsn(ptr, &timeline->end))
elog(ERROR_CORRUPTED,
_("syntax error(endfname) in history file: %s"), fline);
/* we ignore the remainder of each line */
/* Calculate the end lsn finally */
timeline->end = (XLogRecPtr)
((uint64) switchpoint_hi << 32) | switchpoint_lo;
}
if (fd)

18
xlog.c
View File

@ -109,24 +109,6 @@ xlog_is_complete_wal(const pgFile *file, int server_version)
return true;
}
bool
xlog_logfname2lsn(const char *logfname, XLogRecPtr *lsn)
{
uint32 tli;
uint32 xlogid;
uint32 xrecoff;
if (sscanf(logfname, "%08X%08X%08X",
&tli, &xlogid, &xrecoff) != 3)
return false;
xrecoff *= XLogSegSize;
/* Finish calculation of LSN */
*lsn = (XLogRecPtr) ((uint64) xlogid << 32) | xrecoff;
return true;
}
/*
* based on XLogFileName() in xlog_internal.h
*/