Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kUrtE-0006CU-HD for pgsql-bugs@arkaria.postgresql.org; Tue, 20 Oct 2020 13:41:24 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1kUrtD-0000Lq-EG for pgsql-bugs@arkaria.postgresql.org; Tue, 20 Oct 2020 13:41:23 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kUrtC-0000Lj-EV for pgsql-bugs@lists.postgresql.org; Tue, 20 Oct 2020 13:41:23 +0000 Received: from wout5-smtp.messagingengine.com ([64.147.123.21]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kUrt9-0001Jd-W3 for pgsql-bugs@lists.postgresql.org; Tue, 20 Oct 2020 13:41:21 +0000 Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.west.internal (Postfix) with ESMTP id E14085F2; Tue, 20 Oct 2020 09:41:17 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Tue, 20 Oct 2020 09:41:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=uLOolhE1iXdmq/4GilErXZfMH5J0E0IfwCd0ghaLQOI=; b=jSAxP6NR 9lDw6GPJlh+Lg+wmN6sOFA4Qk8O5EvQAirDwM6yFToGvQFAljFINgu5YQMhWsC0L eJ7MMx+TkPIS09lGkBbzMCqwOW5lrGHT8Ko+4nN2K9WyrFwjC7n7I9/QPvF7sDaB /wOYq9qQzPyaibaRL/tjdvMVt9UtjBp39uG4AhyMHZUfKrSamueXmX5/HiiSt+Jb AQLTpsmyImUtrDErlhHV8YAkxFx6PtNVfc2Km82FULkNqYaPsod90LG9kORQv1TL f0oAG1YMyp70lk07HS/a10mKZFAR2LM7tZLrKrkIRhPI6hBC/nGq7p6/Jh1PAauC i9oNbPZm8cdnQg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrjeefgdeiiecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpeffhffvuffkgggtugfgjggfsehtkeertddtreejnecuhfhrohhmpeetlhhvrghr ohcujfgvrhhrvghrrgcuoegrlhhvhhgvrhhrvgesrghlvhhhrdhnohdqihhprdhorhhgqe enucggtffrrghtthgvrhhnpedvleegkeeluedvvddtkefhgefgteehueekheettdehtdef tdevleekleegleeikeenucfkphepudeltddrleehrdduledrudegkeenucevlhhushhtvg hrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpegrlhhvhhgvrhhrvgesrghl vhhhrdhnohdqihhprdhorhhg X-ME-Proxy: Received: from perhan.alvh.no-ip.org (unknown [190.95.19.148]) by mail.messagingengine.com (Postfix) with ESMTPA id D9F0A3280064; Tue, 20 Oct 2020 09:41:16 -0400 (EDT) Received: by perhan.alvh.no-ip.org (Postfix, from userid 1000) id 54C9C2A5ECD; Tue, 20 Oct 2020 10:41:14 -0300 (-03) Date: Tue, 20 Oct 2020 10:41:14 -0300 From: Alvaro Herrera To: David Christensen Cc: Tom Lane , pgsql-bugs@lists.postgresql.org Subject: Re: BUG #16676: SELECT ... FETCH FIRST ROW WITH TIES FOR UPDATE SKIP LOCKED locks rows it doesn't return Message-ID: <20201020134114.GA11045@alvherre.pgsql> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <7EA65D44-7C3A-4FC2-8DE1-1F59BBB10B37@endpoint.com> User-Agent: Mutt/1.10.1 (2018-07-13) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On 2020-Oct-19, David Christensen wrote: > > On Oct 19, 2020, at 6:59 PM, David Christensen wrote: > > > >> On Oct 19, 2020, at 6:07 PM, Tom Lane wrote: > >> > >> David Christensen writes: > >>> Proposed fix: > >>> Reorder Limit/LockRows nodes to prevent locking extra tuples in FETCH FIRST WITH TIES > >> > >> Isn't that going to break more cases than it fixes? > > > > In the case of Limit, isn’t LockRows supposed to only lock the number of actual rows returned? > > > > What are the scenarios that this might break and do you have any ideas for alternate fixes? > > Will now that I think about it, if the LockRows node is responsible > for skipping locked rows, etc then my proposed solution is clearly > wrong. I tried your proposed patch yesterday and found that the second query returns no rows rather than two rows, which is not an improvement. > Maybe splitting LockRows into two nodes, one for locking and one for > emitting unlocked nodes then interleaving Limit in between? (Or only > doing something along these lines for this admittedly narrow use case.) I was having a similar idea, but the main reason I don't think it's a good fix is that we can't backpatch such a change to pg13. I was thinking if it was possible to modify Limit so that it would "peek" into its child node without "actually reading". But that's not possible in our executor implementation AFAIK -- you only have ExecProcNode as an interface, there's no way to affect what happens underneath. Maybe an approach is to forbid a FOR UPDATE clause in a query that has a LIMIT WITH TIES clause; so we'd force the user to write a subquery for LIMIT WITH TIES and then apply FOR UPDATE to an outer query. However, I'm surprised to find that we have *two* LockRows nodes when doing that: explain select * from (select * from queue order by batch_id fetch first 2 rows with ties) t for update skip locked; QUERY PLAN ──────────────────────────────────────────────────────────────────────────────────────── LockRows (cost=55.20..55.27 rows=2 width=40) -> Subquery Scan on t (cost=55.20..55.25 rows=2 width=40) -> Limit (cost=55.20..55.23 rows=2 width=14) -> LockRows (cost=55.20..83.45 rows=2260 width=14) -> Sort (cost=55.20..60.85 rows=2260 width=14) Sort Key: queue.batch_id -> Seq Scan on queue (cost=0.00..32.60 rows=2260 width=14) (7 filas) and of course, we still have the behavior where the third row is skipped.