Remove read_archive_file()'s "count" parameter.

Instead, always try to fill the allocated buffer completely.
The previous coding apparently intended (though it's undocumented)
to read only small amounts of data until we are able to identify the
WAL segment size and begin filtering out unwanted segments.  However
this extra complication has no measurable value according to simple
testing here, and it could easily be a net loss if there is a
substantial amount of non-WAL data in the archive file before the
first WAL file.

Discussion: https://postgr.es/m/3341199.1774221191@sss.pgh.pa.us
This commit is contained in:
Tom Lane 2026-03-24 12:06:08 -04:00
parent 2102ebb195
commit ca1f1ade3f
2 changed files with 9 additions and 21 deletions

View file

@ -89,7 +89,7 @@ typedef struct astreamer_waldump
static ArchivedWALFile *get_archive_wal_entry(const char *fname,
XLogDumpPrivate *privateInfo);
static bool read_archive_file(XLogDumpPrivate *privateInfo, Size count);
static bool read_archive_file(XLogDumpPrivate *privateInfo);
static void setup_tmpwal_dir(const char *waldir);
static void cleanup_tmpwal_dir_atexit(void);
@ -156,14 +156,11 @@ init_archive_reader(XLogDumpPrivate *privateInfo,
privateInfo->archive_streamer = streamer;
/*
* Allocate a buffer for reading the archive file to facilitate content
* decoding; read requests must not exceed the allocated buffer size.
* Allocate a buffer for reading the archive file to begin content
* decoding.
*/
privateInfo->archive_read_buf = pg_malloc(READ_CHUNK_SIZE);
#ifdef USE_ASSERT_CHECKING
privateInfo->archive_read_buf_size = READ_CHUNK_SIZE;
#endif
/*
* Hash table storing WAL entries read from the archive with an arbitrary
@ -182,7 +179,7 @@ init_archive_reader(XLogDumpPrivate *privateInfo,
*/
while (entry == NULL)
{
if (!read_archive_file(privateInfo, XLOG_BLCKSZ))
if (!read_archive_file(privateInfo))
pg_fatal("could not find WAL in archive \"%s\"",
privateInfo->archive_name);
@ -402,7 +399,7 @@ read_archive_wal_page(XLogDumpPrivate *privateInfo, XLogRecPtr targetPagePtr,
fname, privateInfo->archive_name,
(long long int) (count - nbytes),
(long long int) count);
if (!read_archive_file(privateInfo, READ_CHUNK_SIZE))
if (!read_archive_file(privateInfo))
pg_fatal("unexpected end of archive \"%s\" while reading \"%s\": read %lld of %lld bytes",
privateInfo->archive_name, fname,
(long long int) (count - nbytes),
@ -523,7 +520,7 @@ get_archive_wal_entry(const char *fname, XLogDumpPrivate *privateInfo)
/*
* Read more data. If we reach EOF, the desired file is not present.
*/
if (!read_archive_file(privateInfo, READ_CHUNK_SIZE))
if (!read_archive_file(privateInfo))
pg_fatal("could not find WAL \"%s\" in archive \"%s\"",
fname, privateInfo->archive_name);
}
@ -533,10 +530,6 @@ get_archive_wal_entry(const char *fname, XLogDumpPrivate *privateInfo)
* Reads a chunk from the archive file and passes it through the streamer
* pipeline for decompression (if needed) and tar member extraction.
*
* count is the maximum amount to try to read this time. Note that it's
* measured in raw file bytes, and may have little to do with how much
* comes out of decompression/extraction.
*
* Returns true if successful, false if there is no more data.
*
* Callers must be aware that a single call may trigger multiple callbacks
@ -548,19 +541,17 @@ get_archive_wal_entry(const char *fname, XLogDumpPrivate *privateInfo)
* within the same call.
*/
static bool
read_archive_file(XLogDumpPrivate *privateInfo, Size count)
read_archive_file(XLogDumpPrivate *privateInfo)
{
int rc;
/* The read request must not exceed the allocated buffer size. */
Assert(privateInfo->archive_read_buf_size >= count);
/* Fail if we already reached EOF in a prior call. */
if (privateInfo->archive_fd_eof)
return false;
/* Try to read some more data. */
rc = read(privateInfo->archive_fd, privateInfo->archive_read_buf, count);
rc = read(privateInfo->archive_fd, privateInfo->archive_read_buf,
privateInfo->archive_read_buf_size);
if (rc < 0)
pg_fatal("could not read file \"%s\": %m",
privateInfo->archive_name);

View file

@ -39,10 +39,7 @@ typedef struct XLogDumpPrivate
astreamer *archive_streamer;
char *archive_read_buf; /* Reusable read buffer for archive I/O */
#ifdef USE_ASSERT_CHECKING
Size archive_read_buf_size;
#endif
/*
* The buffer for the WAL file the archive streamer is currently reading,