Skip to content

Commit 596ac3a

Browse files
committed
Issue #20. Check system_identifier for PostgreSQL9.5.
System identifier is fetched via pg_read_binary_file() for Pg 9.5.
1 parent a528352 commit 596ac3a

File tree

6 files changed

+89
-36
lines changed

6 files changed

+89
-36
lines changed

src/backup.c

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -915,32 +915,15 @@ check_server_version(void)
915915
static void
916916
check_system_identifiers(void)
917917
{
918-
PGresult *res;
919918
uint64 system_id_conn;
920919
uint64 system_id_pgdata;
921-
char *val;
922920

923921
system_id_pgdata = get_system_identifier(pgdata);
922+
system_id_conn = get_remote_system_identifier(backup_conn);
924923

925-
if (server_version < 90600) {
926-
// Skip match system_identifier between backup data directory and DB connection as
927-
// pg_control_system() exists only in 9.6 onwards
928-
} else {
929-
res = pgut_execute(backup_conn,
930-
"SELECT system_identifier FROM pg_control_system()",
931-
0, NULL, true);
932-
val = PQgetvalue(res, 0, 0);
933-
if (!parse_uint64(val, &system_id_conn, 0))
934-
{
935-
PQclear(res);
936-
elog(ERROR, "%s is not system_identifier", val);
937-
}
938-
PQclear(res);
939-
940-
if (system_id_conn != system_identifier)
941-
elog(ERROR, "Backup data directory was initialized for system id %ld, but connected instance system id is %ld",
942-
system_identifier, system_id_conn);
943-
}
924+
if (system_id_conn != system_identifier)
925+
elog(ERROR, "Backup data directory was initialized for system id %ld, but connected instance system id is %ld",
926+
system_identifier, system_id_conn);
944927
if (system_id_pgdata != system_identifier)
945928
elog(ERROR, "Backup data directory was initialized for system id %ld, but target backup directory system id is %ld",
946929
system_identifier, system_id_pgdata);

src/fetch.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,35 @@ slurpFile(const char *datadir, const char *path, size_t *filesize, bool safe)
8282
*filesize = len;
8383
return buffer;
8484
}
85+
86+
/*
87+
* Receive a single file as a malloc'd buffer.
88+
*/
89+
char *
90+
fetchFile(PGconn *conn, const char *filename, size_t *filesize)
91+
{
92+
PGresult *res;
93+
char *result;
94+
const char *params[1];
95+
int len;
96+
97+
params[0] = filename;
98+
res = pgut_execute(conn, "SELECT pg_read_binary_file($1)",
99+
1, params, false);
100+
101+
/* sanity check the result set */
102+
if (PQntuples(res) != 1 || PQgetisnull(res, 0, 0))
103+
elog(ERROR, "unexpected result set while fetching remote file \"%s\"",
104+
filename);
105+
106+
/* Read result to local variables */
107+
len = PQgetlength(res, 0, 0);
108+
result = pg_malloc(len + 1);
109+
memcpy(result, PQgetvalue(res, 0, 0), len);
110+
result[len] = '\0';
111+
112+
PQclear(res);
113+
*filesize = len;
114+
115+
return result;
116+
}

src/pg_probackup.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ extern char *slurpFile(const char *datadir,
367367
const char *path,
368368
size_t *filesize,
369369
bool safe);
370+
extern char *fetchFile(PGconn *conn, const char *filename, size_t *filesize);
370371

371372
/* in help.c */
372373
extern void help_pg_probackup(void);
@@ -458,6 +459,7 @@ extern uint32 get_data_checksum_version(bool safe);
458459
extern char *base36enc(long unsigned int value);
459460
extern long unsigned int base36dec(const char *text);
460461
extern uint64 get_system_identifier(char *pgdata);
462+
extern uint64 get_remote_system_identifier(PGconn *conn);
461463
extern pg_time_t timestamptz_to_time_t(TimestampTz t);
462464
extern void pgBackup_init(pgBackup *backup);
463465

src/util.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,39 @@ get_system_identifier(char *pgdata_path)
120120
return ControlFile.system_identifier;
121121
}
122122

123+
uint64
124+
get_remote_system_identifier(PGconn *conn)
125+
{
126+
#if PG_VERSION_NUM >= 90600
127+
PGresult *res;
128+
uint64 system_id_conn;
129+
char *val;
130+
131+
res = pgut_execute(conn,
132+
"SELECT system_identifier FROM pg_control_system()",
133+
0, NULL, true);
134+
val = PQgetvalue(res, 0, 0);
135+
if (!parse_uint64(val, &system_id_conn, 0))
136+
{
137+
PQclear(res);
138+
elog(ERROR, "%s is not system_identifier", val);
139+
}
140+
PQclear(res);
141+
142+
return system_id_conn;
143+
#else
144+
char *buffer;
145+
size_t size;
146+
ControlFileData ControlFile;
147+
148+
buffer = fetchFile(conn, "global/pg_control", &size);
149+
digestControlFile(&ControlFile, buffer, size);
150+
pg_free(buffer);
151+
152+
return ControlFile.system_identifier;
153+
#endif
154+
}
155+
123156
uint32
124157
get_data_checksum_version(bool safe)
125158
{

src/utils/pgut.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,7 +1498,7 @@ pgut_set_port(const char *new_port)
14981498

14991499
PGresult *
15001500
pgut_execute(PGconn* conn, const char *query, int nParams, const char **params,
1501-
bool exit_on_error)
1501+
bool text_result)
15021502
{
15031503
PGresult *res;
15041504

@@ -1528,22 +1528,24 @@ pgut_execute(PGconn* conn, const char *query, int nParams, const char **params,
15281528
if (nParams == 0)
15291529
res = PQexec(conn, query);
15301530
else
1531-
res = PQexecParams(conn, query, nParams, NULL, params, NULL, NULL, 0);
1531+
res = PQexecParams(conn, query, nParams, NULL, params, NULL, NULL,
1532+
/*
1533+
* Specify zero to obtain results in text format,
1534+
* or one to obtain results in binary format.
1535+
*/
1536+
(text_result) ? 0 : 1);
15321537
on_after_exec();
15331538

1534-
if (exit_on_error)
1539+
switch (PQresultStatus(res))
15351540
{
1536-
switch (PQresultStatus(res))
1537-
{
1538-
case PGRES_TUPLES_OK:
1539-
case PGRES_COMMAND_OK:
1540-
case PGRES_COPY_IN:
1541-
break;
1542-
default:
1543-
elog(ERROR, "query failed: %squery was: %s",
1544-
PQerrorMessage(conn), query);
1545-
break;
1546-
}
1541+
case PGRES_TUPLES_OK:
1542+
case PGRES_COMMAND_OK:
1543+
case PGRES_COPY_IN:
1544+
break;
1545+
default:
1546+
elog(ERROR, "query failed: %squery was: %s",
1547+
PQerrorMessage(conn), query);
1548+
break;
15471549
}
15481550

15491551
return res;

src/utils/pgut.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ extern PGconn *pgut_connect_replication_extended(const char *pghost, const char
125125
const char *dbname, const char *login,
126126
const char *pwd);
127127
extern void pgut_disconnect(PGconn *conn);
128-
extern PGresult *pgut_execute(PGconn* conn, const char *query, int nParams, const char **params, bool exit_on_error);
128+
extern PGresult *pgut_execute(PGconn* conn, const char *query, int nParams,
129+
const char **params, bool text_result);
129130
extern bool pgut_send(PGconn* conn, const char *query, int nParams, const char **params, int elevel);
130131
extern void pgut_cancel(PGconn* conn);
131132
extern int pgut_wait(int num, PGconn *connections[], struct timeval *timeout);

0 commit comments

Comments
 (0)