aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/pg_stat_statements/pg_stat_statements.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 14cad19afbc..ccd24eb02a0 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -2114,6 +2114,7 @@ qtext_load_file(Size *buffer_size)
char *buf;
int fd;
struct stat stat;
+ Size nread;
fd = OpenTransientFile(PGSS_TEXT_FILE, O_RDONLY | PG_BINARY);
if (fd < 0)
@@ -2154,23 +2155,35 @@ qtext_load_file(Size *buffer_size)
}
/*
- * OK, slurp in the file. If we get a short read and errno doesn't get
- * set, the reason is probably that garbage collection truncated the file
- * since we did the fstat(), so we don't log a complaint --- but we don't
- * return the data, either, since it's most likely corrupt due to
- * concurrent writes from garbage collection.
+ * OK, slurp in the file. Windows fails if we try to read more than
+ * INT_MAX bytes at once, and other platforms might not like that either,
+ * so read a very large file in 1GB segments.
*/
- errno = 0;
- if (read(fd, buf, stat.st_size) != stat.st_size)
+ nread = 0;
+ while (nread < stat.st_size)
{
- if (errno)
- ereport(LOG,
- (errcode_for_file_access(),
- errmsg("could not read file \"%s\": %m",
- PGSS_TEXT_FILE)));
- free(buf);
- CloseTransientFile(fd);
- return NULL;
+ int toread = Min(1024 * 1024 * 1024, stat.st_size - nread);
+
+ /*
+ * If we get a short read and errno doesn't get set, the reason is
+ * probably that garbage collection truncated the file since we did
+ * the fstat(), so we don't log a complaint --- but we don't return
+ * the data, either, since it's most likely corrupt due to concurrent
+ * writes from garbage collection.
+ */
+ errno = 0;
+ if (read(fd, buf + nread, toread) != toread)
+ {
+ if (errno)
+ ereport(LOG,
+ (errcode_for_file_access(),
+ errmsg("could not read file \"%s\": %m",
+ PGSS_TEXT_FILE)));
+ free(buf);
+ CloseTransientFile(fd);
+ return NULL;
+ }
+ nread += toread;
}
if (CloseTransientFile(fd) != 0)
@@ -2178,7 +2191,7 @@ qtext_load_file(Size *buffer_size)
(errcode_for_file_access(),
errmsg("could not close file \"%s\": %m", PGSS_TEXT_FILE)));
- *buffer_size = stat.st_size;
+ *buffer_size = nread;
return buf;
}