diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 14cad19afb..ccd24eb02a 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; }