RE: BUG #17686: SELECT pg_advisory_lock(...) with low lock_timeout sometimes times out but the lock is acquired

From: Mike Adelson <mike(dot)adelson314(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: "pgsql-bugs(at)lists(dot)postgresql(dot)org" <pgsql-bugs(at)lists(dot)postgresql(dot)org>
Subject: RE: BUG #17686: SELECT pg_advisory_lock(...) with low lock_timeout sometimes times out but the lock is acquired
Date: 2022-11-12 18:28:45
Message-ID: F8074C58-D7B7-4A24-9637-429C3B107580@hxcore.ol
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
.MsoChpDefault
{mso-style-type:export-only;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style></head><body lang=EN-US link=blue vlink="#954F72" style='word-wrap:break-word'><div class=WordSection1><p class=MsoNormal>Thanks for looking into this Tom,<o:p></o:p></p><p class=MsoNormal><o:p>&nbsp;</o:p></p><p class=MsoNormal>Glad to have the race condition confirmed. In my view the “real” fix here would be to offer an advisory locking function that accepts a timeout. FWIW, similar functionality on other RDBMS systems (SQL Server, MySQL, Oracle) offers this. That way, users wouldn’t have to rely in SET LOCAL lock_timeout to get this functionality. Thoughts? Is there a backlog item for this or has the idea been considered previously?<o:p></o:p></p><p class=MsoNormal><o:p>&nbsp;</o:p></p><p class=MsoNormal>-Mike</p><p class=MsoNormal><o:p>&nbsp;</o:p></p><div style='mso-element:para-border-div;border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in'><p class=MsoNormal style='border:none;padding:0in'><b>From: </b><a href="mailto:tgl(at)sss(dot)pgh(dot)pa(dot)us">Tom Lane</a><br><b>Sent: </b>Saturday, November 12, 2022 11:47 AM<br><b>To: </b><a href="mailto:mike(dot)adelson314(at)gmail(dot)com">mike(dot)adelson314(at)gmail(dot)com</a><br><b>Cc: </b><a href="mailto:pgsql-bugs(at)lists(dot)postgresql(dot)org">pgsql-bugs(at)lists(dot)postgresql(dot)org</a><br><b>Subject: </b>Re: BUG #17686: SELECT pg_advisory_lock(...) with low lock_timeout sometimes times out but the lock is acquired</p></div><p class=MsoNormal><o:p>&nbsp;</o:p></p><p class=MsoNormal>PG Bug reporting form &lt;noreply(at)postgresql(dot)org&gt; writes:</p><p class=MsoNormal>&gt; I'm finding that with relatively small values of lock_timeout and when the</p><p class=MsoNormal>&gt; system is under load (e.g. 8 connections acquiring concurrently), I will</p><p class=MsoNormal>&gt; encounter a case where the query exits with state 55P03 (lock_not_available)</p><p class=MsoNormal>&gt; and yet the lock was actually acquired (I can tell it has been acquired by</p><p class=MsoNormal>&gt; querying pg_locks and because other connections' calls to pg_advisory_lock</p><p class=MsoNormal>&gt; block).</p><p class=MsoNormal><o:p>&nbsp;</o:p></p><p class=MsoNormal>Yeah, there's a fairly basic race condition there, which is that the</p><p class=MsoNormal>lock might get granted to us immediately after the timeout fires.</p><p class=MsoNormal>In ordinary usage this isn't very problematic because the lock would</p><p class=MsoNormal>get released anyway during the transaction abort resulting from the</p><p class=MsoNormal>timeout error.  However, when you're asking for a session-level</p><p class=MsoNormal>advisory lock, that doesn't happen.</p><p class=MsoNormal><o:p>&nbsp;</o:p></p><p class=MsoNormal>I spent a little time studying whether there's a way to close the race,</p><p class=MsoNormal>but if it's possible at all it'd take major restructuring of what's</p><p class=MsoNormal>already quite complex and delicate code.  I can't get excited about</p><p class=MsoNormal>putting such effort into it, because related problems will exist</p><p class=MsoNormal>no matter what: if you get an error from the pg_advisory_lock command,</p><p class=MsoNormal>was the lock granted before that error occurred?  I don't think there's</p><p class=MsoNormal>any bulletproof way to deal with that except to check the lock status</p><p class=MsoNormal>afterwards (e.g., via pg_locks).  It's very much like the inherent issue</p><p class=MsoNormal>with errors late in COMMIT --- there's an atomic point where the commit</p><p class=MsoNormal>is logged, but the error report isn't going to be very clear about</p><p class=MsoNormal>whether we got past that, if indeed the error report gets to the client</p><p class=MsoNormal>at all.</p><p class=MsoNormal><o:p>&nbsp;</o:p></p><p class=MsoNormal>                                                regards, tom lane</p><p class=MsoNormal><o:p>&nbsp;</o:p></p></div></body></html>

Attachment Content-Type Size
unknown_filename text/html 4.7 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Tom Lane 2022-11-12 18:51:52 Re: BUG #17686: SELECT pg_advisory_lock(...) with low lock_timeout sometimes times out but the lock is acquired
Previous Message Tom Lane 2022-11-12 16:47:57 Re: BUG #17686: SELECT pg_advisory_lock(...) with low lock_timeout sometimes times out but the lock is acquired