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:
parent
a528352919
commit
596ac3a37b
25
src/backup.c
25
src/backup.c
@ -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);
|
||||
|
32
src/fetch.c
32
src/fetch.c
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
33
src/util.c
33
src/util.c
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user