| From: | PG Bug reporting form <noreply(at)postgresql(dot)org> |
|---|---|
| To: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Cc: | idrissaajalloh(at)gmail(dot)com |
| Subject: | BUG #19877: auto_explain omits a sampled cursor plan after sample_rate changes |
| Date: | 2026-11-11 12:33:09 |
| Message-ID: | 19877-d045e13baa7e9857@postgresql.org |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
The following bug has been logged on the website:
Bug reference: 19877
Logged by: Wren
Email address: idrissaajalloh(at)gmail(dot)com
PostgreSQL version: 18.6
Operating system: Linux/amd64
Description:
A cursor started while auto_explain.sample_rate is 1 does not emit its plan
if another top-level statement runs with sample_rate set to 0 before the
cursor ends. The cursor was selected and instrumented when it started, so
the later statement should not change whether its plan is emitted at
ExecutorEnd.
How to repeat:
Save the following as case.sql and run it with `psql -X -f case.sql`:
```sql
\set ON_ERROR_STOP on
LOAD 'auto_explain';
SET client_min_messages = notice;
SET auto_explain.log_level = notice;
SET auto_explain.log_min_duration = 0;
SET auto_explain.log_analyze = off;
-- Control: a cursor selected at sample_rate=1 is logged when it ends.
SET auto_explain.sample_rate = 1;
BEGIN;
DECLARE control_cursor CURSOR FOR
SELECT 'control_marker'::text;
FETCH ALL FROM control_cursor;
COMMIT;
-- This cursor is also selected and instrumented at start. A later top-level
-- statement changes auto_explain's backend-global sampling state.
SET auto_explain.sample_rate = 1;
BEGIN;
DECLARE victim_cursor CURSOR FOR
SELECT 'victim_marker'::text;
FETCH ALL FROM victim_cursor;
SET auto_explain.sample_rate = 0;
SELECT 'resampler_marker'::text;
COMMIT;
RESET auto_explain.sample_rate;
RESET auto_explain.log_analyze;
RESET auto_explain.log_min_duration;
RESET auto_explain.log_level;
RESET client_min_messages;
```
The recorded stdout confirms that both cursors ran and returned their rows:
```
BEGIN
DECLARE CURSOR
text
----------------
control_marker
(1 row)
COMMIT
SET
BEGIN
DECLARE CURSOR
text
---------------
victim_marker
(1 row)
SET
text
------------------
resampler_marker
(1 row)
COMMIT
```
However, stderr contains a plan only for the control cursor:
```
psql:case.sql:15: NOTICE: duration: 0.004 ms plan:
Query Text: DECLARE control_cursor CURSOR FOR
SELECT 'control_marker'::text;
Result (cost=0.00..0.01 rows=1 width=32)
```
There is no corresponding NOTICE for victim_cursor. Since both cursors
started with sample_rate=1 and log_min_duration=0, both should emit a plan.
The control cursor also confirms that NOTICE-level auto_explain output is
reaching the client.
This was reproduced on PostgreSQL 18.6 on Linux/amd64 using the packaged
auto_explain module. The evidence suggests that the sampling decision is
kept in backend-global state and consulted again at ExecutorEnd, allowing
the intervening statement to overwrite the decision made for the still-open
cursor. This occurs when auto_explain sampling is changed by a top-level
statement while an instrumented cursor remains open.
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Dean Rasheed | 2026-11-11 12:33:45 | Re: BUG #19802: MERGE into a partitioned table fails with "SubPlan found with no parent plan" |
| Previous Message | PG Bug reporting form | 2026-11-11 12:16:24 | BUG #19876: rhel-9.9-x86_64 yum repository for Postgres 16 is missing repodata |