From 63ae0cabc3691dffc8227ac6f9d23aca96ea0095 Mon Sep 17 00:00:00 2001
From: David Gilman <davidgilman1@gmail.com>
Date: Wed, 20 May 2020 22:49:28 -0400
Subject: [PATCH] pg_restore fix v2

commit message to come
---
 doc/src/sgml/ref/pg_restore.sgml   |  9 +++++++++
 src/bin/pg_dump/pg_backup_custom.c | 20 ++++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git doc/src/sgml/ref/pg_restore.sgml doc/src/sgml/ref/pg_restore.sgml
index 232f88024f..fd23d6720c 100644
--- doc/src/sgml/ref/pg_restore.sgml
+++ doc/src/sgml/ref/pg_restore.sgml
@@ -279,6 +279,15 @@ PostgreSQL documentation
         jobs cannot be used together with the
         option <option>--single-transaction</option>.
        </para>
+
+       <para>
+        The custom archive format may not work with the <option>-j</option>
+        option if the archive was originally created by writing the archive
+        to an unseekable output file. For the best concurrent restoration
+        performance with the custom archive format use
+        <application>pg_dump</application>'s <option>--file</option> option
+        to specify an output file.
+       </para>
       </listitem>
      </varlistentry>
 
diff --git src/bin/pg_dump/pg_backup_custom.c src/bin/pg_dump/pg_backup_custom.c
index 369dcea429..8dfb6581d1 100644
--- src/bin/pg_dump/pg_backup_custom.c
+++ src/bin/pg_dump/pg_backup_custom.c
@@ -423,9 +423,25 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te)
 	{
 		/*
 		 * We cannot seek directly to the desired block.  Instead, skip over
-		 * block headers until we find the one we want.  This could fail if we
-		 * are asked to restore items out-of-order.
+		 * block headers until we find the one we want.
 		 */
+
+		if (ctx->hasSeek)
+		{
+			/*
+			 * Start searching from the first block. If this is possible, we're
+			 * all but guaranteed to find the block, although at the cost of a bunch
+			 * of redundant, tiny reads. TOC requests aren't guaranteed to come in
+			 * disk order so this is a necessary evil.
+			 *
+			 * If the input file can't be seeked we're at the mercy of the
+			 * file's TOC layout on disk. An out-of-order restore request will
+			 * halt the restore.
+			 */
+			if (fseeko(AH->FH, ctx->dataStart, SEEK_SET) != 0)
+				fatal("error during file seek: %m");
+		}
+
 		_readBlockHeader(AH, &blkType, &id);
 
 		while (blkType != EOF && id != te->dumpId)
-- 
2.26.2

