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 1wZ3Og-000jfu-1v for pgsql-bugs@arkaria.postgresql.org; Mon, 15 Jun 2026 09:14:22 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wZ3Of-00B9di-19 for pgsql-bugs@arkaria.postgresql.org; Mon, 15 Jun 2026 09:14:21 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wZ3Oe-00B9da-3C for pgsql-bugs@lists.postgresql.org; Mon, 15 Jun 2026 09:14:21 +0000 Received: from mail-yw1-x1132.google.com ([2607:f8b0:4864:20::1132]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wZ3Od-00000000SBP-1QNx for pgsql-bugs@lists.postgresql.org; Mon, 15 Jun 2026 09:14:20 +0000 Received: by mail-yw1-x1132.google.com with SMTP id 00721157ae682-7e2fd65f968so29549747b3.3 for ; Mon, 15 Jun 2026 02:14:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1781514858; cv=none; d=google.com; s=arc-20240605; b=YNsy8DaE/Kr7HV1sD/m/W9D/oWCg8ImEnEFWfHbxJLIWYVoCCO8Cie3tNk/a8D9tU2 ehHNVhbmnvUudOch1FNWRcL8TAaV9I5TjD6Yeh8QlBSieNMjvgGkjuygNmnLAQSaftza P17wltOPJBjf+alxi991yDa/HgC31naEDiek9stuHzOWxN6sQ7qdUGoia7c0uTAcdanZ bw6AdmJkZGf293hYo5D9awTPqaBL7oYAczNyOvo9WqCgNaEh32ELXvUTyqLzkiaHTmaV gzyit4x9sjOycdPHPPoMI63C8VKZ7hxVJ5ORJSheSguXJ9EXyHv0ocgKwuXfgkmrQiLj hXcw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=/7tLW4Q3tGG3eUp8fssS6lf0bkoJFnnQr2bd5oP3ZJU=; fh=Pa0nYJqUm+Ji+SKg4VPZqX5RuaVbMu6PqcC1HedGGyM=; b=YxTE6OVo98nijViJ/rQ3Qf04FxdQKg3V/FUBXH97LVcRWBHwODJ9Sn9bBBBQPw0kKo FXKx0T7WBtFpxeU9w+V4h1ro6GPG8uJD0dVwPPnqw7xYxUdLH/ClmhyXREIxo4qyBFih ZcLZwAo914KzjI1cBOXAm9FbpxDRFwsWoisqUGqs9Wvt1qNbbzaFarZRTCHu4tsBWb9O x3Y7GvlV5rDdI9Khrfrps3LeQOY24XRre8b4OuT/MyseTnL6xBeD9bIjLmDtfrAof0Ky BjX5+5cJKkEYWUwuot+wDmSrY4eEl/GkHTHRk+LXf/hTJO+bfNLwlXLZ9YRfSxP6QDdr VRuA==; 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=1781514858; x=1782119658; darn=lists.postgresql.org; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=/7tLW4Q3tGG3eUp8fssS6lf0bkoJFnnQr2bd5oP3ZJU=; b=DaS4u/En2TrpUhl7Hqdj4mq5jFgwf3TDhSAhohuBm2DtkHOWhROpCUPw1hR6uSdEBo ccYBmVK9Pub0xlJ9p2RhHiM5RjGCd8BpvqFkXVNoVq9rl0T1NZRTDAk/pO76rJIqqXrx 6tHXDKB1HC5iJ2V/aLml7PlDkGWdvQr+TZdslvmabnyZl7pwTD2G0QaxpU/bGLywgF0h lWoBRaeUnS2LQ+5ElPlokX+dfub8uGMgVgxVnefGFN/wjPBBLw1aIh0VS+CIyCjpaUjh sLGW53d22lJt0zkliY/4RWPAm0/Ccc3FvNHeMV0gD8rB6ftwGY6ROTeaSZPYM/VIX1+I 3s4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781514858; x=1782119658; h=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=/7tLW4Q3tGG3eUp8fssS6lf0bkoJFnnQr2bd5oP3ZJU=; b=Akm27v7NZ+tGYTvxEqcKYLwHXYLVQF2rH4YkvE+DmjsMd3oiMPiy7YUy9StTTnXGo3 bzjui1NKciluhkQy39EhQZ9AjqwN6XXcqcnp0huTaNusIqLi8wOe8dfhxuh/fYQCv46e pwbnNZoo83CiBrOmfjubGG3elYcBknJaxit07KTmOL2u5owBiSPrqQjUhYd//4whk8PD blKQVLqZqV7vlsNu09h3XKlDP1dS2dmuZSwu0Thm4IUDnrd77uP3OrDQxc0c37FBF2SD L8eo9V4hWgvXioWQjpqZPvvl1CWVNuPhWyDs6l266a76wNm2kFkA6+yNjaFI25hz4d6m SQlA== X-Forwarded-Encrypted: i=1; AFNElJ+w46C20BakNwd61/LndUnjkS+r6xLxc8/b53EJz1nWkZf3zAzcyZpwdsJvlhuJzwVaCEsC1l581mGf@lists.postgresql.org X-Gm-Message-State: AOJu0YydZv6DfGB5O3+P4oL1mZvdCPLvo5XxAa1zw7FrvejpxdgvQ8LN m9vF/Pk2OTbh5wcpRgtzwHNuH1By1ZkhL1LMHQ227Rrk2HMKh+EeDzsQN337QmvyQw3FzB+RzVG 9gAvquu+hjTmQ2l31gGGqlGczbIByFAM= X-Gm-Gg: Acq92OGAHBHOn3FltltqzBTloNlKebgkyVoQYQhqO5Y8JgCDI+8b+d73kruYYRB9cVk XrPeSArnniiN63Pp/wn7pxQ7Md8t7aqjhS9pVObLE/cP6cW8+fQTFyNL2Vtr7px0SbVmN4Yn6u7 ZqWwMH7jGDfsJPgKG4pYJqyerTpyJMW0GEsxTzFBTDOHcXEVp8YFt/0/2+6BHOwrcN4+QFhJWz8 D1ShNOwhHKKqBHHHhi95rtTKqjCws5USIVxlVYR26Cst/5F07hYRIgw9LceVBTdlOl4oqlAeW8d 3Zsh+A== X-Received: by 2002:a05:690c:6381:b0:7db:ccda:a40d with SMTP id 00721157ae682-7f7b594afa7mr128105657b3.5.1781514858087; Mon, 15 Jun 2026 02:14:18 -0700 (PDT) MIME-Version: 1.0 References: <19520-73873648d44793cf@postgresql.org> In-Reply-To: <19520-73873648d44793cf@postgresql.org> From: Ayush Tiwari Date: Mon, 15 Jun 2026 14:44:06 +0530 X-Gm-Features: AVVi8CdIsMQJHOdBwJZxheNndfuuW7IuzrvsTr8cIHINXMpjVSXwMGlL9-hA3Yg Message-ID: Subject: Re: BUG #19520: PANIC when concurrently manipulating stored procedures with pg_stat_statements and track_functions = To: zlh21343@163.com, pgsql-bugs@lists.postgresql.org, Andres Freund , Michael Paquier Content-Type: multipart/alternative; boundary="000000000000474998065447409b" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000474998065447409b Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi, On Sun, 14 Jun 2026 at 22:37, PG Bug reporting form wrote: > The following bug has been logged on the website: > > Bug reference: 19520 > Logged by: zhanglihui > Email address: zlh21343@163.com > PostgreSQL version: 19beta1 > Operating system: Ubuntu 25.04 > Description: > > =3D=3D=3D Configuration =3D=3D=3D > Enabled extensions: pg_stat_statements > postgresql.conf: > shared_preload_libraries =3D 'pg_stat_statements' > track_functions =3D 'all' > > =3D=3D=3D Problem Description =3D=3D=3D > PostgreSQL server throws PANIC under high concurrent create, CALL and DRO= P > of stored procedures. > This issue **only reproduces when pg_stat_statements is enabled and > track_functions =3D all**. > It cannot be triggered if pg_stat_statements is disabled or track_functio= ns > is set to none/pl. > > =3D=3D=3D Run Steps =3D=3D=3D > javac -cp postgresql-42.7.5.jar -d out src/ConcurrentSqlTest.java > src/ProcCrashReprodure.java > # Terminal 1 =E2=80=94 Mixed DDL/DML load test (40 threads, 10000 iterati= ons each) > java -cp out:postgresql-42.7.5.jar ConcurrentSqlTest > > # Terminal 2 =E2=80=94 Pure CALL load test (20 threads, infinite loop) > java -cp out:postgresql-42.7.5.jar ProcCrashReprodure > # Note: If no PANIC log or core dump is generated after the execution of > Terminal 1, please re-run the command repeatedly until the issue occurs. > > PANIC log=EF=BC=9A > postgresql-2026-06-14_235441.log:2026-06-14 23:54:41.949 CST [691761] > PANIC: > XX000: cannot abort transaction 4166281, it was already committed > postgresql-2026-06-14_235931.log:2026-06-14 23:59:31.556 CST [696980] > PANIC: > XX000: cannot abort transaction 4641943, it was already committed > > (gdb) bt > #0 __pthread_kill_implementation (threadid=3D, signo=3D6, > no_tid=3D0) at ./nptl/pthread_kill.c:44 > #1 __pthread_kill_internal (threadid=3D, signo=3D6) at > ./nptl/pthread_kill.c:89 > #2 __GI___pthread_kill (threadid=3D, signo=3Dsigno@entry= =3D6) at > ./nptl/pthread_kill.c:100 > #3 0x000073e62ec4579e in __GI_raise (sig=3Dsig@entry=3D6) at > ../sysdeps/posix/raise.c:26 > #4 0x000073e62ec288cd in __GI_abort () at ./stdlib/abort.c:73 > #5 0x000056aeb574138c in errfinish (filename=3D0x56aeb57ff545 "xact.c", > lineno=3D1835, funcname=3D0x56aeb5800d00 <__func__.26> > "RecordTransactionAbort") > at elog.c:621 > #6 0x000056aeb4faae67 in RecordTransactionAbort (isSubXact=3Dfalse) at > xact.c:1835 > #7 0x000056aeb4fac19f in AbortTransaction () at xact.c:2982 > #8 0x000056aeb4facc22 in AbortCurrentTransactionInternal () at xact.c:35= 53 > #9 0x000056aeb4facb93 in AbortCurrentTransaction () at xact.c:3507 > #10 0x000056aeb5525552 in PostgresMain (dbname=3D0x56aedecf30d0 "postgres= ", > username=3D0x56aedecf30b0 "zlh_user") at postgres.c:4539 > #11 0x000056aeb551b59c in BackendMain (startup_data=3D0x7fffb9501000, > startup_data_len=3D24) at backend_startup.c:124 > #12 0x000056aeb5405686 in postmaster_child_launch (child_type=3DB_BACKEND= , > child_slot=3D24, startup_data=3D0x7fffb9501000, startup_data_len=3D24, > client_sock=3D0x7fffb9501060) at launch_backend.c:268 > #13 0x000056aeb540c11b in BackendStartup (client_sock=3D0x7fffb9501060) a= t > postmaster.c:3627 > #14 0x000056aeb540969f in ServerLoop () at postmaster.c:1728 > #15 0x000056aeb5408f7c in PostmasterMain (argc=3D1, argv=3D0x56aedeca1430= ) at > postmaster.c:1415 > #16 0x000056aeb528ce51 in main (argc=3D1, argv=3D0x56aedeca1430) at main.= c:231 > Thanks for the report! I'm unsure if this has already been reported or not. I looked into this the last day, I could reproduce it locally. Rather than the Java harness I used ~60 concurrent psql clients looping DROP / CREATE OR REPLACE / CALL of the same empty plpgsql procedure (track_functions=3Dall, pg_stat_statements loaded); here it PANICs within a few seconds. Just before the PANIC the failing backend logs: ERROR: trying to drop stats entry already dropped: kind=3Dfunction ... WARNING: AbortTransaction while in COMMIT state PANIC: cannot abort transaction xxx, it was already committed So it looks like a function's shared stats entry gets dropped twice: once out-of-band from pgstat_init_function_usage() when a concurrent CALL notices the function is gone, and once from the transactional drop at DROP time. When the latter loses the race it runs from AtEOXact_PgStat(), past the commit record, so the "already dropped" elog() in pgstat_drop_entry_internal() becomes the PANIC. The two droppers and the guard all seem to date back to PG 15 (5891c7a8ed8f). I guess the "drop exactly once" assumption behind that guard doesn't really hold for function stats, where two independent droppers are legitimate. I've added Andres and Michael on the thread, since they have worked on this in the past, for their input. Regards, Ayush --000000000000474998065447409b Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

On Sun, 14 Jun 2= 026 at 22:37, PG Bug reporting form <noreply@postgresql.org> wrote:
The following bug has been logged on the websi= te:

Bug reference:=C2=A0 =C2=A0 =C2=A0 19520
Logged by:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 zhanglihui
Email address:=C2=A0 =C2=A0 =C2=A0 zlh21343@163.com
PostgreSQL version: 19beta1
Operating system:=C2=A0 =C2=A0Ubuntu 25.04
Description:=C2=A0 =C2=A0 =C2=A0 =C2=A0

=3D=3D=3D Configuration =3D=3D=3D
Enabled extensions: pg_stat_statements
postgresql.conf:
shared_preload_libraries =3D 'pg_stat_statements'
track_functions =3D 'all'

=3D=3D=3D Problem Description =3D=3D=3D
PostgreSQL server throws PANIC under high concurrent create, CALL and DROP<= br> of stored procedures.
This issue **only reproduces when pg_stat_statements is enabled and
track_functions =3D all**.
It cannot be triggered if pg_stat_statements is disabled or track_functions=
is set to none/pl.

=3D=3D=3D Run Steps =3D=3D=3D
javac -cp postgresql-42.7.5.jar -d out=C2=A0 =C2=A0 =C2=A0src/ConcurrentSql= Test.java
src/ProcCrashReprodure.java
# Terminal 1 =E2=80=94 Mixed DDL/DML load test (40 threads, 10000 iteration= s each)
java -cp out:postgresql-42.7.5.jar ConcurrentSqlTest

# Terminal 2 =E2=80=94 Pure CALL load test (20 threads, infinite loop)
java -cp out:postgresql-42.7.5.jar ProcCrashReprodure
# Note: If no PANIC log or core dump is generated after the execution of Terminal 1, please re-run the command repeatedly until the issue occurs.
PANIC log=EF=BC=9A
postgresql-2026-06-14_235441.log:2026-06-14 23:54:41.949 CST [691761] PANIC= :
XX000: cannot abort transaction 4166281, it was already committed
postgresql-2026-06-14_235931.log:2026-06-14 23:59:31.556 CST [696980] PANIC= :
XX000: cannot abort transaction 4641943, it was already committed

(gdb) bt
#0=C2=A0 __pthread_kill_implementation (threadid=3D<optimized out>, s= igno=3D6,
no_tid=3D0) at ./nptl/pthread_kill.c:44
#1=C2=A0 __pthread_kill_internal (threadid=3D<optimized out>, signo= =3D6) at
./nptl/pthread_kill.c:89
#2=C2=A0 __GI___pthread_kill (threadid=3D<optimized out>, signo=3Dsig= no@entry=3D6) at
./nptl/pthread_kill.c:100
#3=C2=A0 0x000073e62ec4579e in __GI_raise (sig=3Dsig@entry=3D6) at
../sysdeps/posix/raise.c:26
#4=C2=A0 0x000073e62ec288cd in __GI_abort () at ./stdlib/abort.c:73
#5=C2=A0 0x000056aeb574138c in errfinish (filename=3D0x56aeb57ff545 "x= act.c",
lineno=3D1835, funcname=3D0x56aeb5800d00 <__func__.26> "RecordTr= ansactionAbort")
at elog.c:621
#6=C2=A0 0x000056aeb4faae67 in RecordTransactionAbort (isSubXact=3Dfalse) a= t
xact.c:1835
#7=C2=A0 0x000056aeb4fac19f in AbortTransaction () at xact.c:2982
#8=C2=A0 0x000056aeb4facc22 in AbortCurrentTransactionInternal () at xact.c= :3553
#9=C2=A0 0x000056aeb4facb93 in AbortCurrentTransaction () at xact.c:3507 #10 0x000056aeb5525552 in PostgresMain (dbname=3D0x56aedecf30d0 "postg= res",
username=3D0x56aedecf30b0 "zlh_user") at postgres.c:4539
#11 0x000056aeb551b59c in BackendMain (startup_data=3D0x7fffb9501000,
startup_data_len=3D24) at backend_startup.c:124
#12 0x000056aeb5405686 in postmaster_child_launch (child_type=3DB_BACKEND,<= br> child_slot=3D24, startup_data=3D0x7fffb9501000, startup_data_len=3D24,
client_sock=3D0x7fffb9501060) at launch_backend.c:268
#13 0x000056aeb540c11b in BackendStartup (client_sock=3D0x7fffb9501060) at<= br> postmaster.c:3627
#14 0x000056aeb540969f in ServerLoop () at postmaster.c:1728
#15 0x000056aeb5408f7c in PostmasterMain (argc=3D1, argv=3D0x56aedeca1430) = at
postmaster.c:1415
#16 0x000056aeb528ce51 in main (argc=3D1, argv=3D0x56aedeca1430) at main.c:= 231

Thanks for the report!=C2=A0 I'm unsure if= this has already been reported or
not.

I looked into this the la= st day, I could reproduce it locally.=C2=A0 Rather
than the Java harness= I used ~60 concurrent psql clients looping DROP /
CREATE OR REPLACE / C= ALL of the same empty plpgsql procedure
(track_functions=3Dall, pg_stat_= statements loaded); here it PANICs within
a few seconds.

Just bef= ore the PANIC the failing backend logs:

=C2=A0 ERROR: =C2=A0trying t= o drop stats entry already dropped: kind=3Dfunction ...
=C2=A0 WARNING: = =C2=A0AbortTransaction while in COMMIT state
=C2=A0 PANIC: =C2=A0cannot = abort transaction xxx, it was already committed

So it looks like a f= unction's shared stats entry gets dropped twice:
once out-of-band fr= om pgstat_init_function_usage() when a concurrent
CALL notices the funct= ion is gone, and once from the transactional drop
at DROP time.=C2=A0 Wh= en the latter loses the race it runs from
AtEOXact_PgStat(), past the co= mmit record, so the "already dropped"
elog() in pgstat_drop_en= try_internal() becomes the PANIC.

The two droppers and the guard all= seem to date back to PG 15
(5891c7a8ed8f).=C2=A0 I guess the "drop= exactly once" assumption behind that
guard doesn't really hold= for function stats, where two independent
droppers are legitimate.
<= br>I've added Andres and Michael on the thread, since they have worked = on
this in the past, for their input.

Regards,
Ayush
--000000000000474998065447409b--