On Mon, Jul 6, 2026 at 2:48 AM Ilmar Yunusov <[email protected]> wrote: > 1. Would it be better for a first version to aim at statement-level sampled > wait event reporting only, and leave plan-node attribution for a later > patch?
I don't know. > 2. If plan-node attribution is included, does keeping track of the active > PlanState only while EXPLAIN ANALYZE has this option enabled sound like a > reasonable direction, provided it stays outside > pgstat_report_wait_start/end()? I think yes, that sounds reasonable. > 3. For sampling, should I focus on an external sampler rather than backend > self-sampling with a timer, to avoid distorting the measured backend? I don't think the answer to this question is entirely clear. If we self-sample, then the main challenge seems to be keeping the work done in the interrupt handler to some acceptable small amount of stuff. If we had only a small, fixed number of wait events, then you could perhaps imagine a global variable that pointed to the set of counters that we should update when the self-sampler trips, but the number of distinct wait events is basically unbounded, we might need an expandable array or some such thing to hold all the counters that we want to maintain, and we definitely cannot re-palloc to enlarge that allocation in an interrupt handler. If, on the other hand, we use an external sampler, then that concern largely goes away, because the code that's doing the sampling no longer needs to run inside of an interrupt routine. But now we have another problem: how does the external sampler know which plan node, or even which query, is running at any given moment in time? With a self-sampler, you can use a global variable that is updated every time we enter or exit a plan node, or every time we enter or exit a query. But with this design, the information has to be published someplace where another process can see it. You could publish a PlannedStmt * or PlanState * pointer in shared memory, I suppose, but another process won't be able to make any sense of that value, since the object doesn't exist in its address space. There's probably more than one thing you could do about that. One idea would be to let the external sampler work in terms of pointers it can't interpret, and then have it somehow ship the resulting data back to the process that can interpret those pointers. Another idea could be to ship something else -- the plan_node_id instead of the PlanState pointer? The query string instead of the PlannedStmt pointer? It's not really clear to me. It seems like no matter what you do you need a way to get the data back to the process that asked for profiling originally, and I'm not clear what the mechanism should be. We could spin up a DSA, get the profiler to attach it and write data there, and then read the DSA after the profiler has detached, maybe? Or the profiler could write a temp file and we could read it? There's probably other options, too. The currently-existing wait event sampling solutions that I know about are not designed to be used with EXPLAIN but on a system-wide basis, so they work per-query, not per-node, and the idea is to sample everything and correlate samples to query text or a query ID. To me, that seems like a more natural fit than this idea, but that's not to say this idea can't be made to work. I just don't know exactly what kind of design we would want. -- Robert Haas EDB: http://www.enterprisedb.com
