Re: unclear behavior xmax/xmin

From: Andres Freund <andres(at)anarazel(dot)de>
To: Mariel Cherkassky <mariel(dot)cherkassky(at)gmail(dot)com>
Cc: pgsql-admin(at)lists(dot)postgresql(dot)org
Subject: Re: unclear behavior xmax/xmin
Date: 2018-11-18 20:23:59
Message-ID: 20181118202359.6cwmsig3jsvzxm2x@alap3.anarazel.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-admin

Hi,

On 2018-11-18 19:13:28 +0200, Mariel Cherkassky wrote:
> - I started transaction A and deleted one row but I didnt commit.
> Afterwards I rolledback the transaction but the xmax of the row was set to
> the txid of transaction A. I opened a new session and run VACUUM on the
> table. However, that record wasnt deleted but the xmax was still set to
> transaction`s A txid. Is that a bug ?

No. A vacuum will not necessarily immeditely process a row/page if has
recently been modified.

> the vacuum process shouldnt delete
> that row because it has an old xmax (there arent any younger transactions).
> In addition, I'm still capable of seeing the record (because of the
> rollback..) but my txid is bigger then the xmax of the record. ? Is that a
> bug ?

No, it's not. For visiblity checks it's not just the xid that counts,
but also whether this xid committed.

bool
HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
Buffer buffer)
...
if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
{
if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple)))
{
if (HeapTupleHeaderGetCmax(tuple) >= snapshot->curcid)
return true; /* deleted after scan started */
else
return false; /* deleted before scan started */
}

if (XidInMVCCSnapshot(HeapTupleHeaderGetRawXmax(tuple), snapshot))
return true;

if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple)))
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
InvalidTransactionId);
return true;
}

> -When I run an update basically its just like running an insert and delete
> (the xmax of the old row is changed to the transaction`s txid and the new
> row contains xmin same as txid of the current transaction and xmax is set
> to 0). However, when I query the table (didnt commit yet) I dont see the
> old record. Is there a way to see it ? Why is that ? I thought that I
> should see the table with a non zero value in the xmax col.

You can use the pageinspect extension to see such rows. We can't
normally show such rows, because it'd violate transactional semantics.

What are you trying to achieve? Just exploring the system?

Greetings,

Andres Freund

In response to

Responses

Browse pgsql-admin by date

  From Date Subject
Next Message Mariel Cherkassky 2018-11-18 20:28:24 Re: unclear behavior xmax/xmin
Previous Message Laurenz Albe 2018-11-18 19:04:49 Re: unclear behavior xmax/xmin