Re: Using ctid in delete statement

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Vick Khera <vivek(at)khera(dot)org>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Using ctid in delete statement
Date: 2017-02-15 16:18:06
Message-ID: 14603.1487175486@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Vick Khera <vivek(at)khera(dot)org> writes:
> On Wed, Feb 15, 2017 at 10:32 AM, pinker <pinker(at)onet(dot)eu> wrote:
>> DELETE FROM table_name WHERE ctid = any ( array ( select tn.ctid from
>> table_name tn JOIN items i on tn.itemid=i.itemid WHERE tn.clock < extract (
>> epoch FROM now() - i.history * interval '10 day')::int + 6 limit 100));
>>
>> Could I be sure that ctid will not change during the execution or will not
>> do any harm to other transactions?

> It will be safe for two reasons: 1) your statement is running in its own
> implicit transaction, and 2) the rows selected from the subquery are
> visible to your transaction and thus will not have been "cleaned up" for
> re-use by any other transaction.

I think it would be a lot safer with the inner SELECT changed to SELECT
FOR UPDATE. As you say, the ctid seen by a plain SELECT couldn't get
recycled for use by a new tuple while the transaction is still alive,
but as-is there's certainly a hazard that the row is updated by another
transaction. Then the ctid would point to an already-dead tuple so the
DELETE wouldn't do anything, which is unlikely to be the desired result.
With SELECT FOR UPDATE, you'd have a tuple lock preventing such race
conditions.

regards, tom lane

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Tom Lane 2017-02-15 16:20:05 Re: Foreign Data Wrapper for filesystem
Previous Message Hari Sankar A 2017-02-15 16:01:26 Problem with PostgreSQL string sorting Hello All,