Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit57e85fa

Browse files
committed
Fix contrib/auto_explain to not cause problems in parallel workers.
A parallel worker process should not be making any decisions of itsown about whether to auto-explain. If the parent session processpassed down flags asking for instrumentation data, do that, otherwisenot. Trying to enable instrumentation anyway leads to bugs like the"could not find key N in shm TOC" failure reported in bug #15821from Christian Hofstaedtler.We can implement this cheaply by piggybacking on the existing logicfor not doing anything when we've chosen not to sample a statement.While at it, clean up some tin-eared coding related to the samplingfeature, including an off-by-one error that meant that asking for 1.0sampling rate didn't actually result in sampling every statement.Although the specific case reported here only manifested in >= v11,I believe that related misbehaviors can be demonstrated in any versionthat has parallel query; and the off-by-one error is certainly thereback to 9.6 where that feature was added. So back-patch to 9.6.Discussion:https://postgr.es/m/15821-5eb422e980594075@postgresql.org
1 parent601084e commit57e85fa

File tree

1 file changed

+28
-15
lines changed

1 file changed

+28
-15
lines changed

‎contrib/auto_explain/auto_explain.c

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include<limits.h>
1616

17+
#include"access/parallel.h"
1718
#include"commands/explain.h"
1819
#include"executor/instrument.h"
1920
#include"jit/jit.h"
@@ -43,19 +44,20 @@ static const struct config_enum_entry format_options[] = {
4344
/* Current nesting depth of ExecutorRun calls */
4445
staticintnesting_level=0;
4546

47+
/* Is the current top-level query to be sampled? */
48+
staticboolcurrent_query_sampled= false;
49+
50+
#defineauto_explain_enabled() \
51+
(auto_explain_log_min_duration >= 0 && \
52+
(nesting_level == 0 || auto_explain_log_nested_statements) && \
53+
current_query_sampled)
54+
4655
/* Saved hook values in case of unload */
4756
staticExecutorStart_hook_typeprev_ExecutorStart=NULL;
4857
staticExecutorRun_hook_typeprev_ExecutorRun=NULL;
4958
staticExecutorFinish_hook_typeprev_ExecutorFinish=NULL;
5059
staticExecutorEnd_hook_typeprev_ExecutorEnd=NULL;
5160

52-
/* Is the current query sampled, per backend */
53-
staticboolcurrent_query_sampled= true;
54-
55-
#defineauto_explain_enabled() \
56-
(auto_explain_log_min_duration >= 0 && \
57-
(nesting_level == 0 || auto_explain_log_nested_statements))
58-
5961
void_PG_init(void);
6062
void_PG_fini(void);
6163

@@ -210,14 +212,25 @@ static void
210212
explain_ExecutorStart(QueryDesc*queryDesc,inteflags)
211213
{
212214
/*
213-
* For rate sampling, randomly choose top-level statement. Either all
214-
* nested statements will be explained or none will.
215+
* At the beginning of each top-level statement, decide whether we'll
216+
* sample this statement. If nested-statement explaining is enabled,
217+
* either all nested statements will be explained or none will.
218+
*
219+
* When in a parallel worker, we should do nothing, which we can implement
220+
* cheaply by pretending we decided not to sample the current statement.
221+
* If EXPLAIN is active in the parent session, data will be collected and
222+
* reported back to the parent, and it's no business of ours to interfere.
215223
*/
216-
if (auto_explain_log_min_duration >=0&&nesting_level==0)
217-
current_query_sampled= (random()<auto_explain_sample_rate*
218-
MAX_RANDOM_VALUE);
224+
if (nesting_level==0)
225+
{
226+
if (auto_explain_log_min_duration >=0&& !IsParallelWorker())
227+
current_query_sampled= (random()<auto_explain_sample_rate*
228+
((double)MAX_RANDOM_VALUE+1));
229+
else
230+
current_query_sampled= false;
231+
}
219232

220-
if (auto_explain_enabled()&&current_query_sampled)
233+
if (auto_explain_enabled())
221234
{
222235
/* Enable per-node instrumentation iff log_analyze is required. */
223236
if (auto_explain_log_analyze&& (eflags&EXEC_FLAG_EXPLAIN_ONLY)==0)
@@ -236,7 +249,7 @@ explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
236249
else
237250
standard_ExecutorStart(queryDesc,eflags);
238251

239-
if (auto_explain_enabled()&&current_query_sampled)
252+
if (auto_explain_enabled())
240253
{
241254
/*
242255
* Set up to track total elapsed time in ExecutorRun. Make sure the
@@ -307,7 +320,7 @@ explain_ExecutorFinish(QueryDesc *queryDesc)
307320
staticvoid
308321
explain_ExecutorEnd(QueryDesc*queryDesc)
309322
{
310-
if (queryDesc->totaltime&&auto_explain_enabled()&&current_query_sampled)
323+
if (queryDesc->totaltime&&auto_explain_enabled())
311324
{
312325
doublemsec;
313326

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp