TransactionXmin != MyProc->xmin

From: Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
To: "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Subject: TransactionXmin != MyProc->xmin
Date: 2024-12-12 18:16:39
Message-ID: d27a046d-a1e4-47d1-a95c-fbabe41debb4@iki.fi
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

The comment in GetSnapshotData() defines transactionXmin like this:

> TransactionXmin: the oldest xmin of any snapshot in use in the
> current transaction (this is the same as MyProc->xmin).
However, we don't update TransactionXmin when we update MyProc->xmin in
SnapshotResetXmin(). So TransactionXmin can be older than MyProc->xmin.

I browsed around to see if that might cause trouble, and found one such
case: SubTransGetTopmostTransaction() uses TransactionXmin as the
cut-off point so that it doesn't try to perform lookups of old XIDs that
might've already been truncated away from pg_subtrans. When
TransactionXmin is older than MyProc->xmin, then it might do that. The
attached isolation test demonstrates that case and produces an error:

ERROR: could not access status of transaction 17190290
DETAIL: Could not open file "pg_subtrans/0106": No such file or directory.

A straightforward fix is to ensure that TransactionXmin is updated
whenever MyProc->xmin is:

diff --git a/src/backend/utils/time/snapmgr.c
b/src/backend/utils/time/snapmgr.c
index a1a0c2adeb6..f59830abd21 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -883,7 +883,7 @@ SnapshotResetXmin(void)
pairingheap_first(&RegisteredSnapshots));

if (TransactionIdPrecedes(MyProc->xmin, minSnapshot->xmin))
- MyProc->xmin = minSnapshot->xmin;
+ MyProc->xmin = TransactionXmin = minSnapshot->xmin;
}

/*

Anyone see a reason not to do that?

There are a two other places where we set MyProc->xmin without updating
TransactionXmin:

1. In ProcessStandbyHSFeedbackMessage(). AFAICS that's OK because
walsender doesn't use TransactionXmin for anything.

2. In SnapBuildInitialSnapshot(). I suppose that's also OK because the
TransactionXmin isn't used. I don't quite remember when that function
might be called though.

In any case, I propose that we set TransactionXmin in all of those cases
as well, so that TransactionXmin is always the equal to MyProc->xmin.
Maybe even rename it to MyProcXmin to make that more clear.

--
Heikki Linnakangas
Neon (https://neon.tech)

Attachment Content-Type Size
subxid-truncation.spec text/x-rpm-spec 2.3 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Jeff Davis 2024-12-12 18:20:14 Re: fixing tsearch locale support
Previous Message Jeff Davis 2024-12-12 18:14:21 Re: fixing tsearch locale support