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
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, |