Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wZlUs-001GcD-1E for pgsql-bugs@arkaria.postgresql.org; Wed, 17 Jun 2026 08:19:42 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wZlUp-005Bk0-1e for pgsql-bugs@arkaria.postgresql.org; Wed, 17 Jun 2026 08:19:39 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wZlUp-005Bjs-0W for pgsql-bugs@lists.postgresql.org; Wed, 17 Jun 2026 08:19:39 +0000 Received: from mail-yw1-x112a.google.com ([2607:f8b0:4864:20::112a]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wZlUm-00000000sY2-2yds for pgsql-bugs@lists.postgresql.org; Wed, 17 Jun 2026 08:19:38 +0000 Received: by mail-yw1-x112a.google.com with SMTP id 00721157ae682-7f5eb760240so69092947b3.0 for ; Wed, 17 Jun 2026 01:19:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1781684374; cv=none; d=google.com; s=arc-20240605; b=jfvmiuofo/EGW/EbLZkqeMObysenFlIBU7eki/ZH1pDpBq55F9e61PCZlGu/WLUKEj bpP27xdeyJabQyJgpUQnpSW9I1TfY3wpiRh1Lw9LWhq3vcQXrpVENg7H/9hsHVnLWQIT vV3RdEOjZ5hsr/0b0EZRSXW8wz+vG/Q4KhfyHx5bhYPCwkAO/NHciIyyIVzZmFxS6g2z LYsOwyqw5YpgD5t/t+XnZpHNJeWWic9RhLgW+NNUXM7twUMtAMgMxQKu+BIyRySL5ngK VZSYF9oXw2zBuT5ZrNBGlkSozhAYliRQKvb0OmMlCn6fvqz5F2wZ2H9YPnVV/XiM6xkg vISA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=qkddCSdIfKzpxAz2p32E7I6KrqagNUtt1AeUHQ+oHb8=; fh=yX0qd+VdYRXhMj9VJrK9ks0oRtSj/pT1TX1AiYHeolw=; b=O4B3vYd1BMX6ZXd6cB1kH+6C6/aKp09lMGDMOo0Eil6VBwZFzI2Yjw0lyJI+iJyQud /Ou4K64E1ioCW33ov+6wdMum83QSuG/CSJyVCK1IXoO0cxT0oiwQ8pUp/B23nG6iyG/X Zu1129hzozt7Xeti8l2nFa+SQnFYwKmBu3fpfIc8PCapsko+9HZgeLGEVZHJTKFcRutu G1qzTq6ByI+6SEUkjHszQ9+ijlvZFIJYMWH3M2EFw30G763gpngV9+07ciZOmeiMuAZ3 KXeOyCBHrUH55rm2yyh+FJwlHNgap8sR1Zyvg/DKBsS1hVqbYnIJVWdKyqdm8n4JlDEd xxoA==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781684374; x=1782289174; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=qkddCSdIfKzpxAz2p32E7I6KrqagNUtt1AeUHQ+oHb8=; b=orID/mAac+Fp0a/bx0KbUr7Qf4jBjEi24R+WoKsMuC4PB/gHs6xYurN+Mj9yerhbMC jcwAuXHy4FtvEzRNuZTJbRkMzWEFGyDL1vpqasjlupXP74x4JYI1pWZoAm1cn8lyOwsD xDMYnGdsQDSfTPQuLX4/XyJFaemv5U9bw5W+6kZUPn+WLm4HdQ06AKm2DphRWjtF41gY 8thKTS63gcrLlLXOzSc6+OwYycgzKnUEMrEj0CbCUzD/mY9mtSFqmw1Ecl8XCC+sP8wT 2LlZfQK2BhYLVXdNE+NeF1EE2GcoPddHttGj+9kRnhyjDkXFc7umxirZheaCRktDj8iQ xbDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781684374; x=1782289174; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=qkddCSdIfKzpxAz2p32E7I6KrqagNUtt1AeUHQ+oHb8=; b=o9rb8c1Y6dS5YKqOCI6lCuF0t6itRoyqO8NZxrT6oq2kYdwcg8sFbjffx2F2sdj0c/ yrZII33d7xwOyb1QAOm0JM2t+dMTFodkk09ADdtzpFNJV2B3F6DD2RGYhE1sOSX0qiEw UC4UsqOaZah0wO7gli7Kq3mjZj2996fhxAApB5jznREUNLHf9q72kAiP3mUcF0HSgTpj cHzz8pWkWiOmT9aicOyPIgsI0I4c8GkihPUdqBkrsenGg/YUw16Lp90C0SuvL/Ia9gnG BPgK39XhD8yrL0MYMlKkQ3VGn+7E6LlLZ282Z2d0RnQ3hyF7N08Sgz09Isy69FatfhRb HxUQ== X-Forwarded-Encrypted: i=1; AFNElJ/dazZ0a+QUXh82lhGWope6CMncjIoJx8khMdCcHTcdQRcaLm557rFfr5YgbeJ8tAt807WPowelGETR@lists.postgresql.org X-Gm-Message-State: AOJu0Yxd4voct/JAzknxoO8FmJfnh/A5jO7k/mq+WW/t8/qqXewGH+it 2i7bhnQVEVb0Uin5X+hZsgMUHAddK1am2LP/0XuH4lc43DP4vIymwsTJpSvB8gGho9sBLZ3kvGC 4kwZMJxaMZpxDzY5PPAYLwxKjcDJT65c= X-Gm-Gg: AfdE7clZXPAt7mJjquvFR7rgMnzVXRG1zBSjYoDKebVwstG6+LjLdU6cryFVnJD7sRM RdNTBfhuHPKYNceEGi7l2buV5JLuoz5s45k7Ecv/y8YQ043BAEtajDWoudigvkNTi3wlJRW6bRw ev/64AwqsOVeqlIW5i5GxyXDwegtbcjEvpAfCJgYDF8sYOYWm1nvxcVPY31Ka8ILifGYMTDfBem bk3U9rteEv2aB36NF59/jRvh0KtvJHmQFeqLt1EyIUDcWIoL+YS4eZwUVQuV1WD1LYwH5E= X-Received: by 2002:a05:690c:e298:10b0:7ff:8a4:e55a with SMTP id 00721157ae682-7ff08a4f131mr2755007b3.23.1781684374356; Wed, 17 Jun 2026 01:19:34 -0700 (PDT) MIME-Version: 1.0 References: <19520-73873648d44793cf@postgresql.org> In-Reply-To: From: Ayush Tiwari Date: Wed, 17 Jun 2026 13:49:23 +0530 X-Gm-Features: AVVi8CfMtFLJ40zAmWZ5F9vh0oEUpRlOywKkmozex6FSwmHcMdgp8g2bxzoGX0Q Message-ID: Subject: Re: BUG #19520: PANIC when concurrently manipulating stored procedures with pg_stat_statements and track_functions = To: Michael Paquier Cc: zlh21343@163.com, pgsql-bugs@lists.postgresql.org, Andres Freund , Sami Imseih , Kyotaro Horiguchi Content-Type: multipart/alternative; boundary="0000000000003c487906546eb823" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000003c487906546eb823 Content-Type: text/plain; charset="UTF-8" Hi, On Wed, 17 Jun 2026 at 09:45, Michael Paquier wrote: > On Tue, Jun 16, 2026 at 08:24:51AM +0900, Michael Paquier wrote: > > On Mon, Jun 15, 2026 at 02:44:06PM +0530, Ayush Tiwari wrote: > >> I've added Andres and Michael on the thread, since they have worked on > >> this in the past, for their input. > > > > Thanks for the poke. I have marked this thread as something to look > > at, but was not able to get back to it. Will investigate.. > > As far as I can see, pgss is not really a requirement. Your case is > taking advantage of the module introducing more slowness to enlarge > the reproduction window. Now saying that pgss being slow is a good > thing, it's bad, but it helps here. I've tried to reproduce in three > environments, only my mac is able to get something, because it's > slower I guess.. > Yeah, you are right, pgss is not a requirement, it just makes the delay broader. > Attached is a script able to reproduce the issue in bash, courtesy of > Claude because java and I sum up to a value very close to 0, see > test_bug19520.txt. The trick of the script is the same as your > scenario, with two concurrent workloads: > - One with DROP PROC/CREATE PROC/CALL. > - One with CALL > > I had much more success after adding two sleeps to enlarge the > conflict window, see also the sleep.patch attached, for reference. > > Finally attached is a patch, where I'd like to propose the > introduction of a path in pgstat_drop_entry() to make the routine able > to accept double drops. > I applied the patch on HEAD and ran my psql harness against it (~60 clients looping DROP / CREATE OR REPLACE / CALL, track_functions=all, pgss loaded). Unpatched it PANICs within seconds; with the patch it stayed up for a ~3 minute run, with the out-of-band drop path firing several thousand times. So it clearly closes the hole here. > The big comment within pgstat_init_function_usage() documents why it > does its stuff for track_functions, so I was wondering if we should > enforce the same double-drop-acceptance rule for all the callers > everybody, but I also see a point in the correctness, by allowing the > caller to complain if we try to do double drops but error on them, > pointing to a programming error. Note that > pgstat_drop_entry_internal() is not touched on purpose, to keep the > database-level scans as they are, with double-drops forbidden. > > This patch is very close to what Sami has posted on his PGSS thread, > v3-0002, using a missing_ok instead of a skip_dropped: > > https://www.postgresql.org/message-id/CAA5RZ0uoxiQ2_=xHGRnyc4WdM9aR0fzdMhBubnw97po==--yGQ@mail.gmail.com > I didn't suspect that we would need something like that for a > backpatch, but well. > > I'm adding Sami in CC in case he wishes to comment on this patch, and > Horiguchi-san as this area of the code concerns him. > > Thoughts or comments welcome. > A couple of things which I'm not clear about (these are not blockers just questions for my understanding): - With the check moved into the wrapper, pgstat_drop_entry_internal() still keeps its own "already dropped" elog(). Every path into _internal now seems to guarantee the entry isn't dropped, so _internal's copy looks unreachable after the patch ,and it's the one with the richer refcount/generation detail. Was the idea to leave it as a backstop, or would folding the handling into one place (or making _internal's an Assert) be cleaner? - In the missing_ok path the wrapper returns true, so the post-commit caller skips the not_freed_count++/GC request that a "real" not-freed drop would do. That seems harmless since the entry self-heals but was returning true there a deliberate choice over mirroring the not-freed/false path? I need to take a look again at this, maybe I missed something. Regards, Ayush --0000000000003c487906546eb823 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

On Wed, 17 Jun 2= 026 at 09:45, Michael Paquier <mi= chael@paquier.xyz> wrote:
On Tue, Jun 16, 2026 at 08:24:51AM +0900, Michael Paquier = wrote:
> On Mon, Jun 15, 2026 at 02:44:06PM +0530, Ayush Tiwari wrote:
>> I've added Andres and Michael on the thread, since they have w= orked on
>> this in the past, for their input.
>
> Thanks for the poke.=C2=A0 I have marked this thread as something to l= ook
> at, but was not able to get back to it.=C2=A0 Will investigate..

As far as I can see, pgss is not really a requirement.=C2=A0 Your case is taking advantage of the module introducing more slowness to enlarge
the reproduction window.=C2=A0 Now saying that pgss being slow is a good thing, it's bad, but it helps here.=C2=A0 I've tried to reproduce i= n three
environments, only my mac is able to get something, because it's
slower I guess..

Yeah, you are right, p= gss is not a requirement, it just
makes the delay broader.
<= div>=C2=A0
Attached is a script able to reproduce the issue in bash, courtesy of
Claude because java and I sum up to a value very close to 0, see
test_bug19520.txt.=C2=A0 The trick of the script is the same as your
scenario, with two concurrent workloads:
- One with DROP PROC/CREATE PROC/CALL.
- One with CALL

I had much more success after adding two sleeps to enlarge the
conflict window, see also the sleep.patch attached, for reference.

Finally attached is a patch, where I'd like to propose the
introduction of a path in pgstat_drop_entry() to make the routine able
to accept double drops.
=C2=A0
I applied the= patch on HEAD and ran my psql harness against it (~60
clients looping D= ROP / CREATE OR REPLACE / CALL, track_functions=3Dall,
pgss loaded).=C2= =A0 Unpatched it PANICs within seconds; with the patch it
stayed up for = a ~3 minute run, with the out-of-band drop path firing
several thousand = times.=C2=A0 So it clearly closes the hole here.
=C2=A0
The big comment within pgstat_init_function_usage() documents why it
does its stuff for track_functions, so I was wondering if we should
enforce the same double-drop-acceptance rule for all the callers
everybody, but I also see a point in the correctness, by allowing the
caller to complain if we try to do double drops but error on them,
pointing to a programming error.=C2=A0 Note that
pgstat_drop_entry_internal() is not touched on purpose, to keep the
database-level scans as they are, with double-drops forbidden.

This patch is very close to what Sami has posted on his PGSS thread,
v3-0002, using a missing_ok instead of a skip_dropped:
https://www.postgresql.org/message-id/CAA5RZ0uoxiQ2_=3DxHGRnyc4= WdM9aR0fzdMhBubnw97po=3D=3D--yGQ@mail.gmail.com
I didn't suspect that we would need something like that for a
backpatch, but well.

I'm adding Sami in CC in case he wishes to comment on this patch, and Horiguchi-san as this area of the code concerns him.

Thoughts or comments welcome.

A couple of th= ings which I'm not clear about (these are not blockers
just questions for my understanding)= :

- With the check moved into the wrapper, pgstat_drop_entry_interna= l()
=C2=A0 still keeps its own "already dropped" elog().=C2=A0= Every path into
=C2=A0 _internal now seems to guarantee the entry isn&#= 39;t dropped, so
=C2=A0 _internal's copy looks unreachable after th= e patch
=C2=A0 ,and it's the one with the richer refcount/generation= detail.=C2=A0 Was
=C2=A0 the idea to leave it as a backstop, or would f= olding the handling into
=C2=A0 one place (or making _internal's an = Assert) be cleaner?

- In the missing_ok path the wrapper returns tru= e, so the post-commit
=C2=A0 caller skips the not_freed_count++/GC reque= st that a "real" not-freed
=C2=A0 drop would do.=C2=A0 That se= ems harmless since the entry self-heals
=C2=A0 but was returning true t= here a deliberate choice over mirroring
=C2=A0 the not-freed/false path= ? I need to take a look again at this, maybe
=C2=A0 I missed something.<= br>
Regards,
Ayush
--0000000000003c487906546eb823--