Re: CURRENT OF cursor without OIDs

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Hiroshi Inoue <Inoue(at)tpf(dot)co(dot)jp>
Cc: Ian Lance Taylor <ian(at)airs(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: CURRENT OF cursor without OIDs
Date: 2001-08-09 01:22:56
Message-ID: 20101.997320176@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hiroshi Inoue <Inoue(at)tpf(dot)co(dot)jp> writes:
> Yes mainly but I want the verification by OID even in
> *inside a transaction* cases. For example,

> 1) A backend tx1 fetch a row using cursor.
> 2) Very old backend tx_old deletes the row and commits.
> 3) The new VACUUM starts to run and find the row to be
> completely dead.

This cannot happen. If VACUUM thought that, VACUUM would be completely
broken. Although the row is committed dead, it is still visible to the
transaction using the cursor, so it must not be deleted. This is true
*whether or not the row has been fetched yet*, or ever will be fetched,
by the cursor.

If cursors had this risk then ordinary UPDATE would be equally broken.
What is a cursor except an externally-accessible scan-in-progress?
There is no difference.

> The page is pinned by tx1, so the new VACUUM refuses
> to change the page ? I there could be another story.

The pin stuff doesn't have anything to do with whether TIDs remain
valid. A pin guarantees that a *physical pointer* into a shared buffer
will remain valid --- it protects against VACUUM reshuffling the page
data to compact free space after it's deleted completely-dead tuples.
But reshuffling doesn't invalidate non-dead TIDs. A TID remains valid
until there are no open transactions that could possibly consider the
tuple visible.

> Both seems to be detected by FULL VACUUM as
> 'NOTICE: Child itemid in update-chain marked as unused - can't
> continue repair_frag' though it may be too late.

AFAICS, that code cannot be executed unless someone has violated the
update protocol (or the on-disk tuple status bits have gotten trashed
somehow). We are never supposed to update a tuple that has been
inserted or deleted by another, not-yet-committed transaction.
Therefore the child tuple should have been inserted by a
later-committing transaction. There is no way that VACUUM can see the
child tuple as dead and the parent tuple as not dead.

Or have I missed something?

regards, tom lane

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Hiroshi Inoue 2001-08-09 02:04:02 Re: CURRENT OF cursor without OIDs
Previous Message Hiroshi Inoue 2001-08-09 00:20:55 Re: CURRENT OF cursor without OIDs