Received: from maia.hub.org (unknown [200.46.204.183]) by mail.postgresql.org (Postfix) with ESMTP id 187A9634F48 for ; Tue, 11 Aug 2009 16:01:09 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 39929-02 for ; Tue, 11 Aug 2009 19:01:06 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from sss.pgh.pa.us (sss.pgh.pa.us [66.207.139.130]) by mail.postgresql.org (Postfix) with ESMTP id 08AE6634DA0 for ; Tue, 11 Aug 2009 16:01:05 -0300 (ADT) Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.2/8.14.2) with ESMTP id n7BJ0qB3028100; Tue, 11 Aug 2009 15:00:52 -0400 (EDT) To: "Peter Headland" cc: pgsql-general@postgresql.org, "Pavel Stehule" Subject: Re: Race hazard deleting using CTID? In-reply-to: <71F491F5DA99604A80DE49424BF3D02B0C7293A0@exchange8.actuate.com> References: <71F491F5DA99604A80DE49424BF3D02B0C7290CA@exchange8.actuate.com> <20090811062503.86993bf6.darcy@druid.net> <162867790908110355g3b62cc56u1c74092dd01bbd8e@mail.gmail.com> <71F491F5DA99604A80DE49424BF3D02B0C7292EF@exchange8.actuate.com> <162867790908111022y48e65d31kcf5a037c1b41857f@mail.gmail.com> <71F491F5DA99604A80DE49424BF3D02B0C7293A0@exchange8.actuate.com> Comments: In-reply-to "Peter Headland" message dated "Tue, 11 Aug 2009 11:29:26 -0700" Date: Tue, 11 Aug 2009 15:00:52 -0400 Message-ID: <28099.1250017252@sss.pgh.pa.us> From: Tom Lane X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-2.599 tagged_above=-10 required=5 tests=BAYES_00=-2.599 X-Spam-Level: X-Archive-Number: 200908/375 X-Sequence-Number: 151576 "Peter Headland" writes: > My question is, does this code contain a race hazard, because the list from the SELECT might get changed by another session before the DELETE uses it? > delete from del where ctid = any(array(select ctid from del limit 10)) Well, the CTID of a row you can see can't be changed by another transaction while your transaction is still live. However, if someone else does modify/delete one of those rows concurrently, it will fail the outer WHERE check and thus silently not be deleted. Net effect is that you might delete fewer than 10 rows. Not sure if you'd consider that a race hazard or not. > If so, am I correct to think that adding FOR UPDATE to create the version below would eliminate the hazard? > delete from del where ctid = any(array(select ctid from del limit 10 for update)) If you'd bothered to try that before asking the list, you'd know the system won't take it --- FOR UPDATE is only supported at top level. You could probably do something equivalent using a plpgsql loop, or pulling the CTIDs back to the client side. regards, tom lane