Re: RFC: Logging plan of the running query

From: Andrei Lepikhov <lepihov(at)gmail(dot)com>
To: torikoshia <torikoshia(at)oss(dot)nttdata(dot)com>
Cc: Lukas Fittl <lukas(at)fittl(dot)com>, Robert Haas <robertmhaas(at)gmail(dot)com>, pgsql-hackers(at)lists(dot)postgresql(dot)org, Atsushi Torikoshi <torikoshia(dot)tech(at)gmail(dot)com>, samimseih(at)gmail(dot)com, destrex271(at)gmail(dot)com
Subject: Re: RFC: Logging plan of the running query
Date: 2026-08-24 07:29:27
Message-ID: 570fc999-51d3-4cf9-883a-bd590e203481@gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 21/07/2026 17:54, torikoshia wrote:
>
>> Hmmm, asynchronous feature that explains an arbitrary part of the query - for
>> example, some query inside an evaluated plpgsql function ... I think it is
>> expected by design.
>
> Even when execution moves to an outer or deeper QueryDesc in this way,
> the LogQueryPlanPending flag remains set, so the plan is logged. [1]
>
> The plan is not logged when there is no subsequent opportunity to call
> ExecProcNode(), including in any outer or deeper QueryDesc, as in the
> example using PREPARE that you showed in your previous message.
>
> My concern is whether, without the pending flag, it would be
> appropriate to log the plan of a different query subsequently
> executed by the same backend.
>
> For example, suppose a user calls pg_log_query_plan() expecting
> the plan of query A to be logged, but there is no opportunity
> to do so. If query B is then executed by the same backend one
> hour later, the plan of query B would be logged at that point.
> This does not seem like behavior that users would expect.
> What do you think?

Hmm, maybe I wasn't clear enough. Let me explain. This feature is asynchronous
by design. Calling it, you never know if the signal will be processed in the
exact query you saw a moment ago in pg_stat_activity. Moreover, it may be an
internal query inside of a massive query - it can be hard for a user to match
this call and the logged query. Just for example:

CREATE OR REPLACE FUNCTION heavy_nested_probe() RETURNS bigint
LANGUAGE plpgsql AS $$
DECLARE
result bigint;
BEGIN
SELECT count(*) INTO result
FROM generate_series(1, 150000000) g(i) WHERE i % 7 = 0; RETURN result;
END; $$; SQL

SELECT heavy_nested_probe();

Calling SELECT pg_log_query_plan() to the backend, executing such a query, you
will probably see 'SELECT heavy_nested_probe ', but the log file contains:

LOG: query and its plan for queryid 0 running on backend with PID 15805 are:
Query Text: SELECT count(*) FROM generate_series(1, 150000000) g(i)
WHERE i % 7 = 0
Aggregate (cost=2251875.00..2251875.01 rows=1 width=8)
-> Function Scan on generate_series g
(cost=0.00..2250000.00 rows=750000 width=0)
Filter: ((i % 7) = 0)

So, my point is Postgres shouldn't pretend that it provides any guarantees: this
function is a direct target for DBA's automation, and it might cause questions.
Just make it an asynchronous function and provide users with a way to know
whether it has already been logged and to match the call to the specific log record.

--
regards, Andrei Lepikhov,
pgEdge

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Nick Ivanov 2026-08-24 07:56:41 Re: Possible race condition in pg_basebackup
Previous Message Peter Smith 2026-08-24 07:24:57 Re: Support EXCEPT for TABLES IN SCHEMA publications