PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
auto_explain.c File Reference
#include "postgres.h"
#include <limits.h>
#include "commands/explain.h"
#include "executor/instrument.h"
#include "utils/guc.h"
Include dependency graph for auto_explain.c:

Go to the source code of this file.

Macros

#define auto_explain_enabled()
 

Functions

void _PG_init (void)
 
void _PG_fini (void)
 
static void explain_ExecutorStart (QueryDesc *queryDesc, int eflags)
 
static void explain_ExecutorRun (QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
 
static void explain_ExecutorFinish (QueryDesc *queryDesc)
 
static void explain_ExecutorEnd (QueryDesc *queryDesc)
 

Variables

 PG_MODULE_MAGIC
 
static int auto_explain_log_min_duration = -1
 
static bool auto_explain_log_analyze = false
 
static bool auto_explain_log_verbose = false
 
static bool auto_explain_log_buffers = false
 
static bool auto_explain_log_triggers = false
 
static bool auto_explain_log_timing = true
 
static int auto_explain_log_format = EXPLAIN_FORMAT_TEXT
 
static bool auto_explain_log_nested_statements = false
 
static double auto_explain_sample_rate = 1
 
static const struct
config_enum_entry 
format_options []
 
static int nesting_level = 0
 
static ExecutorStart_hook_type prev_ExecutorStart = NULL
 
static ExecutorRun_hook_type prev_ExecutorRun = NULL
 
static ExecutorFinish_hook_type prev_ExecutorFinish = NULL
 
static ExecutorEnd_hook_type prev_ExecutorEnd = NULL
 
static bool current_query_sampled = true
 

Macro Definition Documentation

#define auto_explain_enabled ( )
Value:
static bool auto_explain_log_nested_statements
Definition: auto_explain.c:31
static int nesting_level
Definition: auto_explain.c:43
static int auto_explain_log_min_duration
Definition: auto_explain.c:24

Definition at line 54 of file auto_explain.c.

Referenced by explain_ExecutorEnd(), and explain_ExecutorStart().

Function Documentation

void _PG_fini ( void  )

Definition at line 196 of file auto_explain.c.

References ExecutorEnd_hook, ExecutorFinish_hook, ExecutorRun_hook, ExecutorStart_hook, prev_ExecutorEnd, prev_ExecutorFinish, prev_ExecutorRun, and prev_ExecutorStart.

197 {
198  /* Uninstall hooks. */
203 }
static ExecutorRun_hook_type prev_ExecutorRun
Definition: auto_explain.c:47
ExecutorStart_hook_type ExecutorStart_hook
Definition: execMain.c:69
static ExecutorStart_hook_type prev_ExecutorStart
Definition: auto_explain.c:46
ExecutorRun_hook_type ExecutorRun_hook
Definition: execMain.c:70
ExecutorEnd_hook_type ExecutorEnd_hook
Definition: execMain.c:72
static ExecutorFinish_hook_type prev_ExecutorFinish
Definition: auto_explain.c:48
static ExecutorEnd_hook_type prev_ExecutorEnd
Definition: auto_explain.c:49
ExecutorFinish_hook_type ExecutorFinish_hook
Definition: execMain.c:71
void _PG_init ( void  )

Definition at line 73 of file auto_explain.c.

References auto_explain_log_analyze, auto_explain_log_buffers, auto_explain_log_format, auto_explain_log_min_duration, auto_explain_log_nested_statements, auto_explain_log_timing, auto_explain_log_triggers, auto_explain_log_verbose, auto_explain_sample_rate, DefineCustomBoolVariable(), DefineCustomEnumVariable(), DefineCustomIntVariable(), DefineCustomRealVariable(), EmitWarningsOnPlaceholders(), ExecutorEnd_hook, ExecutorFinish_hook, ExecutorRun_hook, ExecutorStart_hook, explain_ExecutorEnd(), explain_ExecutorFinish(), explain_ExecutorRun(), explain_ExecutorStart(), EXPLAIN_FORMAT_TEXT, GUC_UNIT_MS, NULL, PGC_SUSET, prev_ExecutorEnd, prev_ExecutorFinish, prev_ExecutorRun, and prev_ExecutorStart.

74 {
75  /* Define custom GUC variables. */
76  DefineCustomIntVariable("auto_explain.log_min_duration",
77  "Sets the minimum execution time above which plans will be logged.",
78  "Zero prints all plans. -1 turns this feature off.",
80  -1,
81  -1, INT_MAX / 1000,
82  PGC_SUSET,
84  NULL,
85  NULL,
86  NULL);
87 
88  DefineCustomBoolVariable("auto_explain.log_analyze",
89  "Use EXPLAIN ANALYZE for plan logging.",
90  NULL,
92  false,
93  PGC_SUSET,
94  0,
95  NULL,
96  NULL,
97  NULL);
98 
99  DefineCustomBoolVariable("auto_explain.log_verbose",
100  "Use EXPLAIN VERBOSE for plan logging.",
101  NULL,
103  false,
104  PGC_SUSET,
105  0,
106  NULL,
107  NULL,
108  NULL);
109 
110  DefineCustomBoolVariable("auto_explain.log_buffers",
111  "Log buffers usage.",
112  NULL,
114  false,
115  PGC_SUSET,
116  0,
117  NULL,
118  NULL,
119  NULL);
120 
121  DefineCustomBoolVariable("auto_explain.log_triggers",
122  "Include trigger statistics in plans.",
123  "This has no effect unless log_analyze is also set.",
125  false,
126  PGC_SUSET,
127  0,
128  NULL,
129  NULL,
130  NULL);
131 
132  DefineCustomEnumVariable("auto_explain.log_format",
133  "EXPLAIN format to be used for plan logging.",
134  NULL,
138  PGC_SUSET,
139  0,
140  NULL,
141  NULL,
142  NULL);
143 
144  DefineCustomBoolVariable("auto_explain.log_nested_statements",
145  "Log nested statements.",
146  NULL,
148  false,
149  PGC_SUSET,
150  0,
151  NULL,
152  NULL,
153  NULL);
154 
155  DefineCustomBoolVariable("auto_explain.log_timing",
156  "Collect timing data, not just row counts.",
157  NULL,
159  true,
160  PGC_SUSET,
161  0,
162  NULL,
163  NULL,
164  NULL);
165 
166  DefineCustomRealVariable("auto_explain.sample_rate",
167  "Fraction of queries to process.",
168  NULL,
170  1.0,
171  0.0,
172  1.0,
173  PGC_SUSET,
174  0,
175  NULL,
176  NULL,
177  NULL);
178 
179  EmitWarningsOnPlaceholders("auto_explain");
180 
181  /* Install hooks. */
190 }
static double auto_explain_sample_rate
Definition: auto_explain.c:32
void DefineCustomIntVariable(const char *name, const char *short_desc, const char *long_desc, int *valueAddr, int bootValue, int minValue, int maxValue, GucContext context, int flags, GucIntCheckHook check_hook, GucIntAssignHook assign_hook, GucShowHook show_hook)
Definition: guc.c:7755
static ExecutorRun_hook_type prev_ExecutorRun
Definition: auto_explain.c:47
static bool auto_explain_log_verbose
Definition: auto_explain.c:26
static bool auto_explain_log_buffers
Definition: auto_explain.c:27
static bool auto_explain_log_nested_statements
Definition: auto_explain.c:31
static void explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition: auto_explain.c:209
static int auto_explain_log_format
Definition: auto_explain.c:30
void DefineCustomRealVariable(const char *name, const char *short_desc, const char *long_desc, double *valueAddr, double bootValue, double minValue, double maxValue, GucContext context, int flags, GucRealCheckHook check_hook, GucRealAssignHook assign_hook, GucShowHook show_hook)
Definition: guc.c:7785
void DefineCustomEnumVariable(const char *name, const char *short_desc, const char *long_desc, int *valueAddr, int bootValue, const struct config_enum_entry *options, GucContext context, int flags, GucEnumCheckHook check_hook, GucEnumAssignHook assign_hook, GucShowHook show_hook)
Definition: guc.c:7840
ExecutorStart_hook_type ExecutorStart_hook
Definition: execMain.c:69
static ExecutorStart_hook_type prev_ExecutorStart
Definition: auto_explain.c:46
static void explain_ExecutorFinish(QueryDesc *queryDesc)
Definition: auto_explain.c:284
static const struct config_enum_entry format_options[]
Definition: auto_explain.c:34
ExecutorRun_hook_type ExecutorRun_hook
Definition: execMain.c:70
ExecutorEnd_hook_type ExecutorEnd_hook
Definition: execMain.c:72
Definition: guc.h:75
void EmitWarningsOnPlaceholders(const char *className)
Definition: guc.c:7868
static int auto_explain_log_min_duration
Definition: auto_explain.c:24
static bool auto_explain_log_timing
Definition: auto_explain.c:29
static ExecutorFinish_hook_type prev_ExecutorFinish
Definition: auto_explain.c:48
static bool auto_explain_log_analyze
Definition: auto_explain.c:25
static void explain_ExecutorEnd(QueryDesc *queryDesc)
Definition: auto_explain.c:307
#define NULL
Definition: c.h:229
static ExecutorEnd_hook_type prev_ExecutorEnd
Definition: auto_explain.c:49
static void explain_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
Definition: auto_explain.c:260
ExecutorFinish_hook_type ExecutorFinish_hook
Definition: execMain.c:71
void DefineCustomBoolVariable(const char *name, const char *short_desc, const char *long_desc, bool *valueAddr, bool bootValue, GucContext context, int flags, GucBoolCheckHook check_hook, GucBoolAssignHook assign_hook, GucShowHook show_hook)
Definition: guc.c:7729
#define GUC_UNIT_MS
Definition: guc.h:224
static bool auto_explain_log_triggers
Definition: auto_explain.c:28
static void explain_ExecutorEnd ( QueryDesc queryDesc)
static

Definition at line 307 of file auto_explain.c.

References ExplainState::analyze, auto_explain_enabled, auto_explain_log_analyze, auto_explain_log_buffers, auto_explain_log_format, auto_explain_log_min_duration, auto_explain_log_timing, auto_explain_log_triggers, auto_explain_log_verbose, ExplainState::buffers, current_query_sampled, StringInfoData::data, ereport, errhidestmt(), errmsg(), EXPLAIN_FORMAT_JSON, ExplainBeginOutput(), ExplainEndOutput(), ExplainPrintPlan(), ExplainPrintTriggers(), ExplainQueryText(), ExplainState::format, InstrEndLoop(), QueryDesc::instrument_options, StringInfoData::len, LOG, NewExplainState(), pfree(), prev_ExecutorEnd, standard_ExecutorEnd(), ExplainState::str, ExplainState::summary, ExplainState::timing, Instrumentation::total, QueryDesc::totaltime, and ExplainState::verbose.

Referenced by _PG_init().

308 {
310  {
311  double msec;
312 
313  /*
314  * Make sure stats accumulation is done. (Note: it's okay if several
315  * levels of hook all do this.)
316  */
317  InstrEndLoop(queryDesc->totaltime);
318 
319  /* Log plan if duration is exceeded. */
320  msec = queryDesc->totaltime->total * 1000.0;
321  if (msec >= auto_explain_log_min_duration)
322  {
324 
328  es->timing = (es->analyze && auto_explain_log_timing);
329  es->summary = es->analyze;
331 
332  ExplainBeginOutput(es);
333  ExplainQueryText(es, queryDesc);
334  ExplainPrintPlan(es, queryDesc);
336  ExplainPrintTriggers(es, queryDesc);
337  ExplainEndOutput(es);
338 
339  /* Remove last line break */
340  if (es->str->len > 0 && es->str->data[es->str->len - 1] == '\n')
341  es->str->data[--es->str->len] = '\0';
342 
343  /* Fix JSON to output an object */
345  {
346  es->str->data[0] = '{';
347  es->str->data[es->str->len - 1] = '}';
348  }
349 
350  /*
351  * Note: we rely on the existing logging of context or
352  * debug_query_string to identify just which statement is being
353  * reported. This isn't ideal but trying to do it here would
354  * often result in duplication.
355  */
356  ereport(LOG,
357  (errmsg("duration: %.3f ms plan:\n%s",
358  msec, es->str->data),
359  errhidestmt(true)));
360 
361  pfree(es->str->data);
362  }
363  }
364 
365  if (prev_ExecutorEnd)
366  prev_ExecutorEnd(queryDesc);
367  else
368  standard_ExecutorEnd(queryDesc);
369 }
bool summary
Definition: explain.h:37
static bool current_query_sampled
Definition: auto_explain.c:52
ExplainState * NewExplainState(void)
Definition: explain.c:285
static bool auto_explain_log_verbose
Definition: auto_explain.c:26
static bool auto_explain_log_buffers
Definition: auto_explain.c:27
void standard_ExecutorEnd(QueryDesc *queryDesc)
Definition: execMain.c:469
int errhidestmt(bool hide_stmt)
Definition: elog.c:1068
static int auto_explain_log_format
Definition: auto_explain.c:30
#define LOG
Definition: elog.h:26
bool analyze
Definition: explain.h:33
int instrument_options
Definition: execdesc.h:44
void InstrEndLoop(Instrumentation *instr)
Definition: instrument.c:114
void ExplainEndOutput(ExplainState *es)
Definition: explain.c:3393
#define auto_explain_enabled()
Definition: auto_explain.c:54
void ExplainPrintTriggers(ExplainState *es, QueryDesc *queryDesc)
Definition: explain.c:654
void pfree(void *pointer)
Definition: mcxt.c:950
void ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc)
Definition: explain.c:617
void ExplainBeginOutput(ExplainState *es)
Definition: explain.c:3362
void ExplainQueryText(ExplainState *es, QueryDesc *queryDesc)
Definition: explain.c:688
#define ereport(elevel, rest)
Definition: elog.h:122
bool timing
Definition: explain.h:36
static int auto_explain_log_min_duration
Definition: auto_explain.c:24
static bool auto_explain_log_timing
Definition: auto_explain.c:29
static bool auto_explain_log_analyze
Definition: auto_explain.c:25
bool verbose
Definition: explain.h:32
struct Instrumentation * totaltime
Definition: execdesc.h:55
static ExecutorEnd_hook_type prev_ExecutorEnd
Definition: auto_explain.c:49
ExplainFormat format
Definition: explain.h:38
int errmsg(const char *fmt,...)
Definition: elog.c:797
bool buffers
Definition: explain.h:35
StringInfo str
Definition: explain.h:30
static bool auto_explain_log_triggers
Definition: auto_explain.c:28
static void explain_ExecutorFinish ( QueryDesc queryDesc)
static

Definition at line 284 of file auto_explain.c.

References nesting_level, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, prev_ExecutorFinish, and standard_ExecutorFinish().

Referenced by _PG_init().

285 {
286  nesting_level++;
287  PG_TRY();
288  {
290  prev_ExecutorFinish(queryDesc);
291  else
292  standard_ExecutorFinish(queryDesc);
293  nesting_level--;
294  }
295  PG_CATCH();
296  {
297  nesting_level--;
298  PG_RE_THROW();
299  }
300  PG_END_TRY();
301 }
void standard_ExecutorFinish(QueryDesc *queryDesc)
Definition: execMain.c:409
static int nesting_level
Definition: auto_explain.c:43
static ExecutorFinish_hook_type prev_ExecutorFinish
Definition: auto_explain.c:48
#define PG_CATCH()
Definition: elog.h:293
#define PG_RE_THROW()
Definition: elog.h:314
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300
static void explain_ExecutorRun ( QueryDesc queryDesc,
ScanDirection  direction,
uint64  count,
bool  execute_once 
)
static

Definition at line 260 of file auto_explain.c.

References nesting_level, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, prev_ExecutorRun, and standard_ExecutorRun().

Referenced by _PG_init().

262 {
263  nesting_level++;
264  PG_TRY();
265  {
266  if (prev_ExecutorRun)
267  prev_ExecutorRun(queryDesc, direction, count, execute_once);
268  else
269  standard_ExecutorRun(queryDesc, direction, count, execute_once);
270  nesting_level--;
271  }
272  PG_CATCH();
273  {
274  nesting_level--;
275  PG_RE_THROW();
276  }
277  PG_END_TRY();
278 }
void standard_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count, bool execute_once)
Definition: execMain.c:309
static ExecutorRun_hook_type prev_ExecutorRun
Definition: auto_explain.c:47
static int nesting_level
Definition: auto_explain.c:43
#define PG_CATCH()
Definition: elog.h:293
#define PG_RE_THROW()
Definition: elog.h:314
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300
static void explain_ExecutorStart ( QueryDesc queryDesc,
int  eflags 
)
static

Definition at line 209 of file auto_explain.c.

References auto_explain_enabled, auto_explain_log_analyze, auto_explain_log_buffers, auto_explain_log_min_duration, auto_explain_log_timing, auto_explain_sample_rate, current_query_sampled, EState::es_query_cxt, QueryDesc::estate, EXEC_FLAG_EXPLAIN_ONLY, InstrAlloc(), INSTRUMENT_ALL, INSTRUMENT_BUFFERS, QueryDesc::instrument_options, INSTRUMENT_ROWS, INSTRUMENT_TIMER, MAX_RANDOM_VALUE, MemoryContextSwitchTo(), nesting_level, NULL, prev_ExecutorStart, random(), standard_ExecutorStart(), and QueryDesc::totaltime.

Referenced by _PG_init().

210 {
211  /*
212  * For rate sampling, randomly choose top-level statement. Either all
213  * nested statements will be explained or none will.
214  */
218 
220  {
221  /* Enable per-node instrumentation iff log_analyze is required. */
222  if (auto_explain_log_analyze && (eflags & EXEC_FLAG_EXPLAIN_ONLY) == 0)
223  {
225  queryDesc->instrument_options |= INSTRUMENT_TIMER;
226  else
227  queryDesc->instrument_options |= INSTRUMENT_ROWS;
230  }
231  }
232 
233  if (prev_ExecutorStart)
234  prev_ExecutorStart(queryDesc, eflags);
235  else
236  standard_ExecutorStart(queryDesc, eflags);
237 
239  {
240  /*
241  * Set up to track total elapsed time in ExecutorRun. Make sure the
242  * space is allocated in the per-query context so it will go away at
243  * ExecutorEnd.
244  */
245  if (queryDesc->totaltime == NULL)
246  {
247  MemoryContext oldcxt;
248 
249  oldcxt = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt);
250  queryDesc->totaltime = InstrAlloc(1, INSTRUMENT_ALL);
251  MemoryContextSwitchTo(oldcxt);
252  }
253  }
254 }
static double auto_explain_sample_rate
Definition: auto_explain.c:32
static bool current_query_sampled
Definition: auto_explain.c:52
EState * estate
Definition: execdesc.h:48
long random(void)
Definition: random.c:22
static bool auto_explain_log_buffers
Definition: auto_explain.c:27
void standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
Definition: execMain.c:155
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Instrumentation * InstrAlloc(int n, int instrument_options)
Definition: instrument.c:30
int instrument_options
Definition: execdesc.h:44
static ExecutorStart_hook_type prev_ExecutorStart
Definition: auto_explain.c:46
#define auto_explain_enabled()
Definition: auto_explain.c:54
MemoryContext es_query_cxt
Definition: execnodes.h:468
static int nesting_level
Definition: auto_explain.c:43
#define MAX_RANDOM_VALUE
static int auto_explain_log_min_duration
Definition: auto_explain.c:24
static bool auto_explain_log_timing
Definition: auto_explain.c:29
static bool auto_explain_log_analyze
Definition: auto_explain.c:25
struct Instrumentation * totaltime
Definition: execdesc.h:55
#define NULL
Definition: c.h:229
#define EXEC_FLAG_EXPLAIN_ONLY
Definition: executor.h:58

Variable Documentation

bool auto_explain_log_analyze = false
static

Definition at line 25 of file auto_explain.c.

Referenced by _PG_init(), explain_ExecutorEnd(), and explain_ExecutorStart().

bool auto_explain_log_buffers = false
static

Definition at line 27 of file auto_explain.c.

Referenced by _PG_init(), explain_ExecutorEnd(), and explain_ExecutorStart().

int auto_explain_log_format = EXPLAIN_FORMAT_TEXT
static

Definition at line 30 of file auto_explain.c.

Referenced by _PG_init(), and explain_ExecutorEnd().

int auto_explain_log_min_duration = -1
static

Definition at line 24 of file auto_explain.c.

Referenced by _PG_init(), explain_ExecutorEnd(), and explain_ExecutorStart().

bool auto_explain_log_nested_statements = false
static

Definition at line 31 of file auto_explain.c.

Referenced by _PG_init().

bool auto_explain_log_timing = true
static

Definition at line 29 of file auto_explain.c.

Referenced by _PG_init(), explain_ExecutorEnd(), and explain_ExecutorStart().

bool auto_explain_log_triggers = false
static

Definition at line 28 of file auto_explain.c.

Referenced by _PG_init(), and explain_ExecutorEnd().

bool auto_explain_log_verbose = false
static

Definition at line 26 of file auto_explain.c.

Referenced by _PG_init(), and explain_ExecutorEnd().

double auto_explain_sample_rate = 1
static

Definition at line 32 of file auto_explain.c.

Referenced by _PG_init(), and explain_ExecutorStart().

bool current_query_sampled = true
static

Definition at line 52 of file auto_explain.c.

Referenced by explain_ExecutorEnd(), and explain_ExecutorStart().

const struct config_enum_entry format_options[]
static
Initial value:
= {
{"text", EXPLAIN_FORMAT_TEXT, false},
{"xml", EXPLAIN_FORMAT_XML, false},
{"json", EXPLAIN_FORMAT_JSON, false},
{"yaml", EXPLAIN_FORMAT_YAML, false},
{NULL, 0, false}
}
#define NULL
Definition: c.h:229

Definition at line 34 of file auto_explain.c.

int nesting_level = 0
static
PG_MODULE_MAGIC

Definition at line 21 of file auto_explain.c.

ExecutorEnd_hook_type prev_ExecutorEnd = NULL
static

Definition at line 49 of file auto_explain.c.

Referenced by _PG_fini(), _PG_init(), and explain_ExecutorEnd().

ExecutorFinish_hook_type prev_ExecutorFinish = NULL
static

Definition at line 48 of file auto_explain.c.

Referenced by _PG_fini(), _PG_init(), and explain_ExecutorFinish().

ExecutorRun_hook_type prev_ExecutorRun = NULL
static

Definition at line 47 of file auto_explain.c.

Referenced by _PG_fini(), _PG_init(), and explain_ExecutorRun().

ExecutorStart_hook_type prev_ExecutorStart = NULL
static

Definition at line 46 of file auto_explain.c.

Referenced by _PG_fini(), _PG_init(), and explain_ExecutorStart().