mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2025-01-26 11:54:25 +02:00
8aa6b84b98
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.
122 lines
3.2 KiB
C
122 lines
3.2 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* xlog.c: Parse WAL files.
|
|
*
|
|
* Copyright (c) 2009-2013, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "pg_rman.h"
|
|
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#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"
|
|
|
|
#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_v90 0xD064 /* 9.0 */
|
|
#define XLOG_PAGE_MAGIC_v91 0xD066 /* 9.1 */
|
|
#define XLOG_PAGE_MAGIC_v92 0xD071 /* 9.2 */
|
|
#define XLOG_PAGE_MAGIC_v93 0xD075 /* 9.2 */
|
|
|
|
/*
|
|
* XLogLongPageHeaderData is modified in 8.3, but the layout is compatible
|
|
* except xlp_xlog_blcksz.
|
|
*/
|
|
typedef union XLogPage
|
|
{
|
|
XLogPageHeaderData header;
|
|
XLogLongPageHeaderData lheader;
|
|
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, int server_version)
|
|
{
|
|
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)
|
|
{
|
|
fclose(fp);
|
|
return false;
|
|
}
|
|
fclose(fp);
|
|
|
|
/* xlog_page_magic from server version */
|
|
if (server_version < 80000)
|
|
return false; /* never happen */
|
|
else 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 < 90000)
|
|
xlog_page_magic = XLOG_PAGE_MAGIC_v84;
|
|
else if (server_version < 90100)
|
|
xlog_page_magic = XLOG_PAGE_MAGIC_v90;
|
|
else if (server_version < 90200)
|
|
xlog_page_magic = XLOG_PAGE_MAGIC_v91;
|
|
else if (server_version < 90300)
|
|
xlog_page_magic = XLOG_PAGE_MAGIC_v92;
|
|
else if (server_version < 90400)
|
|
xlog_page_magic = XLOG_PAGE_MAGIC_v93;
|
|
else
|
|
return false; /* not supported */
|
|
|
|
/* 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) == 0)
|
|
return false;
|
|
if (page.lheader.xlp_seg_size != XLogSegSize)
|
|
return false;
|
|
if (server_version >= 80300 && page.lheader.xlp_xlog_blcksz != XLOG_BLCKSZ)
|
|
return false;
|
|
|
|
/*
|
|
* check size (actual file size, not backup file size)
|
|
* TODO: Support pre-compressed xlog. They might have different file sizes.
|
|
*/
|
|
if (file->size != XLogSegSize)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* based on XLogFileName() in xlog_internal.h
|
|
*/
|
|
void
|
|
xlog_fname(char *fname, size_t len, TimeLineID tli, XLogRecPtr *lsn)
|
|
{
|
|
snprintf(fname, len, "%08X%08X%08X", tli,
|
|
(uint32) (*lsn / XLogSegSize),
|
|
(uint32) (*lsn % XLogSegSize));
|
|
}
|