Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 47e5969

Browse files
committed
Make pg_dump error cleanly with -j against hot standby
Getting a synchronized snapshot is not supported on a hot standby node, and is by default taken when using -j with multiple sessions. Trying to do so still failed, but with a server error that would also go in the log. Instead, proprely detect this case and give a better error message.
1 parent aa86edb commit 47e5969

File tree

4 files changed

+53
-40
lines changed

4 files changed

+53
-40
lines changed

src/bin/pg_dump/pg_backup.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ typedef struct Archive
172172
int verbose;
173173
char *remoteVersionStr; /* server's version string */
174174
int remoteVersion; /* same in numeric form */
175+
bool isStandby; /* is server a standby node */
175176

176177
int minRemoteVersion; /* allowable range */
177178
int maxRemoteVersion;

src/bin/pg_dump/pg_backup_db.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ _check_database_version(ArchiveHandle *AH)
3737
{
3838
const char *remoteversion_str;
3939
int remoteversion;
40+
PGresult *res;
4041

4142
remoteversion_str = PQparameterStatus(AH->connection, "server_version");
4243
remoteversion = PQserverVersion(AH->connection);
@@ -56,6 +57,20 @@ _check_database_version(ArchiveHandle *AH)
5657
remoteversion_str, progname, PG_VERSION);
5758
exit_horribly(NULL, "aborting because of server version mismatch\n");
5859
}
60+
61+
/*
62+
* When running against 9.0 or later, check if we are in recovery mode,
63+
* which means we are on a hot standby.
64+
*/
65+
if (remoteversion >= 90000)
66+
{
67+
res = ExecuteSqlQueryForSingleRow((Archive *) AH, "SELECT pg_catalog.pg_is_in_recovery()");
68+
69+
AH->public.isStandby = (strcmp(PQgetvalue(res, 0, 0), "t") == 0);
70+
PQclear(res);
71+
}
72+
else
73+
AH->public.isStandby = false;
5974
}
6075

6176
/*
@@ -388,6 +403,29 @@ ExecuteSqlQuery(Archive *AHX, const char *query, ExecStatusType status)
388403
return res;
389404
}
390405

406+
/*
407+
* Execute an SQL query and verify that we got exactly one row back.
408+
*/
409+
PGresult *
410+
ExecuteSqlQueryForSingleRow(Archive *fout, char *query)
411+
{
412+
PGresult *res;
413+
int ntups;
414+
415+
res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
416+
417+
/* Expecting a single result only */
418+
ntups = PQntuples(res);
419+
if (ntups != 1)
420+
exit_horribly(NULL,
421+
ngettext("query returned %d row instead of one: %s\n",
422+
"query returned %d rows instead of one: %s\n",
423+
ntups),
424+
ntups, query);
425+
426+
return res;
427+
}
428+
391429
/*
392430
* Convenience function to send a query.
393431
* Monitors result to detect COPY statements

src/bin/pg_dump/pg_backup_db.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ extern int ExecuteSqlCommandBuf(Archive *AHX, const char *buf, size_t bufLen);
1616
extern void ExecuteSqlStatement(Archive *AHX, const char *query);
1717
extern PGresult *ExecuteSqlQuery(Archive *AHX, const char *query,
1818
ExecStatusType status);
19+
extern PGresult *ExecuteSqlQueryForSingleRow(Archive *fout, char *query);
1920

2021
extern void EndDBCopyMode(Archive *AHX, const char *tocEntryTag);
2122

src/bin/pg_dump/pg_dump.c

Lines changed: 13 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,6 @@ static bool nonemptyReloptions(const char *reloptions);
255255
static void fmtReloptionsArray(Archive *fout, PQExpBuffer buffer,
256256
const char *reloptions, const char *prefix);
257257
static char *get_synchronized_snapshot(Archive *fout);
258-
static PGresult *ExecuteSqlQueryForSingleRow(Archive *fout, char *query);
259258
static void setupDumpWorker(Archive *AHX);
260259

261260

@@ -647,23 +646,11 @@ main(int argc, char **argv)
647646
dopt.no_security_labels = 1;
648647

649648
/*
650-
* When running against 9.0 or later, check if we are in recovery mode,
651-
* which means we are on a hot standby.
649+
* On hot standby slaves, never try to dump unlogged table data, since it
650+
* will just throw an error.
652651
*/
653-
if (fout->remoteVersion >= 90000)
654-
{
655-
PGresult *res = ExecuteSqlQueryForSingleRow(fout, "SELECT pg_catalog.pg_is_in_recovery()");
656-
657-
if (strcmp(PQgetvalue(res, 0, 0), "t") == 0)
658-
{
659-
/*
660-
* On hot standby slaves, never try to dump unlogged table data,
661-
* since it will just throw an error.
662-
*/
663-
dopt.no_unlogged_table_data = true;
664-
}
665-
PQclear(res);
666-
}
652+
if (fout->isStandby)
653+
dopt.no_unlogged_table_data = true;
667654

668655
/* Select the appropriate subquery to convert user IDs to names */
669656
if (fout->remoteVersion >= 80100)
@@ -1088,7 +1075,16 @@ setup_connection(Archive *AH, const char *dumpencoding,
10881075
else if (AH->numWorkers > 1 &&
10891076
AH->remoteVersion >= 90200 &&
10901077
!dopt->no_synchronized_snapshots)
1078+
{
1079+
if (AH->isStandby)
1080+
exit_horribly(NULL,
1081+
"Synchronized snapshots are not supported on standby servers.\n"
1082+
"Run with --no-synchronized-snapshots instead if you do not need\n"
1083+
"synchronized snapshots.\n");
1084+
1085+
10911086
AH->sync_snapshot_id = get_synchronized_snapshot(AH);
1087+
}
10921088
}
10931089

10941090
static void
@@ -16559,26 +16555,3 @@ fmtReloptionsArray(Archive *fout, PQExpBuffer buffer, const char *reloptions,
1655916555
if (options)
1656016556
free(options);
1656116557
}
16562-
16563-
/*
16564-
* Execute an SQL query and verify that we got exactly one row back.
16565-
*/
16566-
static PGresult *
16567-
ExecuteSqlQueryForSingleRow(Archive *fout, char *query)
16568-
{
16569-
PGresult *res;
16570-
int ntups;
16571-
16572-
res = ExecuteSqlQuery(fout, query, PGRES_TUPLES_OK);
16573-
16574-
/* Expecting a single result only */
16575-
ntups = PQntuples(res);
16576-
if (ntups != 1)
16577-
exit_horribly(NULL,
16578-
ngettext("query returned %d row instead of one: %s\n",
16579-
"query returned %d rows instead of one: %s\n",
16580-
ntups),
16581-
ntups, query);
16582-
16583-
return res;
16584-
}

0 commit comments

Comments
 (0)