Skip to content

Commit d8005d5

Browse files
committed
PGPRO-1290: Check connected server version with build version
1 parent c408a0e commit d8005d5

File tree

6 files changed

+84
-37
lines changed

6 files changed

+84
-37
lines changed

src/backup.c

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,8 @@ do_backup(time_t start_time)
934934
static void
935935
check_server_version(void)
936936
{
937+
PGresult *res;
938+
937939
/* confirm server version */
938940
server_version = PQserverVersion(backup_conn);
939941

@@ -958,6 +960,39 @@ check_server_version(void)
958960
"server version is %s, must be %s or higher for backup from replica",
959961
server_version_str, "9.6");
960962

963+
res = pgut_execute_extended(backup_conn, "SELECT pgpro_edition()",
964+
0, NULL, true, true);
965+
966+
/*
967+
* Check major version of connected PostgreSQL and major version of
968+
* compiled PostgreSQL.
969+
*/
970+
#ifdef PGPRO_VERSION
971+
if (PQresultStatus(res) == PGRES_FATAL_ERROR)
972+
/* It seems we connected to PostgreSQL (not Postgres Pro) */
973+
elog(ERROR, "%s was built with Postgres Pro %s %s, "
974+
"but connection made with PostgreSQL %s",
975+
PROGRAM_NAME, PG_MAJORVERSION, PGPRO_EDITION, server_version_str);
976+
else if (strcmp(server_version_str, PG_MAJORVERSION) != 0 &&
977+
strcmp(PQgetvalue(res, 0, 0), PGPRO_EDITION) != 0)
978+
elog(ERROR, "%s was built with Postgres Pro %s %s, "
979+
"but connection made with Postgres Pro %s %s",
980+
PROGRAM_NAME, PG_MAJORVERSION, PGPRO_EDITION,
981+
server_version_str, PQgetvalue(res, 0, 0));
982+
#else
983+
if (PQresultStatus(res) != PGRES_FATAL_ERROR)
984+
/* It seems we connected to Postgres Pro (not PostgreSQL) */
985+
elog(ERROR, "%s was built with PostgreSQL %s, "
986+
"but connection made with Postgres Pro %s %s",
987+
PROGRAM_NAME, PG_MAJORVERSION,
988+
server_version_str, PQgetvalue(res, 0, 0));
989+
else if (strcmp(server_version_str, PG_MAJORVERSION) != 0)
990+
elog(ERROR, "%s was built with PostgreSQL %s, but connection made with %s",
991+
PROGRAM_NAME, PG_MAJORVERSION, server_version_str);
992+
#endif
993+
994+
PQclear(res);
995+
961996
/* Do exclusive backup only for PostgreSQL 9.5 */
962997
exclusive_backup = server_version < 90600 ||
963998
current.backup_mode == BACKUP_MODE_DIFF_PTRACK;
@@ -997,7 +1032,7 @@ confirm_block_size(const char *name, int blcksz)
9971032
char *endp;
9981033
int block_size;
9991034

1000-
res = pgut_execute(backup_conn, "SELECT pg_catalog.current_setting($1)", 1, &name, true);
1035+
res = pgut_execute(backup_conn, "SELECT pg_catalog.current_setting($1)", 1, &name);
10011036
if (PQntuples(res) != 1 || PQnfields(res) != 1)
10021037
elog(ERROR, "cannot get %s: %s", name, PQerrorMessage(backup_conn));
10031038

@@ -1033,14 +1068,12 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
10331068
res = pgut_execute(conn,
10341069
"SELECT pg_catalog.pg_start_backup($1, $2, false)",
10351070
2,
1036-
params,
1037-
true);
1071+
params);
10381072
else
10391073
res = pgut_execute(conn,
10401074
"SELECT pg_catalog.pg_start_backup($1, $2)",
10411075
2,
1042-
params,
1043-
true);
1076+
params);
10441077

10451078
/* Extract timeline and LSN from results of pg_start_backup() */
10461079
XLogDataFromLSN(PQgetvalue(res, 0, 0), &xlogid, &xrecoff);
@@ -1091,13 +1124,13 @@ pg_switch_wal(PGconn *conn)
10911124
PGresult *res;
10921125

10931126
/* Remove annoying NOTICE messages generated by backend */
1094-
res = pgut_execute(conn, "SET client_min_messages = warning;", 0, NULL, true);
1127+
res = pgut_execute(conn, "SET client_min_messages = warning;", 0, NULL);
10951128
PQclear(res);
10961129

10971130
if (server_version >= 100000)
1098-
res = pgut_execute(conn, "SELECT * FROM pg_catalog.pg_switch_wal()", 0, NULL, true);
1131+
res = pgut_execute(conn, "SELECT * FROM pg_catalog.pg_switch_wal()", 0, NULL);
10991132
else
1100-
res = pgut_execute(conn, "SELECT * FROM pg_catalog.pg_switch_xlog()", 0, NULL, true);
1133+
res = pgut_execute(conn, "SELECT * FROM pg_catalog.pg_switch_xlog()", 0, NULL);
11011134

11021135
PQclear(res);
11031136
}
@@ -1113,7 +1146,7 @@ pg_ptrack_support(void)
11131146

11141147
res_db = pgut_execute(backup_conn,
11151148
"SELECT proname FROM pg_proc WHERE proname='ptrack_version'",
1116-
0, NULL, true);
1149+
0, NULL);
11171150
if (PQntuples(res_db) == 0)
11181151
{
11191152
PQclear(res_db);
@@ -1123,7 +1156,7 @@ pg_ptrack_support(void)
11231156

11241157
res_db = pgut_execute(backup_conn,
11251158
"SELECT pg_catalog.ptrack_version()",
1126-
0, NULL, true);
1159+
0, NULL);
11271160
if (PQntuples(res_db) == 0)
11281161
{
11291162
PQclear(res_db);
@@ -1148,7 +1181,7 @@ pg_ptrack_enable(void)
11481181
{
11491182
PGresult *res_db;
11501183

1151-
res_db = pgut_execute(backup_conn, "show ptrack_enable", 0, NULL, true);
1184+
res_db = pgut_execute(backup_conn, "show ptrack_enable", 0, NULL);
11521185

11531186
if (strcmp(PQgetvalue(res_db, 0, 0), "on") != 0)
11541187
{
@@ -1165,7 +1198,7 @@ pg_checksum_enable(void)
11651198
{
11661199
PGresult *res_db;
11671200

1168-
res_db = pgut_execute(backup_conn, "show data_checksums", 0, NULL, true);
1201+
res_db = pgut_execute(backup_conn, "show data_checksums", 0, NULL);
11691202

11701203
if (strcmp(PQgetvalue(res_db, 0, 0), "on") != 0)
11711204
{
@@ -1182,7 +1215,7 @@ pg_is_in_recovery(void)
11821215
{
11831216
PGresult *res_db;
11841217

1185-
res_db = pgut_execute(backup_conn, "SELECT pg_catalog.pg_is_in_recovery()", 0, NULL, true);
1218+
res_db = pgut_execute(backup_conn, "SELECT pg_catalog.pg_is_in_recovery()", 0, NULL);
11861219

11871220
if (PQgetvalue(res_db, 0, 0)[0] == 't')
11881221
{
@@ -1207,7 +1240,7 @@ pg_ptrack_clear(void)
12071240
params[0] = palloc(64);
12081241
params[1] = palloc(64);
12091242
res_db = pgut_execute(backup_conn, "SELECT datname, oid, dattablespace FROM pg_database",
1210-
0, NULL, true);
1243+
0, NULL);
12111244

12121245
for(i = 0; i < PQntuples(res_db); i++)
12131246
{
@@ -1221,12 +1254,12 @@ pg_ptrack_clear(void)
12211254
tblspcOid = atoi(PQgetvalue(res_db, i, 2));
12221255

12231256
tmp_conn = pgut_connect(dbname);
1224-
res = pgut_execute(tmp_conn, "SELECT pg_catalog.pg_ptrack_clear()", 0, NULL, true);
1257+
res = pgut_execute(tmp_conn, "SELECT pg_catalog.pg_ptrack_clear()", 0, NULL);
12251258

12261259
sprintf(params[0], "%i", dbOid);
12271260
sprintf(params[1], "%i", tblspcOid);
12281261
res = pgut_execute(tmp_conn, "SELECT pg_catalog.pg_ptrack_get_and_clear_db($1, $2)",
1229-
2, (const char **)params, true);
1262+
2, (const char **)params);
12301263
PQclear(res);
12311264

12321265
pgut_disconnect(tmp_conn);
@@ -1252,7 +1285,7 @@ pg_ptrack_get_and_clear_db(Oid dbOid, Oid tblspcOid)
12521285
sprintf(params[0], "%i", dbOid);
12531286
res_db = pgut_execute(backup_conn,
12541287
"SELECT datname FROM pg_database WHERE oid=$1",
1255-
1, (const char **) params, true);
1288+
1, (const char **) params);
12561289
/*
12571290
* If database is not found, it's not an error.
12581291
* It could have been deleted since previous backup.
@@ -1273,7 +1306,7 @@ pg_ptrack_get_and_clear_db(Oid dbOid, Oid tblspcOid)
12731306
sprintf(params[0], "%i", dbOid);
12741307
sprintf(params[1], "%i", tblspcOid);
12751308
res = pgut_execute(backup_conn, "SELECT pg_catalog.pg_ptrack_get_and_clear_db($1, $2)",
1276-
2, (const char **)params, true);
1309+
2, (const char **)params);
12771310

12781311
if (PQnfields(res) != 1)
12791312
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,
13181351
sprintf(params[0], "%i", db_oid);
13191352
res_db = pgut_execute(backup_conn,
13201353
"SELECT datname FROM pg_database WHERE oid=$1",
1321-
1, (const char **) params, true);
1354+
1, (const char **) params);
13221355
/*
13231356
* If database is not found, it's not an error.
13241357
* 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,
13381371
sprintf(params[0], "%i", tablespace_oid);
13391372
sprintf(params[1], "%i", rel_filenode);
13401373
res = pgut_execute(tmp_conn, "SELECT pg_catalog.pg_ptrack_get_and_clear($1, $2)",
1341-
2, (const char **)params, true);
1374+
2, (const char **)params);
13421375

13431376
if (PQnfields(res) != 1)
13441377
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,
13561389
sprintf(params[0], "%i", tablespace_oid);
13571390
sprintf(params[1], "%i", rel_filenode);
13581391
res = pgut_execute(backup_conn, "SELECT pg_catalog.pg_ptrack_get_and_clear($1, $2)",
1359-
2, (const char **)params, true);
1392+
2, (const char **)params);
13601393

13611394
if (PQnfields(res) != 1)
13621395
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)
15371570
{
15381571
if (server_version >= 100000)
15391572
res = pgut_execute(backup_conn, "SELECT pg_catalog.pg_last_wal_replay_lsn()",
1540-
0, NULL, true);
1573+
0, NULL);
15411574
else
15421575
res = pgut_execute(backup_conn, "SELECT pg_catalog.pg_last_xlog_replay_location()",
1543-
0, NULL, true);
1576+
0, NULL);
15441577
}
15451578
/*
15461579
* 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)
15501583
{
15511584
if (server_version >= 100000)
15521585
res = pgut_execute(backup_conn, "SELECT pg_catalog.pg_last_wal_receive_lsn()",
1553-
0, NULL, true);
1586+
0, NULL);
15541587
else
15551588
res = pgut_execute(backup_conn, "SELECT pg_catalog.pg_last_xlog_receive_location()",
1556-
0, NULL, true);
1589+
0, NULL);
15571590
}
15581591

15591592
/* Extract timeline and LSN from result */
@@ -1620,7 +1653,7 @@ pg_stop_backup(pgBackup *backup)
16201653

16211654
/* Remove annoying NOTICE messages generated by backend */
16221655
res = pgut_execute(conn, "SET client_min_messages = warning;",
1623-
0, NULL, true);
1656+
0, NULL);
16241657
PQclear(res);
16251658

16261659
/* Create restore point */
@@ -1638,7 +1671,7 @@ pg_stop_backup(pgBackup *backup)
16381671
params[0] = name;
16391672

16401673
res = pgut_execute(conn, "SELECT pg_catalog.pg_create_restore_point($1)",
1641-
1, params, true);
1674+
1, params);
16421675
PQclear(res);
16431676
}
16441677

@@ -1901,7 +1934,7 @@ checkpoint_timeout(void)
19011934
const char *hintmsg;
19021935
int val_int;
19031936

1904-
res = pgut_execute(backup_conn, "show checkpoint_timeout", 0, NULL, true);
1937+
res = pgut_execute(backup_conn, "show checkpoint_timeout", 0, NULL);
19051938
val = PQgetvalue(res, 0, 0);
19061939

19071940
if (!parse_int(val, &val_int, OPTION_UNIT_S, &hintmsg))
@@ -2586,7 +2619,7 @@ get_last_ptrack_lsn(void)
25862619
uint32 xrecoff;
25872620
XLogRecPtr lsn;
25882621

2589-
res = pgut_execute(backup_conn, "select pg_catalog.pg_ptrack_control_lsn()", 0, NULL, true);
2622+
res = pgut_execute(backup_conn, "select pg_catalog.pg_ptrack_control_lsn()", 0, NULL);
25902623

25912624
/* Extract timeline and LSN from results of pg_start_backup() */
25922625
XLogDataFromLSN(PQgetvalue(res, 0, 0), &xlogid, &xrecoff);

src/fetch.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ fetchFile(PGconn *conn, const char *filename, size_t *filesize)
9595
int len;
9696

9797
params[0] = filename;
98-
res = pgut_execute(conn, "SELECT pg_catalog.pg_read_binary_file($1)",
99-
1, params, false);
98+
res = pgut_execute_extended(conn, "SELECT pg_catalog.pg_read_binary_file($1)",
99+
1, params, false, false);
100100

101101
/* sanity check the result set */
102102
if (PQntuples(res) != 1 || PQgetisnull(res, 0, 0))

src/pg_probackup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ main(int argc, char *argv[])
251251
if (argc == 2)
252252
{
253253
#ifdef PGPRO_VERSION
254-
fprintf(stderr, "%s %s (PostgresPro %s %s)\n",
254+
fprintf(stderr, "%s %s (Postgres Pro %s %s)\n",
255255
PROGRAM_NAME, PROGRAM_VERSION,
256256
PGPRO_VERSION, PGPRO_EDITION);
257257
#else

src/util.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ get_remote_system_identifier(PGconn *conn)
149149

150150
res = pgut_execute(conn,
151151
"SELECT system_identifier FROM pg_catalog.pg_control_system()",
152-
0, NULL, true);
152+
0, NULL);
153153
val = PQgetvalue(res, 0, 0);
154154
if (!parse_uint64(val, &system_id_conn, 0))
155155
{

src/utils/pgut.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,11 +1690,19 @@ pgut_execute_parallel(PGconn* conn,
16901690

16911691
return res;
16921692
}
1693+
1694+
PGresult *
1695+
pgut_execute(PGconn* conn, const char *query, int nParams, const char **params)
1696+
{
1697+
return pgut_execute_extended(conn, query, nParams, params, true, false);
1698+
}
1699+
16931700
PGresult *
1694-
pgut_execute(PGconn* conn, const char *query, int nParams, const char **params,
1695-
bool text_result)
1701+
pgut_execute_extended(PGconn* conn, const char *query, int nParams,
1702+
const char **params, bool text_result, bool ok_error)
16961703
{
16971704
PGresult *res;
1705+
ExecStatusType res_status;
16981706

16991707
if (interrupted && !in_cleanup)
17001708
elog(ERROR, "interrupted");
@@ -1730,13 +1738,17 @@ pgut_execute(PGconn* conn, const char *query, int nParams, const char **params,
17301738
(text_result) ? 0 : 1);
17311739
on_after_exec(NULL);
17321740

1733-
switch (PQresultStatus(res))
1741+
res_status = PQresultStatus(res);
1742+
switch (res_status)
17341743
{
17351744
case PGRES_TUPLES_OK:
17361745
case PGRES_COMMAND_OK:
17371746
case PGRES_COPY_IN:
17381747
break;
17391748
default:
1749+
if (ok_error && res_status == PGRES_FATAL_ERROR)
1750+
break;
1751+
17401752
elog(ERROR, "query failed: %squery was: %s",
17411753
PQerrorMessage(conn), query);
17421754
break;

src/utils/pgut.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ extern PGconn *pgut_connect_replication_extended(const char *pghost, const char
135135
const char *dbname, const char *pguser);
136136
extern void pgut_disconnect(PGconn *conn);
137137
extern PGresult *pgut_execute(PGconn* conn, const char *query, int nParams,
138-
const char **params, bool text_result);
138+
const char **params);
139+
extern PGresult *pgut_execute_extended(PGconn* conn, const char *query, int nParams,
140+
const char **params, bool text_result, bool ok_error);
139141
extern PGresult *pgut_execute_parallel(PGconn* conn, PGcancel* thread_cancel_conn,
140142
const char *query, int nParams,
141143
const char **params, bool text_result);

0 commit comments

Comments
 (0)