Re: BUG #18212: Functions txid_status() and pg_xact_status() return invalid status of the specified transaction

From: Karina Litskevich <litskevichkarina(at)gmail(dot)com>
To: kyzevan23(at)mail(dot)ru, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #18212: Functions txid_status() and pg_xact_status() return invalid status of the specified transaction
Date: 2023-11-24 11:38:23
Message-ID: CACiT8iawSCnQGMGqdXOC4CwB843NUhewzcfPGApFDhFz7DFapQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi,

The problem here is in TransactionIdInRecentPast() function. If
ShmemVariableCache->oldestClogXid had been stored as a FullTransactionId,
this function would be very simple for normal transaction ids: ids between
oldestClogXid and next full transaction id are in the recent past (return
true), ids before oldestClogXid are too far in the past (return false),
ids after next full xid are in the future (raise an error). Expected
results are demonstrated in the following picture, where vertical bar is
used to separate different epochs.

|pppppppppppppppp|pppppppppppprrff|ffffffffffffffff|
^ ^
| |
| next fxid
|
oldestClogXid

The problem is that oldestClogXid is a TransactionId, so it's epoch is not
stored, and the following condition is wrong:

if (xid_epoch + 1 < now_epoch
|| (xid_epoch + 1 == now_epoch && xid < now_epoch_next_xid)
|| TransactionIdPrecedes(xid, ShmemVariableCache->oldestClogXid))
return false;

First, given full transaction id (xid_epoch, xid) is compared to the next
full transaction id (now_epoch, now_epoch_next_xid), and if it's more than
one epoch older, it's far in the past. For newer ids, it's transaction id
part without an epoch is compared to oldestClogXid, but it's a modulo-2^32
comparison, so only 2^31 xids before oldestClogXid are considered preceding
it. Thus, all full transaction ids between (next full transaction id - 2^32)
and (oldestClogXid - 2^31) are mistakenly considered to be in the recent
past.

|pppppppppppppprr|rrrrpppppppprrff|ffffffffffffffff|
^ ^
| |
| next fxid
|
oldestClogXid

In the attached patch I suggest calculating an epoch for oldestClogXid
assuming it's not much older than next full transaction id, make a full
transaction id for oldestClogXid, and then just compare it to the given
full transaction id.

Best regards,
Karina Litskevich
Postgres Professional: http://postgrespro.com/

Attachment Content-Type Size
v1-0001-Fix-TransactionIdInRecentPast.patch text/x-patch 2.4 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Tom Lane 2023-11-24 18:01:02 Re: BUG #18214: poly_contain (@>) hangs forever for input data with zeros and infinities
Previous Message Nikolay Shaplov 2023-11-24 11:24:49 Re: BUG #18214: poly_contain (@>) hangs forever for input data with zeros and infinities