Thread: Quick question regarding HeapTupleHeaderData.t_ctid

Quick question regarding HeapTupleHeaderData.t_ctid

From
Aleksander Alekseev
Date:
Hi hackers,

It's been a while since the last time I explored how PostgreSQL stores
the data on disk, so I decided to refresh my memory. All in all this
topic is well documented, but there is one question that I couldn't
find an answer to quickly.

From README.HOT:

> If an update changes any indexed column, or there is not room on the
> same page for the new tuple, then the HOT chain ends: the last member
> has a regular t_ctid link to the next version and is not marked
> HEAP_HOT_UPDATED.

So t_ctid will point to the newer version of the tuple regardless of
whether HOT is used or not. But I couldn't find an answer to how
t_ctid is used when a tuple is not a part of a HOT chain, or is the
last item in the chain. Which brings a question, maybe it shouldn't
take that much space on disk.

Probably I missed something. Could you please point me to the document
or comments that describe this topic? Or maybe we should add a brief
comment to HeapTupleHeaderData.t_ctid field and/or README.HOT that
would clarify this. For sure this could be learned from the code, but
I believe clarifying this moment in the comments could simplify the
life of the newcomers a bit.

-- 
Best regards,
Aleksander Alekseev



Re: Quick question regarding HeapTupleHeaderData.t_ctid

From
Tom Lane
Date:
Aleksander Alekseev <aleksander@timescale.com> writes:
> So t_ctid will point to the newer version of the tuple regardless of
> whether HOT is used or not. But I couldn't find an answer to how
> t_ctid is used when a tuple is not a part of a HOT chain, or is the
> last item in the chain.

t_ctid points to the tuple itself if it's the latest version of its row.

> Which brings a question, maybe it shouldn't
> take that much space on disk.

How would you make it optional?  In particular, what are you going to
to when it's time to update a row (and therefore insert a ctid link)
and the page is already completely full?

            regards, tom lane



Re: Quick question regarding HeapTupleHeaderData.t_ctid

From
Aleksander Alekseev
Date:
Hi Tom,

> > Which brings a question, maybe it shouldn't
> > take that much space on disk.
>
> How would you make it optional?  In particular, what are you going to
> to when it's time to update a row (and therefore insert a ctid link)
> and the page is already completely full?

In other words, if I have an ItemPointer to an old tuple and try to
UPDATE it, t_ctid allows me to find the next page with another HOT
chain and, if possible, add a new tuple to that HOT chain. And
although there are newer versions of the tuple they are not
necessarily alive, e.g. if the corresponding transactions were
aborted, or they are running and it's not clear whether they will
succeed or not. I didn't think about this scenario.

It also explains why t_ctid can't be variable in size depending on
whether it points to a tuple in the same page or in the different one.
Next time we change t_ctid its size may change which will require
resizing the tuple, and the whole story becomes very complicated.

I think I get it now. Many thanks!

Just to clarify, is t_ctid used for anything _but_ HOT?

-- 
Best regards,
Aleksander Alekseev



Re: Quick question regarding HeapTupleHeaderData.t_ctid

From
Aleksander Alekseev
Date:
Hi again,

> Just to clarify, is t_ctid used for anything _but_ HOT?

Apparently, I got carried away with HOT too much. htup_details.h
pretty much answers that it does.

-- 
Best regards,
Aleksander Alekseev