mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2024-12-03 09:59:53 +02:00
PGPRO-1290: Check connected server version with build version
This commit is contained in:
parent
c408a0ea47
commit
d8005d5496
91
src/backup.c
91
src/backup.c
@ -934,6 +934,8 @@ do_backup(time_t start_time)
|
||||
static void
|
||||
check_server_version(void)
|
||||
{
|
||||
PGresult *res;
|
||||
|
||||
/* confirm server version */
|
||||
server_version = PQserverVersion(backup_conn);
|
||||
|
||||
@ -958,6 +960,39 @@ check_server_version(void)
|
||||
"server version is %s, must be %s or higher for backup from replica",
|
||||
server_version_str, "9.6");
|
||||
|
||||
res = pgut_execute_extended(backup_conn, "SELECT pgpro_edition()",
|
||||
0, NULL, true, true);
|
||||
|
||||
/*
|
||||
* Check major version of connected PostgreSQL and major version of
|
||||
* compiled PostgreSQL.
|
||||
*/
|
||||
#ifdef PGPRO_VERSION
|
||||
if (PQresultStatus(res) == PGRES_FATAL_ERROR)
|
||||
/* It seems we connected to PostgreSQL (not Postgres Pro) */
|
||||
elog(ERROR, "%s was built with Postgres Pro %s %s, "
|
||||
"but connection made with PostgreSQL %s",
|
||||
PROGRAM_NAME, PG_MAJORVERSION, PGPRO_EDITION, server_version_str);
|
||||
else if (strcmp(server_version_str, PG_MAJORVERSION) != 0 &&
|
||||
strcmp(PQgetvalue(res, 0, 0), PGPRO_EDITION) != 0)
|
||||
elog(ERROR, "%s was built with Postgres Pro %s %s, "
|
||||
"but connection made with Postgres Pro %s %s",
|
||||
PROGRAM_NAME, PG_MAJORVERSION, PGPRO_EDITION,
|
||||
server_version_str, PQgetvalue(res, 0, 0));
|
||||
#else
|
||||
if (PQresultStatus(res) != PGRES_FATAL_ERROR)
|
||||
/* It seems we connected to Postgres Pro (not PostgreSQL) */
|
||||
elog(ERROR, "%s was built with PostgreSQL %s, "
|
||||
"but connection made with Postgres Pro %s %s",
|
||||
PROGRAM_NAME, PG_MAJORVERSION,
|
||||
server_version_str, PQgetvalue(res, 0, 0));
|
||||
else if (strcmp(server_version_str, PG_MAJORVERSION) != 0)
|
||||
elog(ERROR, "%s was built with PostgreSQL %s, but connection made with %s",
|
||||
PROGRAM_NAME, PG_MAJORVERSION, server_version_str);
|
||||
#endif
|
||||
|
||||
PQclear(res);
|
||||
|
||||
/* Do exclusive backup only for PostgreSQL 9.5 */
|
||||
exclusive_backup = server_version < 90600 ||
|
||||
current.backup_mode == BACKUP_MODE_DIFF_PTRACK;
|
||||
@ -997,7 +1032,7 @@ confirm_block_size(const char *name, int blcksz)
|
||||
char *endp;
|
||||
int block_size;
|
||||
|
||||
res = pgut_execute(backup_conn, "SELECT pg_catalog.current_setting($1)", 1, &name, true);
|
||||
res = pgut_execute(backup_conn, "SELECT pg_catalog.current_setting($1)", 1, &name);
|
||||
if (PQntuples(res) != 1 || PQnfields(res) != 1)
|
||||
elog(ERROR, "cannot get %s: %s", name, PQerrorMessage(backup_conn));
|
||||
|
||||
@ -1033,14 +1068,12 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
|
||||
res = pgut_execute(conn,
|
||||
"SELECT pg_catalog.pg_start_backup($1, $2, false)",
|
||||
2,
|
||||
params,
|
||||
true);
|
||||
params);
|
||||
else
|
||||
res = pgut_execute(conn,
|
||||
"SELECT pg_catalog.pg_start_backup($1, $2)",
|
||||
2,
|
||||
params,
|
||||
true);
|
||||
params);
|
||||
|
||||
/* Extract timeline and LSN from results of pg_start_backup() */
|
||||
XLogDataFromLSN(PQgetvalue(res, 0, 0), &xlogid, &xrecoff);
|
||||
@ -1091,13 +1124,13 @@ pg_switch_wal(PGconn *conn)
|
||||
PGresult *res;
|
||||
|
||||
/* Remove annoying NOTICE messages generated by backend */
|
||||
res = pgut_execute(conn, "SET client_min_messages = warning;", 0, NULL, true);
|
||||
res = pgut_execute(conn, "SET client_min_messages = warning;", 0, NULL);
|
||||
PQclear(res);
|
||||
|
||||
if (server_version >= 100000)
|
||||
res = pgut_execute(conn, "SELECT * FROM pg_catalog.pg_switch_wal()", 0, NULL, true);
|
||||
res = pgut_execute(conn, "SELECT * FROM pg_catalog.pg_switch_wal()", 0, NULL);
|
||||
else
|
||||
res = pgut_execute(conn, "SELECT * FROM pg_catalog.pg_switch_xlog()", 0, NULL, true);
|
||||
res = pgut_execute(conn, "SELECT * FROM pg_catalog.pg_switch_xlog()", 0, NULL);
|
||||
|
||||
PQclear(res);
|
||||
}
|
||||
@ -1113,7 +1146,7 @@ pg_ptrack_support(void)
|
||||
|
||||
res_db = pgut_execute(backup_conn,
|
||||
"SELECT proname FROM pg_proc WHERE proname='ptrack_version'",
|
||||
0, NULL, true);
|
||||
0, NULL);
|
||||
if (PQntuples(res_db) == 0)
|
||||
{
|
||||
PQclear(res_db);
|
||||
@ -1123,7 +1156,7 @@ pg_ptrack_support(void)
|
||||
|
||||
res_db = pgut_execute(backup_conn,
|
||||
"SELECT pg_catalog.ptrack_version()",
|
||||
0, NULL, true);
|
||||
0, NULL);
|
||||
if (PQntuples(res_db) == 0)
|
||||
{
|
||||
PQclear(res_db);
|
||||
@ -1148,7 +1181,7 @@ pg_ptrack_enable(void)
|
||||
{
|
||||
PGresult *res_db;
|
||||
|
||||
res_db = pgut_execute(backup_conn, "show ptrack_enable", 0, NULL, true);
|
||||
res_db = pgut_execute(backup_conn, "show ptrack_enable", 0, NULL);
|
||||
|
||||
if (strcmp(PQgetvalue(res_db, 0, 0), "on") != 0)
|
||||
{
|
||||
@ -1165,7 +1198,7 @@ pg_checksum_enable(void)
|
||||
{
|
||||
PGresult *res_db;
|
||||
|
||||
res_db = pgut_execute(backup_conn, "show data_checksums", 0, NULL, true);
|
||||
res_db = pgut_execute(backup_conn, "show data_checksums", 0, NULL);
|
||||
|
||||
if (strcmp(PQgetvalue(res_db, 0, 0), "on") != 0)
|
||||
{
|
||||
@ -1182,7 +1215,7 @@ pg_is_in_recovery(void)
|
||||
{
|
||||
PGresult *res_db;
|
||||
|
||||
res_db = pgut_execute(backup_conn, "SELECT pg_catalog.pg_is_in_recovery()", 0, NULL, true);
|
||||
res_db = pgut_execute(backup_conn, "SELECT pg_catalog.pg_is_in_recovery()", 0, NULL);
|
||||
|
||||
if (PQgetvalue(res_db, 0, 0)[0] == 't')
|
||||
{
|
||||
@ -1207,7 +1240,7 @@ pg_ptrack_clear(void)
|
||||
params[0] = palloc(64);
|
||||
params[1] = palloc(64);
|
||||
res_db = pgut_execute(backup_conn, "SELECT datname, oid, dattablespace FROM pg_database",
|
||||
0, NULL, true);
|
||||
0, NULL);
|
||||
|
||||
for(i = 0; i < PQntuples(res_db); i++)
|
||||
{
|
||||
@ -1221,12 +1254,12 @@ pg_ptrack_clear(void)
|
||||
tblspcOid = atoi(PQgetvalue(res_db, i, 2));
|
||||
|
||||
tmp_conn = pgut_connect(dbname);
|
||||
res = pgut_execute(tmp_conn, "SELECT pg_catalog.pg_ptrack_clear()", 0, NULL, true);
|
||||
res = pgut_execute(tmp_conn, "SELECT pg_catalog.pg_ptrack_clear()", 0, NULL);
|
||||
|
||||
sprintf(params[0], "%i", dbOid);
|
||||
sprintf(params[1], "%i", tblspcOid);
|
||||
res = pgut_execute(tmp_conn, "SELECT pg_catalog.pg_ptrack_get_and_clear_db($1, $2)",
|
||||
2, (const char **)params, true);
|
||||
2, (const char **)params);
|
||||
PQclear(res);
|
||||
|
||||
pgut_disconnect(tmp_conn);
|
||||
@ -1252,7 +1285,7 @@ pg_ptrack_get_and_clear_db(Oid dbOid, Oid tblspcOid)
|
||||
sprintf(params[0], "%i", dbOid);
|
||||
res_db = pgut_execute(backup_conn,
|
||||
"SELECT datname FROM pg_database WHERE oid=$1",
|
||||
1, (const char **) params, true);
|
||||
1, (const char **) params);
|
||||
/*
|
||||
* If database is not found, it's not an error.
|
||||
* It could have been deleted since previous backup.
|
||||
@ -1273,7 +1306,7 @@ pg_ptrack_get_and_clear_db(Oid dbOid, Oid tblspcOid)
|
||||
sprintf(params[0], "%i", dbOid);
|
||||
sprintf(params[1], "%i", tblspcOid);
|
||||
res = pgut_execute(backup_conn, "SELECT pg_catalog.pg_ptrack_get_and_clear_db($1, $2)",
|
||||
2, (const char **)params, true);
|
||||
2, (const char **)params);
|
||||
|
||||
if (PQnfields(res) != 1)
|
||||
elog(ERROR, "cannot perform pg_ptrack_get_and_clear_db()");
|
||||
@ -1318,7 +1351,7 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_filenode,
|
||||
sprintf(params[0], "%i", db_oid);
|
||||
res_db = pgut_execute(backup_conn,
|
||||
"SELECT datname FROM pg_database WHERE oid=$1",
|
||||
1, (const char **) params, true);
|
||||
1, (const char **) params);
|
||||
/*
|
||||
* If database is not found, it's not an error.
|
||||
* It could have been deleted since previous backup.
|
||||
@ -1338,7 +1371,7 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_filenode,
|
||||
sprintf(params[0], "%i", tablespace_oid);
|
||||
sprintf(params[1], "%i", rel_filenode);
|
||||
res = pgut_execute(tmp_conn, "SELECT pg_catalog.pg_ptrack_get_and_clear($1, $2)",
|
||||
2, (const char **)params, true);
|
||||
2, (const char **)params);
|
||||
|
||||
if (PQnfields(res) != 1)
|
||||
elog(ERROR, "cannot get ptrack file from database \"%s\" by tablespace oid %u and relation oid %u",
|
||||
@ -1356,7 +1389,7 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_filenode,
|
||||
sprintf(params[0], "%i", tablespace_oid);
|
||||
sprintf(params[1], "%i", rel_filenode);
|
||||
res = pgut_execute(backup_conn, "SELECT pg_catalog.pg_ptrack_get_and_clear($1, $2)",
|
||||
2, (const char **)params, true);
|
||||
2, (const char **)params);
|
||||
|
||||
if (PQnfields(res) != 1)
|
||||
elog(ERROR, "cannot get ptrack file from pg_global tablespace and relation oid %u",
|
||||
@ -1537,10 +1570,10 @@ wait_replica_wal_lsn(XLogRecPtr lsn, bool is_start_backup)
|
||||
{
|
||||
if (server_version >= 100000)
|
||||
res = pgut_execute(backup_conn, "SELECT pg_catalog.pg_last_wal_replay_lsn()",
|
||||
0, NULL, true);
|
||||
0, NULL);
|
||||
else
|
||||
res = pgut_execute(backup_conn, "SELECT pg_catalog.pg_last_xlog_replay_location()",
|
||||
0, NULL, true);
|
||||
0, NULL);
|
||||
}
|
||||
/*
|
||||
* For lsn from pg_stop_backup() we need it only to be received by
|
||||
@ -1550,10 +1583,10 @@ wait_replica_wal_lsn(XLogRecPtr lsn, bool is_start_backup)
|
||||
{
|
||||
if (server_version >= 100000)
|
||||
res = pgut_execute(backup_conn, "SELECT pg_catalog.pg_last_wal_receive_lsn()",
|
||||
0, NULL, true);
|
||||
0, NULL);
|
||||
else
|
||||
res = pgut_execute(backup_conn, "SELECT pg_catalog.pg_last_xlog_receive_location()",
|
||||
0, NULL, true);
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
/* Extract timeline and LSN from result */
|
||||
@ -1620,7 +1653,7 @@ pg_stop_backup(pgBackup *backup)
|
||||
|
||||
/* Remove annoying NOTICE messages generated by backend */
|
||||
res = pgut_execute(conn, "SET client_min_messages = warning;",
|
||||
0, NULL, true);
|
||||
0, NULL);
|
||||
PQclear(res);
|
||||
|
||||
/* Create restore point */
|
||||
@ -1638,7 +1671,7 @@ pg_stop_backup(pgBackup *backup)
|
||||
params[0] = name;
|
||||
|
||||
res = pgut_execute(conn, "SELECT pg_catalog.pg_create_restore_point($1)",
|
||||
1, params, true);
|
||||
1, params);
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
@ -1901,7 +1934,7 @@ checkpoint_timeout(void)
|
||||
const char *hintmsg;
|
||||
int val_int;
|
||||
|
||||
res = pgut_execute(backup_conn, "show checkpoint_timeout", 0, NULL, true);
|
||||
res = pgut_execute(backup_conn, "show checkpoint_timeout", 0, NULL);
|
||||
val = PQgetvalue(res, 0, 0);
|
||||
|
||||
if (!parse_int(val, &val_int, OPTION_UNIT_S, &hintmsg))
|
||||
@ -2586,7 +2619,7 @@ get_last_ptrack_lsn(void)
|
||||
uint32 xrecoff;
|
||||
XLogRecPtr lsn;
|
||||
|
||||
res = pgut_execute(backup_conn, "select pg_catalog.pg_ptrack_control_lsn()", 0, NULL, true);
|
||||
res = pgut_execute(backup_conn, "select pg_catalog.pg_ptrack_control_lsn()", 0, NULL);
|
||||
|
||||
/* Extract timeline and LSN from results of pg_start_backup() */
|
||||
XLogDataFromLSN(PQgetvalue(res, 0, 0), &xlogid, &xrecoff);
|
||||
|
@ -95,8 +95,8 @@ fetchFile(PGconn *conn, const char *filename, size_t *filesize)
|
||||
int len;
|
||||
|
||||
params[0] = filename;
|
||||
res = pgut_execute(conn, "SELECT pg_catalog.pg_read_binary_file($1)",
|
||||
1, params, false);
|
||||
res = pgut_execute_extended(conn, "SELECT pg_catalog.pg_read_binary_file($1)",
|
||||
1, params, false, false);
|
||||
|
||||
/* sanity check the result set */
|
||||
if (PQntuples(res) != 1 || PQgetisnull(res, 0, 0))
|
||||
|
@ -251,7 +251,7 @@ main(int argc, char *argv[])
|
||||
if (argc == 2)
|
||||
{
|
||||
#ifdef PGPRO_VERSION
|
||||
fprintf(stderr, "%s %s (PostgresPro %s %s)\n",
|
||||
fprintf(stderr, "%s %s (Postgres Pro %s %s)\n",
|
||||
PROGRAM_NAME, PROGRAM_VERSION,
|
||||
PGPRO_VERSION, PGPRO_EDITION);
|
||||
#else
|
||||
|
@ -149,7 +149,7 @@ get_remote_system_identifier(PGconn *conn)
|
||||
|
||||
res = pgut_execute(conn,
|
||||
"SELECT system_identifier FROM pg_catalog.pg_control_system()",
|
||||
0, NULL, true);
|
||||
0, NULL);
|
||||
val = PQgetvalue(res, 0, 0);
|
||||
if (!parse_uint64(val, &system_id_conn, 0))
|
||||
{
|
||||
|
@ -1690,11 +1690,19 @@ pgut_execute_parallel(PGconn* conn,
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
PGresult *
|
||||
pgut_execute(PGconn* conn, const char *query, int nParams, const char **params,
|
||||
bool text_result)
|
||||
pgut_execute(PGconn* conn, const char *query, int nParams, const char **params)
|
||||
{
|
||||
return pgut_execute_extended(conn, query, nParams, params, true, false);
|
||||
}
|
||||
|
||||
PGresult *
|
||||
pgut_execute_extended(PGconn* conn, const char *query, int nParams,
|
||||
const char **params, bool text_result, bool ok_error)
|
||||
{
|
||||
PGresult *res;
|
||||
ExecStatusType res_status;
|
||||
|
||||
if (interrupted && !in_cleanup)
|
||||
elog(ERROR, "interrupted");
|
||||
@ -1730,13 +1738,17 @@ pgut_execute(PGconn* conn, const char *query, int nParams, const char **params,
|
||||
(text_result) ? 0 : 1);
|
||||
on_after_exec(NULL);
|
||||
|
||||
switch (PQresultStatus(res))
|
||||
res_status = PQresultStatus(res);
|
||||
switch (res_status)
|
||||
{
|
||||
case PGRES_TUPLES_OK:
|
||||
case PGRES_COMMAND_OK:
|
||||
case PGRES_COPY_IN:
|
||||
break;
|
||||
default:
|
||||
if (ok_error && res_status == PGRES_FATAL_ERROR)
|
||||
break;
|
||||
|
||||
elog(ERROR, "query failed: %squery was: %s",
|
||||
PQerrorMessage(conn), query);
|
||||
break;
|
||||
|
@ -135,7 +135,9 @@ extern PGconn *pgut_connect_replication_extended(const char *pghost, const char
|
||||
const char *dbname, const char *pguser);
|
||||
extern void pgut_disconnect(PGconn *conn);
|
||||
extern PGresult *pgut_execute(PGconn* conn, const char *query, int nParams,
|
||||
const char **params, bool text_result);
|
||||
const char **params);
|
||||
extern PGresult *pgut_execute_extended(PGconn* conn, const char *query, int nParams,
|
||||
const char **params, bool text_result, bool ok_error);
|
||||
extern PGresult *pgut_execute_parallel(PGconn* conn, PGcancel* thread_cancel_conn,
|
||||
const char *query, int nParams,
|
||||
const char **params, bool text_result);
|
||||
|
Loading…
Reference in New Issue
Block a user