Skip to content

Commit b16dd21

Browse files
committed
PGPRO-1189: fix for exclusive mode for backup from replica
1 parent d094131 commit b16dd21

File tree

5 files changed

+54
-65
lines changed

5 files changed

+54
-65
lines changed

src/backup.c

Lines changed: 39 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,6 @@ do_backup_instance(void)
457457
/* Initialize size summary */
458458
current.data_bytes = 0;
459459

460-
current.tablespace_map_exists = false;
461-
462460
/* Obtain current timeline */
463461
if (is_remote_backup)
464462
{
@@ -898,7 +896,7 @@ check_server_version(void)
898896
current.backup_mode == BACKUP_MODE_DIFF_PTRACK;
899897

900898
/* Save server_version to use it in future */
901-
res = pgut_execute(backup_conn, "show server_version", 0, NULL);
899+
res = pgut_execute(backup_conn, "show server_version", 0, NULL, true);
902900
StrNCpy(server_version_str, PQgetvalue(res, 0, 0), sizeof(server_version_str));
903901
PQclear(res);
904902
}
@@ -921,7 +919,7 @@ check_system_identifiers(void)
921919

922920
res = pgut_execute(backup_conn,
923921
"SELECT system_identifier FROM pg_control_system()",
924-
0, NULL);
922+
0, NULL, true);
925923
val = PQgetvalue(res, 0, 0);
926924

927925
if (!parse_uint64(val, &system_id_conn))
@@ -951,7 +949,7 @@ confirm_block_size(const char *name, int blcksz)
951949
char *endp;
952950
int block_size;
953951

954-
res = pgut_execute(backup_conn, "SELECT current_setting($1)", 1, &name);
952+
res = pgut_execute(backup_conn, "SELECT current_setting($1)", 1, &name, true);
955953
if (PQntuples(res) != 1 || PQnfields(res) != 1)
956954
elog(ERROR, "cannot get %s: %s", name, PQerrorMessage(backup_conn));
957955

@@ -987,12 +985,14 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup)
987985
res = pgut_execute(conn,
988986
"SELECT pg_start_backup($1, $2, false)",
989987
2,
990-
params);
988+
params,
989+
true);
991990
else
992991
res = pgut_execute(conn,
993992
"SELECT pg_start_backup($1, $2)",
994993
2,
995-
params);
994+
params,
995+
true);
996996

997997
/* Extract timeline and LSN from results of pg_start_backup() */
998998
XLogDataFromLSN(PQgetvalue(res, 0, 0), &xlogid, &xrecoff);
@@ -1043,13 +1043,13 @@ pg_switch_wal(PGconn *conn)
10431043
PGresult *res;
10441044

10451045
/* Remove annoying NOTICE messages generated by backend */
1046-
res = pgut_execute(conn, "SET client_min_messages = warning;", 0, NULL);
1046+
res = pgut_execute(conn, "SET client_min_messages = warning;", 0, NULL, true);
10471047
PQclear(res);
10481048

10491049
if (server_version >= 100000)
1050-
res = pgut_execute(conn, "SELECT * FROM pg_switch_wal()", 0, NULL);
1050+
res = pgut_execute(conn, "SELECT * FROM pg_switch_wal()", 0, NULL, true);
10511051
else
1052-
res = pgut_execute(conn, "SELECT * FROM pg_switch_xlog()", 0, NULL);
1052+
res = pgut_execute(conn, "SELECT * FROM pg_switch_xlog()", 0, NULL, true);
10531053

10541054
PQclear(res);
10551055
}
@@ -1065,7 +1065,7 @@ pg_ptrack_support(void)
10651065

10661066
res_db = pgut_execute(backup_conn,
10671067
"SELECT proname FROM pg_proc WHERE proname='ptrack_version'",
1068-
0, NULL);
1068+
0, NULL, true);
10691069
if (PQntuples(res_db) == 0)
10701070
{
10711071
PQclear(res_db);
@@ -1075,7 +1075,7 @@ pg_ptrack_support(void)
10751075

10761076
res_db = pgut_execute(backup_conn,
10771077
"SELECT ptrack_version()",
1078-
0, NULL);
1078+
0, NULL, true);
10791079
if (PQntuples(res_db) == 0)
10801080
{
10811081
PQclear(res_db);
@@ -1100,7 +1100,7 @@ pg_ptrack_enable(void)
11001100
{
11011101
PGresult *res_db;
11021102

1103-
res_db = pgut_execute(backup_conn, "show ptrack_enable", 0, NULL);
1103+
res_db = pgut_execute(backup_conn, "show ptrack_enable", 0, NULL, true);
11041104

11051105
if (strcmp(PQgetvalue(res_db, 0, 0), "on") != 0)
11061106
{
@@ -1117,7 +1117,7 @@ pg_is_in_recovery(void)
11171117
{
11181118
PGresult *res_db;
11191119

1120-
res_db = pgut_execute(backup_conn, "SELECT pg_is_in_recovery()", 0, NULL);
1120+
res_db = pgut_execute(backup_conn, "SELECT pg_is_in_recovery()", 0, NULL, true);
11211121

11221122
if (PQgetvalue(res_db, 0, 0)[0] == 't')
11231123
{
@@ -1136,7 +1136,7 @@ pg_archive_enabled(void)
11361136
{
11371137
PGresult *res_db;
11381138

1139-
res_db = pgut_execute(backup_conn, "show archive_mode", 0, NULL);
1139+
res_db = pgut_execute(backup_conn, "show archive_mode", 0, NULL, true);
11401140

11411141
if (strcmp(PQgetvalue(res_db, 0, 0), "off") == 0)
11421142
{
@@ -1145,7 +1145,7 @@ pg_archive_enabled(void)
11451145
}
11461146
PQclear(res_db);
11471147

1148-
res_db = pgut_execute(backup_conn, "show archive_command", 0, NULL);
1148+
res_db = pgut_execute(backup_conn, "show archive_command", 0, NULL, true);
11491149
if (strlen(PQgetvalue(res_db, 0, 0)) == 0)
11501150
{
11511151
PQclear(res_db);
@@ -1170,7 +1170,7 @@ pg_ptrack_clear(void)
11701170
params[0] = palloc(64);
11711171
params[1] = palloc(64);
11721172
res_db = pgut_execute(backup_conn, "SELECT datname, oid, dattablespace FROM pg_database",
1173-
0, NULL);
1173+
0, NULL, true);
11741174

11751175
for(i = 0; i < PQntuples(res_db); i++)
11761176
{
@@ -1184,12 +1184,12 @@ pg_ptrack_clear(void)
11841184
tblspcOid = atoi(PQgetvalue(res_db, i, 2));
11851185

11861186
tmp_conn = pgut_connect(dbname);
1187-
res = pgut_execute(tmp_conn, "SELECT pg_ptrack_clear()", 0, NULL);
1187+
res = pgut_execute(tmp_conn, "SELECT pg_ptrack_clear()", 0, NULL, true);
11881188

11891189
sprintf(params[0], "%i", dbOid);
11901190
sprintf(params[1], "%i", tblspcOid);
11911191
res = pgut_execute(tmp_conn, "SELECT pg_ptrack_get_and_clear_db($1, $2)",
1192-
2, (const char **)params);
1192+
2, (const char **)params, true);
11931193
PQclear(res);
11941194

11951195
pgut_disconnect(tmp_conn);
@@ -1215,7 +1215,7 @@ pg_ptrack_get_and_clear_db(Oid dbOid, Oid tblspcOid)
12151215
sprintf(params[0], "%i", dbOid);
12161216
res_db = pgut_execute(backup_conn,
12171217
"SELECT datname FROM pg_database WHERE oid=$1",
1218-
1, (const char **) params);
1218+
1, (const char **) params, true);
12191219
/*
12201220
* If database is not found, it's not an error.
12211221
* It could have been deleted since previous backup.
@@ -1236,7 +1236,7 @@ pg_ptrack_get_and_clear_db(Oid dbOid, Oid tblspcOid)
12361236
sprintf(params[0], "%i", dbOid);
12371237
sprintf(params[1], "%i", tblspcOid);
12381238
res = pgut_execute(backup_conn, "SELECT pg_ptrack_get_and_clear_db($1, $2)",
1239-
2, (const char **)params);
1239+
2, (const char **)params, true);
12401240

12411241
if (PQnfields(res) != 1)
12421242
elog(ERROR, "cannot perform pg_ptrack_get_and_clear_db()");
@@ -1277,7 +1277,7 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_filenode,
12771277
sprintf(params[0], "%i", db_oid);
12781278
res_db = pgut_execute(backup_conn,
12791279
"SELECT datname FROM pg_database WHERE oid=$1",
1280-
1, (const char **) params);
1280+
1, (const char **) params, true);
12811281
/*
12821282
* If database is not found, it's not an error.
12831283
* It could have been deleted since previous backup.
@@ -1297,7 +1297,7 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_filenode,
12971297
sprintf(params[0], "%i", tablespace_oid);
12981298
sprintf(params[1], "%i", rel_filenode);
12991299
res = pgut_execute(tmp_conn, "SELECT pg_ptrack_get_and_clear($1, $2)",
1300-
2, (const char **)params);
1300+
2, (const char **)params, true);
13011301

13021302
if (PQnfields(res) != 1)
13031303
elog(ERROR, "cannot get ptrack file from database \"%s\" by tablespace oid %u and relation oid %u",
@@ -1315,7 +1315,7 @@ pg_ptrack_get_and_clear(Oid tablespace_oid, Oid db_oid, Oid rel_filenode,
13151315
sprintf(params[0], "%i", tablespace_oid);
13161316
sprintf(params[1], "%i", rel_filenode);
13171317
res = pgut_execute(backup_conn, "SELECT pg_ptrack_get_and_clear($1, $2)",
1318-
2, (const char **)params);
1318+
2, (const char **)params, true);
13191319

13201320
if (PQnfields(res) != 1)
13211321
elog(ERROR, "cannot get ptrack file from pg_global tablespace and relation oid %u",
@@ -1472,10 +1472,10 @@ wait_replica_wal_lsn(XLogRecPtr lsn, bool is_start_backup)
14721472
{
14731473
if (server_version >= 100000)
14741474
res = pgut_execute(backup_conn, "SELECT pg_last_wal_replay_lsn()",
1475-
0, NULL);
1475+
0, NULL, true);
14761476
else
14771477
res = pgut_execute(backup_conn, "SELECT pg_last_xlog_replay_location()",
1478-
0, NULL);
1478+
0, NULL, true);
14791479
}
14801480
/*
14811481
* For lsn from pg_stop_backup() we need it only to be received by
@@ -1485,10 +1485,10 @@ wait_replica_wal_lsn(XLogRecPtr lsn, bool is_start_backup)
14851485
{
14861486
if (server_version >= 100000)
14871487
res = pgut_execute(backup_conn, "SELECT pg_last_wal_receive_lsn()",
1488-
0, NULL);
1488+
0, NULL, true);
14891489
else
14901490
res = pgut_execute(backup_conn, "SELECT pg_last_xlog_receive_location()",
1491-
0, NULL);
1491+
0, NULL, true);
14921492
}
14931493

14941494
/* Extract timeline and LSN from result */
@@ -1555,7 +1555,7 @@ pg_stop_backup(pgBackup *backup)
15551555

15561556
/* Remove annoying NOTICE messages generated by backend */
15571557
res = pgut_execute(conn, "SET client_min_messages = warning;",
1558-
0, NULL);
1558+
0, NULL, true);
15591559
PQclear(res);
15601560

15611561
/* Create restore point */
@@ -1576,7 +1576,7 @@ pg_stop_backup(pgBackup *backup)
15761576
params[0] = name;
15771577

15781578
res = pgut_execute(conn, "SELECT pg_create_restore_point($1)",
1579-
1, params);
1579+
1, params, true);
15801580
PQclear(res);
15811581

15821582
pfree(backup_id);
@@ -1610,13 +1610,11 @@ pg_stop_backup(pgBackup *backup)
16101610
}
16111611
else
16121612
{
1613-
if (current.tablespace_map_exists)
1614-
{
1615-
/* We cannot execute pg_read_file after pg_stop_backup */
1616-
tablespace_map_content = pgut_execute(conn,
1617-
"SELECT pg_read_file('tablespace_map')",
1618-
0, NULL);
1619-
}
1613+
1614+
tablespace_map_content = pgut_execute(conn,
1615+
"SELECT pg_read_file('tablespace_map');",
1616+
0, NULL, false);
1617+
16201618
sent = pgut_send(conn,
16211619
"SELECT"
16221620
" pg_read_file('backup_label') as labelfile,"
@@ -1739,11 +1737,8 @@ pg_stop_backup(pgBackup *backup)
17391737
*/
17401738
if (exclusive_backup)
17411739
{
1742-
if (current.tablespace_map_exists)
1743-
{
1740+
if (PQresultStatus(tablespace_map_content) == PGRES_TUPLES_OK)
17441741
val = PQgetvalue(tablespace_map_content, 0, 0);
1745-
PQclear(tablespace_map_content);
1746-
}
17471742
}
17481743
else
17491744
val = PQgetvalue(res, 0, 4);
@@ -1776,6 +1771,7 @@ pg_stop_backup(pgBackup *backup)
17761771
file->path = strdup(PG_TABLESPACE_MAP_FILE);
17771772
parray_append(backup_files_list, file);
17781773
}
1774+
PQclear(tablespace_map_content);
17791775
}
17801776
PQclear(res);
17811777
if (stream_wal)
@@ -1832,7 +1828,7 @@ checkpoint_timeout(void)
18321828
const char *hintmsg;
18331829
int val_int;
18341830

1835-
res = pgut_execute(backup_conn, "show checkpoint_timeout", 0, NULL);
1831+
res = pgut_execute(backup_conn, "show checkpoint_timeout", 0, NULL, true);
18361832
val = PQgetvalue(res, 0, 0);
18371833

18381834
if (!parse_int(val, &val_int, OPTION_UNIT_S, &hintmsg))
@@ -2691,7 +2687,7 @@ get_last_ptrack_lsn(void)
26912687
uint32 xrecoff;
26922688
XLogRecPtr lsn;
26932689

2694-
res = pgut_execute(backup_conn, "select pg_ptrack_control_lsn()", 0, NULL);
2690+
res = pgut_execute(backup_conn, "select pg_ptrack_control_lsn()", 0, NULL, true);
26952691

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

src/dir.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ static char *pgdata_exclude_files[] =
7676
"postmaster.pid",
7777
"postmaster.opts",
7878
"backup_label",
79+
"tablespace_map",
7980
NULL
8081
};
8182

@@ -399,15 +400,6 @@ dir_list_file_internal(parray *files, const char *root, bool exclude,
399400
file->name = file_name;
400401
}
401402

402-
/* Exclude tablespace_map from backup but we must be aware of its existence
403-
* for correct stop_backup procedure in exclusive mode
404-
*/
405-
if (strcmp(file->name, "tablespace_map") == 0)
406-
{
407-
current.tablespace_map_exists = true;
408-
return;
409-
}
410-
411403
/* Check if we need to exclude file by name */
412404
for (i = 0; pgdata_exclude_files[i]; i++)
413405
if (strcmp(file->name, pgdata_exclude_files[i]) == 0)

src/pg_probackup.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,6 @@ typedef struct pgBackup
222222
time_t parent_backup; /* Identifier of the previous backup.
223223
* Which is basic backup for this
224224
* incremental backup. */
225-
/* Is tablespace_map exists in PGDATA */
226-
bool tablespace_map_exists;
227225
} pgBackup;
228226

229227
/* Recovery target for restore and validate subcommands */

src/utils/pgut.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,7 +1289,7 @@ pgut_set_port(const char *new_port)
12891289
}
12901290

12911291
PGresult *
1292-
pgut_execute(PGconn* conn, const char *query, int nParams, const char **params)
1292+
pgut_execute(PGconn* conn, const char *query, int nParams, const char **params, bool exit_on_error)
12931293
{
12941294
PGresult *res;
12951295

@@ -1322,16 +1322,19 @@ pgut_execute(PGconn* conn, const char *query, int nParams, const char **params)
13221322
res = PQexecParams(conn, query, nParams, NULL, params, NULL, NULL, 0);
13231323
on_after_exec();
13241324

1325-
switch (PQresultStatus(res))
1325+
if (exit_on_error)
13261326
{
1327-
case PGRES_TUPLES_OK:
1328-
case PGRES_COMMAND_OK:
1329-
case PGRES_COPY_IN:
1330-
break;
1331-
default:
1332-
elog(ERROR, "query failed: %squery was: %s",
1333-
PQerrorMessage(conn), query);
1334-
break;
1327+
switch (PQresultStatus(res))
1328+
{
1329+
case PGRES_TUPLES_OK:
1330+
case PGRES_COMMAND_OK:
1331+
case PGRES_COPY_IN:
1332+
break;
1333+
default:
1334+
elog(ERROR, "query failed: %squery was: %s",
1335+
PQerrorMessage(conn), query);
1336+
break;
1337+
}
13351338
}
13361339

13371340
return res;

src/utils/pgut.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ extern PGconn *pgut_connect_replication_extended(const char *pghost, const char
124124
const char *dbname, const char *login,
125125
const char *pwd);
126126
extern void pgut_disconnect(PGconn *conn);
127-
extern PGresult *pgut_execute(PGconn* conn, const char *query, int nParams, const char **params);
127+
extern PGresult *pgut_execute(PGconn* conn, const char *query, int nParams, const char **params, bool exit_on_error);
128128
extern bool pgut_send(PGconn* conn, const char *query, int nParams, const char **params, int elevel);
129129
extern void pgut_cancel(PGconn* conn);
130130
extern int pgut_wait(int num, PGconn *connections[], struct timeval *timeout);

0 commit comments

Comments
 (0)