Skip to content

Commit e2bbf69

Browse files
author
Michael Paquier
committed
Remove code duplication to get a node's current timeline
The same code was duplicated between restore and backup. At the same time this commit introduces routines to fetch the control data file.
1 parent a5a76c1 commit e2bbf69

File tree

4 files changed

+61
-83
lines changed

4 files changed

+61
-83
lines changed

backup.c

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include <dirent.h>
1818
#include <time.h>
1919

20-
#include "catalog/pg_control.h"
2120
#include "libpq/pqsignal.h"
2221
#include "pgut/pgut-port.h"
2322

@@ -54,7 +53,6 @@ static void create_file_list(parray *files,
5453
const char *subdir,
5554
const char *prefix,
5655
bool is_append);
57-
static TimeLineID get_current_timeline(void);
5856

5957
/*
6058
* Take a backup of database and return the list of files backed up.
@@ -1047,27 +1045,3 @@ create_file_list(parray *files,
10471045
fclose(fp);
10481046
}
10491047
}
1050-
1051-
/*
1052-
* Scan control file of given cluster at obtain the current timeline
1053-
* since last checkpoint that occurred on it.
1054-
*/
1055-
static TimeLineID
1056-
get_current_timeline(void)
1057-
{
1058-
char *buffer;
1059-
size_t size;
1060-
ControlFileData control_file;
1061-
1062-
/* First fetch file... */
1063-
buffer = slurpFile(pgdata, "global/pg_control", &size);
1064-
1065-
/* .. Then interpret it */
1066-
if (size != PG_CONTROL_SIZE)
1067-
elog(ERROR_CORRUPTED, "unexpected control file size %d, expected %d",
1068-
(int) size, PG_CONTROL_SIZE);
1069-
memcpy(&control_file, buffer, sizeof(ControlFileData));
1070-
1071-
/* Finally return the timeline wanted */
1072-
return control_file.checkPointCopy.ThisTimeLineID;
1073-
}

pg_arman.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ extern bool copy_file(const char *from_root, const char *to_root,
289289
pgFile *file);
290290

291291
/* in util.c */
292+
extern TimeLineID get_current_timeline(void);
292293
extern void time2iso(char *buf, size_t len, time_t time);
293294
extern const char *status2str(BackupStatus status);
294295
extern void remove_trailing_space(char *buf, int comment_mark);

restore.c

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ static parray * readTimeLineHistory(TimeLineID targetTLI);
2929
static bool satisfy_timeline(const parray *timelines, const pgBackup *backup);
3030
static bool satisfy_recovery_target(const pgBackup *backup,
3131
const pgRecoveryTarget *rt);
32-
static TimeLineID get_current_timeline(void);
3332
static TimeLineID get_fullbackup_timeline(parray *backups,
3433
const pgRecoveryTarget *rt);
3534
static void print_backup_lsn(const pgBackup *backup);
@@ -624,62 +623,6 @@ satisfy_timeline(const parray *timelines, const pgBackup *backup)
624623
return false;
625624
}
626625

627-
/* get TLI of the current database */
628-
static TimeLineID
629-
get_current_timeline(void)
630-
{
631-
ControlFileData ControlFile;
632-
int fd;
633-
char ControlFilePath[MAXPGPATH];
634-
pg_crc32 crc;
635-
TimeLineID ret;
636-
637-
snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", pgdata);
638-
639-
if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1)
640-
{
641-
elog(WARNING, "cannot open pg_controldata file \"%s\": %s",
642-
ControlFilePath, strerror(errno));
643-
return 0;
644-
}
645-
646-
if (read(fd, &ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData))
647-
{
648-
elog(WARNING, "cannot read pg_controldata file \"%s\": %s",
649-
ControlFilePath, strerror(errno));
650-
return 0;
651-
}
652-
close(fd);
653-
654-
/* Check the CRC. */
655-
INIT_CRC32C(crc);
656-
COMP_CRC32C(crc,
657-
(char *) &ControlFile,
658-
offsetof(ControlFileData, crc));
659-
FIN_CRC32C(crc);
660-
661-
if (!EQ_CRC32C(crc, ControlFile.crc))
662-
{
663-
elog(WARNING, "Calculated CRC checksum does not match value stored in file.\n"
664-
"Either the file is corrupt, or it has a different layout than this program\n"
665-
"is expecting. The results below are untrustworthy.\n");
666-
return 0;
667-
}
668-
669-
if (ControlFile.pg_control_version % 65536 == 0 && ControlFile.pg_control_version / 65536 != 0)
670-
{
671-
elog(WARNING, "possible byte ordering mismatch\n"
672-
"The byte ordering used to store the pg_control file might not match the one\n"
673-
"used by this program. In that case the results below would be incorrect, and\n"
674-
"the PostgreSQL installation would be incompatible with this data directory.\n");
675-
return 0;
676-
}
677-
678-
ret = ControlFile.checkPointCopy.ThisTimeLineID;
679-
680-
return ret;
681-
}
682-
683626
/* get TLI of the latest full backup */
684627
static TimeLineID
685628
get_fullbackup_timeline(parray *backups, const pgRecoveryTarget *rt)

util.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,66 @@
1111

1212
#include <time.h>
1313

14+
#include "catalog/pg_control.h"
15+
16+
static void
17+
checkControlFile(ControlFileData *ControlFile)
18+
{
19+
pg_crc32c crc;
20+
21+
/* Calculate CRC */
22+
INIT_CRC32C(crc);
23+
COMP_CRC32C(crc, (char *) ControlFile, offsetof(ControlFileData, crc));
24+
FIN_CRC32C(crc);
25+
26+
/* Then compare it */
27+
if (!EQ_CRC32C(crc, ControlFile->crc))
28+
elog(ERROR_CORRUPTED, "Calculated CRC checksum does not match value stored in file.\n"
29+
"Either the file is corrupt, or it has a different layout than this program\n"
30+
"is expecting. The results below are untrustworthy.\n");
31+
32+
if (ControlFile->pg_control_version % 65536 == 0 && ControlFile->pg_control_version / 65536 != 0)
33+
elog(ERROR_CORRUPTED, "possible byte ordering mismatch\n"
34+
"The byte ordering used to store the pg_control file might not match the one\n"
35+
"used by this program. In that case the results below would be incorrect, and\n"
36+
"the PostgreSQL installation would be incompatible with this data directory.\n");
37+
}
38+
39+
/*
40+
* Verify control file contents in the buffer src, and copy it to *ControlFile.
41+
*/
42+
static void
43+
digestControlFile(ControlFileData *ControlFile, char *src, size_t size)
44+
{
45+
if (size != PG_CONTROL_SIZE)
46+
elog(ERROR_PG_INCOMPATIBLE, "unexpected control file size %d, expected %d\n",
47+
(int) size, PG_CONTROL_SIZE);
48+
49+
memcpy(ControlFile, src, sizeof(ControlFileData));
50+
51+
/* Additional checks on control file */
52+
checkControlFile(ControlFile);
53+
}
54+
55+
/*
56+
* Utility shared by backup and restore to fetch the current timeline
57+
* used by a node.
58+
*/
59+
TimeLineID
60+
get_current_timeline(void)
61+
{
62+
ControlFileData ControlFile;
63+
char *buffer;
64+
size_t size;
65+
66+
/* First fetch file... */
67+
buffer = slurpFile(pgdata, "global/pg_control", &size);
68+
digestControlFile(&ControlFile, buffer, size);
69+
pg_free(buffer);
70+
71+
return ControlFile.checkPointCopy.ThisTimeLineID;
72+
}
73+
1474
/*
1575
* Convert time_t value to ISO-8601 format string
1676
*/

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy