1
0
mirror of https://github.com/postgrespro/pg_probackup.git synced 2025-01-05 13:20:31 +02:00

Issue #20. Check system_identifier for PostgreSQL9.5.

System identifier is fetched via pg_read_binary_file() for Pg 9.5.
This commit is contained in:
Arthur Zakirov 2017-12-11 15:44:54 +03:00
parent a528352919
commit 596ac3a37b
6 changed files with 89 additions and 36 deletions

View File

@ -915,32 +915,15 @@ check_server_version(void)
static void
check_system_identifiers(void)
{
PGresult *res;
uint64 system_id_conn;
uint64 system_id_pgdata;
char *val;
system_id_pgdata = get_system_identifier(pgdata);
system_id_conn = get_remote_system_identifier(backup_conn);
if (server_version < 90600) {
// Skip match system_identifier between backup data directory and DB connection as
// pg_control_system() exists only in 9.6 onwards
} else {
res = pgut_execute(backup_conn,
"SELECT system_identifier FROM pg_control_system()",
0, NULL, true);
val = PQgetvalue(res, 0, 0);
if (!parse_uint64(val, &system_id_conn, 0))
{
PQclear(res);
elog(ERROR, "%s is not system_identifier", val);
}
PQclear(res);
if (system_id_conn != system_identifier)
elog(ERROR, "Backup data directory was initialized for system id %ld, but connected instance system id is %ld",
system_identifier, system_id_conn);
}
if (system_id_conn != system_identifier)
elog(ERROR, "Backup data directory was initialized for system id %ld, but connected instance system id is %ld",
system_identifier, system_id_conn);
if (system_id_pgdata != system_identifier)
elog(ERROR, "Backup data directory was initialized for system id %ld, but target backup directory system id is %ld",
system_identifier, system_id_pgdata);

View File

@ -82,3 +82,35 @@ slurpFile(const char *datadir, const char *path, size_t *filesize, bool safe)
*filesize = len;
return buffer;
}
/*
* Receive a single file as a malloc'd buffer.
*/
char *
fetchFile(PGconn *conn, const char *filename, size_t *filesize)
{
PGresult *res;
char *result;
const char *params[1];
int len;
params[0] = filename;
res = pgut_execute(conn, "SELECT pg_read_binary_file($1)",
1, params, false);
/* sanity check the result set */
if (PQntuples(res) != 1 || PQgetisnull(res, 0, 0))
elog(ERROR, "unexpected result set while fetching remote file \"%s\"",
filename);
/* Read result to local variables */
len = PQgetlength(res, 0, 0);
result = pg_malloc(len + 1);
memcpy(result, PQgetvalue(res, 0, 0), len);
result[len] = '\0';
PQclear(res);
*filesize = len;
return result;
}

View File

@ -367,6 +367,7 @@ extern char *slurpFile(const char *datadir,
const char *path,
size_t *filesize,
bool safe);
extern char *fetchFile(PGconn *conn, const char *filename, size_t *filesize);
/* in help.c */
extern void help_pg_probackup(void);
@ -458,6 +459,7 @@ extern uint32 get_data_checksum_version(bool safe);
extern char *base36enc(long unsigned int value);
extern long unsigned int base36dec(const char *text);
extern uint64 get_system_identifier(char *pgdata);
extern uint64 get_remote_system_identifier(PGconn *conn);
extern pg_time_t timestamptz_to_time_t(TimestampTz t);
extern void pgBackup_init(pgBackup *backup);

View File

@ -120,6 +120,39 @@ get_system_identifier(char *pgdata_path)
return ControlFile.system_identifier;
}
uint64
get_remote_system_identifier(PGconn *conn)
{
#if PG_VERSION_NUM >= 90600
PGresult *res;
uint64 system_id_conn;
char *val;
res = pgut_execute(conn,
"SELECT system_identifier FROM pg_control_system()",
0, NULL, true);
val = PQgetvalue(res, 0, 0);
if (!parse_uint64(val, &system_id_conn, 0))
{
PQclear(res);
elog(ERROR, "%s is not system_identifier", val);
}
PQclear(res);
return system_id_conn;
#else
char *buffer;
size_t size;
ControlFileData ControlFile;
buffer = fetchFile(conn, "global/pg_control", &size);
digestControlFile(&ControlFile, buffer, size);
pg_free(buffer);
return ControlFile.system_identifier;
#endif
}
uint32
get_data_checksum_version(bool safe)
{

View File

@ -1498,7 +1498,7 @@ pgut_set_port(const char *new_port)
PGresult *
pgut_execute(PGconn* conn, const char *query, int nParams, const char **params,
bool exit_on_error)
bool text_result)
{
PGresult *res;
@ -1528,22 +1528,24 @@ pgut_execute(PGconn* conn, const char *query, int nParams, const char **params,
if (nParams == 0)
res = PQexec(conn, query);
else
res = PQexecParams(conn, query, nParams, NULL, params, NULL, NULL, 0);
res = PQexecParams(conn, query, nParams, NULL, params, NULL, NULL,
/*
* Specify zero to obtain results in text format,
* or one to obtain results in binary format.
*/
(text_result) ? 0 : 1);
on_after_exec();
if (exit_on_error)
switch (PQresultStatus(res))
{
switch (PQresultStatus(res))
{
case PGRES_TUPLES_OK:
case PGRES_COMMAND_OK:
case PGRES_COPY_IN:
break;
default:
elog(ERROR, "query failed: %squery was: %s",
PQerrorMessage(conn), query);
break;
}
case PGRES_TUPLES_OK:
case PGRES_COMMAND_OK:
case PGRES_COPY_IN:
break;
default:
elog(ERROR, "query failed: %squery was: %s",
PQerrorMessage(conn), query);
break;
}
return res;

View File

@ -125,7 +125,8 @@ extern PGconn *pgut_connect_replication_extended(const char *pghost, const char
const char *dbname, const char *login,
const char *pwd);
extern void pgut_disconnect(PGconn *conn);
extern PGresult *pgut_execute(PGconn* conn, const char *query, int nParams, const char **params, bool exit_on_error);
extern PGresult *pgut_execute(PGconn* conn, const char *query, int nParams,
const char **params, bool text_result);
extern bool pgut_send(PGconn* conn, const char *query, int nParams, const char **params, int elevel);
extern void pgut_cancel(PGconn* conn);
extern int pgut_wait(int num, PGconn *connections[], struct timeval *timeout);