v1-0001-Fix-GetStrictOldestNonRemovableTransactionId-on-s.patch

application/octet-stream

Filename: v1-0001-Fix-GetStrictOldestNonRemovableTransactionId-on-s.patch
Type: application/octet-stream
Part: 0
Message: Re: collect_corrupt_items_vacuum.patch

Patch

Format: format-patch
Series: patch v1-0001
Subject: Fix GetStrictOldestNonRemovableTransactionId() on standby
File+
contrib/pg_visibility/pg_visibility.c 11 1
contrib/pg_visibility/t/001_concurrent_transaction.pl 17 2
From 0d4b46ac9e69ef6289d8dbf2c52e505c48515cd5 Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Wed, 14 Aug 2024 03:13:57 +0300
Subject: [PATCH v1] Fix GetStrictOldestNonRemovableTransactionId() on standby

e85662df44 implemented GetStrictOldestNonRemovableTransactionId() function
for computation of xid horizon that avoid reporting of false errors.
However, GetStrictOldestNonRemovableTransactionId() uses
GetRunningTransactionData() even on standby leading to an assertion failure.

Given that we decided to ignore KnownAssignedXids and standby can't have
own running xids, we switch to use TransamVariables->nextXid as a xid horizon.

Reported-by: Heikki Linnakangas
Discussion: https://postgr.es/m/42218c4f-2c8d-40a3-8743-4d34dd0e4cce%40iki.fi
---
 contrib/pg_visibility/pg_visibility.c         | 12 +++++++++++-
 .../t/001_concurrent_transaction.pl           | 19 +++++++++++++++++--
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c
index 1a1a4ff7be7..067c804e00d 100644
--- a/contrib/pg_visibility/pg_visibility.c
+++ b/contrib/pg_visibility/pg_visibility.c
@@ -560,7 +560,17 @@ GetStrictOldestNonRemovableTransactionId(Relation rel)
 {
 	RunningTransactions runningTransactions;
 
-	if (rel == NULL || rel->rd_rel->relisshared || RecoveryInProgress())
+	if (RecoveryInProgress())
+	{
+		TransactionId result;
+
+		/* As we ignore KnownAssignedXids on standby, just pick nextXid */
+		LWLockAcquire(XidGenLock, LW_SHARED);
+		result = XidFromFullTransactionId(TransamVariables->nextXid);
+		LWLockRelease(XidGenLock);
+		return result;
+	}
+	else if (rel == NULL || rel->rd_rel->relisshared)
 	{
 		/* Shared relation: take into account all running xids */
 		runningTransactions = GetRunningTransactionData();
diff --git a/contrib/pg_visibility/t/001_concurrent_transaction.pl b/contrib/pg_visibility/t/001_concurrent_transaction.pl
index c31d041757d..498ce412d9a 100644
--- a/contrib/pg_visibility/t/001_concurrent_transaction.pl
+++ b/contrib/pg_visibility/t/001_concurrent_transaction.pl
@@ -10,11 +10,18 @@ use PostgreSQL::Test::Utils;
 use Test::More;
 
 
+# Initialize the primary node
 my $node = PostgreSQL::Test::Cluster->new('main');
-
-$node->init;
+$node->init(allows_streaming => 1);
 $node->start;
 
+# Initialize the streaming standby
+my $backup_name = 'my_backup';
+$node->backup($backup_name);
+my $standby = PostgreSQL::Test::Cluster->new('standby');
+$standby->init_from_backup($node, $backup_name, has_streaming => 1);
+$standby->start;
+
 # Setup another database
 $node->safe_psql("postgres", "CREATE DATABASE other_database;\n");
 my $bsession = $node->background_psql('other_database');
@@ -39,9 +46,17 @@ my $result = $node->safe_psql("postgres",
 # There should be no false negatives
 ok($result eq "", "pg_check_visible() detects no errors");
 
+# Run pg_check_visible() on standby
+$result = $standby->safe_psql("postgres",
+	"SELECT * FROM pg_check_visible('vacuum_test');");
+
+# There should be no false negatives either
+ok($result eq "", "pg_check_visible() detects no errors");
+
 # Shutdown
 $bsession->query_safe("COMMIT;");
 $bsession->quit;
 $node->stop;
+$standby->stop;
 
 done_testing();
-- 
2.39.3 (Apple Git-146)