Allow setting sample ratio for auto_explain
authorMagnus Hagander <magnus@hagander.net>
Fri, 11 Mar 2016 14:08:34 +0000 (15:08 +0100)
committerMagnus Hagander <magnus@hagander.net>
Fri, 11 Mar 2016 14:08:34 +0000 (15:08 +0100)
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

contrib/auto_explain/auto_explain.c
doc/src/sgml/auto-explain.sgml

index 0950e18f6d9359f74a28852aef0a54b0d0cf6fb1..76d183156772bde9b8fd4609fc13cabfe21ae4ae 100644 (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;
 
index d527208271f003fd5c1744755c7754bb4d5c1791..6f1bde0d17ef2a00bbfc46573a3e5b47f87e82fb 100644 (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>