aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2019-09-06 08:22:32 -0400
committerRobert Haas <rhaas@postgresql.org>2019-09-06 09:05:12 -0400
commitf697c6396d73c1e6d550afed84a6bd8362d9a0d4 (patch)
tree359d844d8b238e02c5e043a52f02c50bbeb63cb9
parent62724bd952a2a2a7e114364f5af655f11e21289f (diff)
downloadpostgresql-f697c6396d73c1e6d550afed84a6bd8362d9a0d4.tar.gz
postgresql-f697c6396d73c1e6d550afed84a6bd8362d9a0d4.zip
When performing a base backup, check for read errors.
The old code didn't differentiate between a read error and a concurrent truncation. fread reports both of these by returning 0; you have to use feof() or ferror() to distinguish between them, which this code did not do. It might be a better idea to use read() rather than fread() here, so that we can display a less-generic error message, but I'm not sure that would qualify as a back-patchable bug fix, so just do this much for now. Jeevan Chalke, reviewed by Jeevan Ladhe and by me. Discussion: http://postgr.es/m/CA+TgmobG4ywMzL5oQq2a8YKp8x2p3p1LOMMcGqpS7aekT9+ETA@mail.gmail.com
-rw-r--r--src/backend/replication/basebackup.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index 8259ec5bd89..ddb1de0621d 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -84,6 +84,18 @@ static char *statrelpath = NULL;
*/
#define THROTTLING_FREQUENCY 8
+/*
+ * Checks whether we encountered any error in fread(). fread() doesn't give
+ * any clue what has happened, so we check with ferror(). Also, neither
+ * fread() nor ferror() set errno, so we just throw a generic error.
+ */
+#define CHECK_FREAD_ERROR(fp, filename) \
+do { \
+ if (ferror(fp)) \
+ ereport(ERROR, \
+ (errmsg("could not read from file \"%s\"", filename))); \
+} while (0)
+
/* The actual number of bytes, transfer of which may cause sleep. */
static uint64 throttling_sample;
@@ -434,6 +446,8 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
break;
}
+ CHECK_FREAD_ERROR(fp, pathbuf);
+
if (len != XLogSegSize)
{
CheckXLogRemoved(segno, tli);
@@ -1173,6 +1187,8 @@ sendFile(char *readfilename, char *tarfilename, struct stat * statbuf,
}
}
+ CHECK_FREAD_ERROR(fp, readfilename);
+
/* If the file was truncated while we were sending it, pad it with zeros */
if (len < statbuf->st_size)
{