Allow setting sample ratio for auto_explain

New configuration parameter auto_explain.sample_ratio makes it
possible to log just a fraction of the queries meeting the configured
threshold, to reduce the amount of logging.

Author: Craig Ringer and Julien Rouhaud
Review: Petr Jelinek
This commit is contained in:
Magnus Hagander 2016-03-11 15:08:34 +01:00
parent 69ab7b9d6c
commit 92f03fe76f
2 changed files with 46 additions and 3 deletions

View File

@ -29,6 +29,7 @@ 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_ratio = 1;
static const struct config_enum_entry format_options[] = {
{"text", EXPLAIN_FORMAT_TEXT, false},
@ -47,6 +48,9 @@ static ExecutorRun_hook_type prev_ExecutorRun = NULL;
static ExecutorFinish_hook_type prev_ExecutorFinish = NULL;
static ExecutorEnd_hook_type prev_ExecutorEnd = NULL;
/* Is the current query sampled, per backend */
static bool current_query_sampled = true;
#define auto_explain_enabled() \
(auto_explain_log_min_duration >= 0 && \
(nesting_level == 0 || auto_explain_log_nested_statements))
@ -159,6 +163,19 @@ _PG_init(void)
NULL,
NULL);
DefineCustomRealVariable("auto_explain.sample_ratio",
"Fraction of queries to process.",
NULL,
&auto_explain_sample_ratio,
1.0,
0.0,
1.0,
PGC_SUSET,
0,
NULL,
NULL,
NULL);
EmitWarningsOnPlaceholders("auto_explain");
/* Install hooks. */
@ -191,7 +208,15 @@ _PG_fini(void)
static void
explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
{
if (auto_explain_enabled())
/*
* For ratio sampling, randomly choose top-level statement. Either
* all nested statements will be explained or none will.
*/
if (auto_explain_log_min_duration >= 0 && nesting_level == 0)
current_query_sampled = (random() < auto_explain_sample_ratio *
MAX_RANDOM_VALUE);
if (auto_explain_enabled() && current_query_sampled)
{
/* Enable per-node instrumentation iff log_analyze is required. */
if (auto_explain_log_analyze && (eflags & EXEC_FLAG_EXPLAIN_ONLY) == 0)
@ -210,7 +235,7 @@ explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
else
standard_ExecutorStart(queryDesc, eflags);
if (auto_explain_enabled())
if (auto_explain_enabled() && current_query_sampled)
{
/*
* Set up to track total elapsed time in ExecutorRun. Make sure the
@ -280,7 +305,7 @@ explain_ExecutorFinish(QueryDesc *queryDesc)
static void
explain_ExecutorEnd(QueryDesc *queryDesc)
{
if (queryDesc->totaltime && auto_explain_enabled())
if (queryDesc->totaltime && auto_explain_enabled() && current_query_sampled)
{
double msec;

View File

@ -203,6 +203,24 @@ LOAD 'auto_explain';
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<varname>auto_explain.sample_ratio</varname> (<type>real</type>)
<indexterm>
<primary><varname>auto_explain.sample_ratio</> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
<varname>auto_explain.sample_ratio</varname> (<type>floating point</type>)
causes auto_explain to only explain a fraction of the statements in each
session. The default is 1, meaning explain all the queries. In case
of nested statements, either all will be explained or none. Only
superusers can change this setting.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>