Subject: [PATCH] Do not push the active snapshot for copy_table_data before it's needed.

From: Antonin Houska <[email-masked]>
Date: Fri, 10 Apr 2026 12:17:36 +0200

make_new_heap() can launch parallel workers when building index on TOAST
relation. If the snapshot for copy_table_data() is already the active
snapshot, the workers can incorrectly consider it their transaction snapshot.
---
 src/backend/commands/repack.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c
index 58e3867246f..08fd132a4e3 100644
--- a/src/backend/commands/repack.c
+++ b/src/backend/commands/repack.c
@@ -1013,8 +1013,6 @@ rebuild_relation(Relation OldHeap, Relation index, bool verbose,
 		 * Wait until the worker has the initial snapshot and retrieve it.
 		 */
 		snapshot = get_initial_snapshot(decoding_worker);
-
-		PushActiveSnapshot(snapshot);
 	}
 
 	/* for CLUSTER or REPACK USING INDEX, mark the index as the one to use */
@@ -1038,6 +1036,8 @@ rebuild_relation(Relation OldHeap, Relation index, bool verbose,
 	NewHeap = table_open(OIDNewHeap, NoLock);
 
 	/* Copy the heap data into the new table in the desired order */
+	if (snapshot)
+		PushActiveSnapshot(snapshot);
 	copy_table_data(NewHeap, OldHeap, index, snapshot, verbose,
 					&swap_toast_by_content, &frozenXid, &cutoffMulti);
 
-- 
2.47.3

--=-=-=--