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

Commitba38967

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 parent5b8c93c commitba38967

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"utils/guc.h"
@@ -42,19 +43,20 @@ static const struct config_enum_entry format_options[] = {
4243
/* Current nesting depth of ExecutorRun calls */
4344
staticintnesting_level=0;
4445

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

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

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

219-
if (auto_explain_enabled()&&current_query_sampled)
232+
if (auto_explain_enabled())
220233
{
221234
/* Enable per-node instrumentation iff log_analyze is required. */
222235
if (auto_explain_log_analyze&& (eflags&EXEC_FLAG_EXPLAIN_ONLY)==0)
@@ -235,7 +248,7 @@ explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
235248
else
236249
standard_ExecutorStart(queryDesc,eflags);
237250

238-
if (auto_explain_enabled()&&current_query_sampled)
251+
if (auto_explain_enabled())
239252
{
240253
/*
241254
* Set up to track total elapsed time in ExecutorRun. Make sure the
@@ -306,7 +319,7 @@ explain_ExecutorFinish(QueryDesc *queryDesc)
306319
staticvoid
307320
explain_ExecutorEnd(QueryDesc*queryDesc)
308321
{
309-
if (queryDesc->totaltime&&auto_explain_enabled()&&current_query_sampled)
322+
if (queryDesc->totaltime&&auto_explain_enabled())
310323
{
311324
doublemsec;
312325

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp