cf5955-fixes.patch.no-cfbot

text/plain

Filename: cf5955-fixes.patch.no-cfbot
Type: text/plain
Part: 0
Message: Re: pg_waldump: support decoding of WAL inside tarfile
diff --git a/src/bin/pg_verifybackup/pg_verifybackup.c b/src/bin/pg_verifybackup/pg_verifybackup.c
index 935ab8fafa8..db79dd39103 100644
--- a/src/bin/pg_verifybackup/pg_verifybackup.c
+++ b/src/bin/pg_verifybackup/pg_verifybackup.c
@@ -131,6 +131,7 @@ main(int argc, char **argv)
 		{"quiet", no_argument, NULL, 'q'},
 		{"skip-checksums", no_argument, NULL, 's'},
 		{"wal-path", required_argument, NULL, 'w'},
+		{"wal-directory", required_argument, NULL, 'w'},	/* deprecated */
 		{NULL, 0, NULL, 0}
 	};
 
diff --git a/src/bin/pg_waldump/archive_waldump.c b/src/bin/pg_waldump/archive_waldump.c
index 1479efe61f5..f0cc42b18bf 100644
--- a/src/bin/pg_waldump/archive_waldump.c
+++ b/src/bin/pg_waldump/archive_waldump.c
@@ -236,6 +236,13 @@ free_archive_reader(XLogDumpPrivate *privateInfo)
 	 */
 	astreamer_free(privateInfo->archive_streamer);
 
+	/* Free the reusable read buffer. */
+	if (privateInfo->archive_read_buf != NULL)
+	{
+		pg_free(privateInfo->archive_read_buf);
+		privateInfo->archive_read_buf = NULL;
+	}
+
 	/* Close the file. */
 	if (close(privateInfo->archive_fd) != 0)
 		pg_log_error("could not close file \"%s\": %m",
@@ -350,17 +357,17 @@ read_archive_wal_page(XLogDumpPrivate *privateInfo, XLogRecPtr targetPagePtr,
 	}
 
 	/*
-	 * Should have either have successfully read all the requested bytes or
-	 * reported a failure before this point.
+	 * Should have successfully read all the requested bytes or reported a
+	 * failure before this point.
 	 */
 	Assert(nbytes == 0);
 
 	/*
-	 * NB: We return the fixed value provided as input. Although we could
-	 * return a boolean since we either successfully read the WAL page or
-	 * raise an error, but the caller expects this value to be returned. The
-	 * routine that reads WAL pages from the physical WAL file follows the
-	 * same convention.
+	 * NB: We return the fixed value provided as input. We could return a
+	 * boolean since we either successfully read the WAL page or raise an
+	 * error, but the caller expects this value to be returned. The routine
+	 * that reads WAL pages from the physical WAL file follows the same
+	 * convention.
 	 */
 	return count;
 }
@@ -368,8 +375,8 @@ read_archive_wal_page(XLogDumpPrivate *privateInfo, XLogRecPtr targetPagePtr,
 /*
  * Clears the buffer of a WAL entry that is being ignored.  This frees up memory
  * and prevents the accumulation of irrelevant WAL data.  Additionally,
- * conditionally setting cur_file within privateinfo to NULL ensures the
- * archive streamer skips unnecessary copy operations
+ * conditionally setting cur_file within privateInfo to NULL ensures the
+ * archive streamer skips unnecessary copy operations.
  */
 void
 free_archive_wal_entry(const char *fname, XLogDumpPrivate *privateInfo)
@@ -498,11 +505,18 @@ static int
 read_archive_file(XLogDumpPrivate *privateInfo, Size count)
 {
 	int			rc;
-	char	   *buffer;
 
-	buffer = pg_malloc(count * sizeof(uint8));
+	/* Allocate or grow the reusable read buffer as needed */
+	if (privateInfo->archive_read_buf == NULL ||
+		privateInfo->archive_read_buf_size < count)
+	{
+		if (privateInfo->archive_read_buf != NULL)
+			pg_free(privateInfo->archive_read_buf);
+		privateInfo->archive_read_buf = pg_malloc(count);
+		privateInfo->archive_read_buf_size = count;
+	}
 
-	rc = read(privateInfo->archive_fd, buffer, count);
+	rc = read(privateInfo->archive_fd, privateInfo->archive_read_buf, count);
 	if (rc < 0)
 		pg_fatal("could not read file \"%s\": %m",
 				 privateInfo->archive_name);
@@ -513,8 +527,8 @@ read_archive_file(XLogDumpPrivate *privateInfo, Size count)
 	 */
 	if (rc > 0)
 		astreamer_content(privateInfo->archive_streamer, NULL,
-						  buffer, rc, ASTREAMER_UNKNOWN);
-	pg_free(buffer);
+						  privateInfo->archive_read_buf, rc,
+						  ASTREAMER_UNKNOWN);
 
 	return rc;
 }
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index 4b438b53ead..e970b007883 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -491,7 +491,7 @@ TarWALDumpReadPage(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen,
 	if (!XLByteInSeg(targetPagePtr, curSegNo, WalSegSz))
 	{
 		char		fname[MAXFNAMELEN];
-		XLogSegNo   nextSegNo;
+		XLogSegNo	nextSegNo;
 
 		/*
 		 * Calculate the next WAL segment to be decoded from the given page
@@ -509,9 +509,10 @@ TarWALDumpReadPage(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen,
 		}
 
 		/*
-		 * If in pre-reading mode (prior to actual decoding), do not delete any
-		 * entries that might be requested again once the decoding loop starts.
-		 * For more details, see the comments in read_archive_wal_page().
+		 * If in pre-reading mode (prior to actual decoding), do not delete
+		 * any entries that might be requested again once the decoding loop
+		 * starts. For more details, see the comments in
+		 * read_archive_wal_page().
 		 */
 		if (private->decoding_started && curSegNo < nextSegNo)
 		{
@@ -908,7 +909,7 @@ main(int argc, char **argv)
 	char	   *waldir = NULL;
 	char	   *walpath = NULL;
 	char	   *errormsg;
-	pg_compress_algorithm compression;
+	pg_compress_algorithm compression = PG_COMPRESSION_NONE;
 
 	static struct option long_options[] = {
 		{"bkp-details", no_argument, NULL, 'b'},
@@ -1317,7 +1318,6 @@ main(int argc, char **argv)
 				segno = endsegno;
 			}
 
-
 			if (!XLByteInSeg(private.endptr, segno, private.segsize) &&
 				private.endptr != (segno + 1) * private.segsize)
 			{
diff --git a/src/bin/pg_waldump/pg_waldump.h b/src/bin/pg_waldump/pg_waldump.h
index 6c242b7fcbc..1097390d575 100644
--- a/src/bin/pg_waldump/pg_waldump.h
+++ b/src/bin/pg_waldump/pg_waldump.h
@@ -36,6 +36,8 @@ typedef struct XLogDumpPrivate
 	int			archive_fd;		/* File descriptor for the open tar file */
 
 	astreamer  *archive_streamer;
+	char	   *archive_read_buf;	/* Reusable read buffer for archive I/O */
+	Size		archive_read_buf_size;
 
 	/* What the archive streamer is currently reading */
 	struct ArchivedWALFile *cur_file;
diff --git a/src/common/compression.c b/src/common/compression.c
index f117e21237f..fb27501d297 100644
--- a/src/common/compression.c
+++ b/src/common/compression.c
@@ -46,7 +46,7 @@ static bool expect_boolean_value(char *keyword, char *value,
  * sets *algorithm if the name is recognized. Otherwise returns false.
  */
 bool
-parse_tar_compress_algorithm(char *fname, pg_compress_algorithm *algorithm)
+parse_tar_compress_algorithm(const char *fname, pg_compress_algorithm *algorithm)
 {
 	int			fname_len = strlen(fname);
 
diff --git a/src/include/common/compression.h b/src/include/common/compression.h
index 50f21656b88..f99c747cdd3 100644
--- a/src/include/common/compression.h
+++ b/src/include/common/compression.h
@@ -41,7 +41,7 @@ typedef struct pg_compress_specification
 
 extern void parse_compress_options(const char *option, char **algorithm,
 								   char **detail);
-extern bool parse_tar_compress_algorithm(char *fname,
+extern bool parse_tar_compress_algorithm(const char *fname,
 										 pg_compress_algorithm *algorithm);
 extern bool parse_compress_algorithm(char *name, pg_compress_algorithm *algorithm);
 extern const char *get_compress_algorithm_name(pg_compress_algorithm algorithm);