Re: BUG #18212: Functions txid_status() and pg_xact_status() return invalid status of the specified transaction - Mailing list pgsql-bugs

From Karina Litskevich
Subject Re: BUG #18212: Functions txid_status() and pg_xact_status() return invalid status of the specified transaction
Date
Msg-id CACiT8iawSCnQGMGqdXOC4CwB843NUhewzcfPGApFDhFz7DFapQ@mail.gmail.com
Whole thread Raw
In response to BUG #18212: Functions txid_status() and pg_xact_status() return invalid status of the specified transaction  (PG Bug reporting form <noreply@postgresql.org>)
Responses Re: BUG #18212: Functions txid_status() and pg_xact_status() return invalid status of the specified transaction  (Kyotaro Horiguchi <horikyota.ntt@gmail.com>)
List 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

pgsql-bugs by date:

Previous
From: Nikolay Shaplov
Date:
Subject: Re: BUG #18214: poly_contain (@>) hangs forever for input data with zeros and infinities
Next
From: Tom Lane
Date:
Subject: Re: BUG #18214: poly_contain (@>) hangs forever for input data with zeros and infinities