Hi
čt 6. 6. 2019 v 10:48 odesílatel Gilles Darold <[email protected]> napsal:
> Le 06/06/2019 à 10:38, Pavel Stehule a écrit :
> > Hi
> >
> > I like the idea of sampling slow statements via
> > log_statement_sample_rate. But I miss some parameter that can ensure
> > so every query executed over this limit is logged.
> >
> > Can we introduce new option
> >
> > log_statement_sampling_limit
> >
> > The query with execution time over this limit is logged every time.
> >
> > What do you think about this?
> >
> > Regards
> >
> > Pavel
>
>
> +1, log_min_duration_statement is modulated by log_statement_sample_rate
> that mean that there is no more way to log all statements over a certain
> duration limit. log_statement_sampling_limit might probably always be
> upper than log_min_duration_statement.
>
Here is a patch
Regards
Pavel
>
> --
> Gilles Darold
> http://www.darold.net/
>
>
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 84341a30e5..690f54f731 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -5903,6 +5903,21 @@ local0.* /var/log/postgresql
</listitem>
</varlistentry>
+ <varlistentry id="guc-log-statement-sample-limit" xreflabel="log_statement_sample_limit">
+ <term><varname>log_statement_sample_limit</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>log_statement_sample_limit</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Only if query duration is less than this value, the log sampling is active.
+ When <varname>log_statement_sample_limit</varname> is <literal>-1</literal>
+ then log sampling is without limit.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="guc-log-transaction-sample-rate" xreflabel="log_transaction_sample_rate">
<term><varname>log_transaction_sample_rate</varname> (<type>real</type>)
<indexterm>
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 44a59e1d4f..2d8cc7d411 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -2193,7 +2193,9 @@ check_log_statement(List *stmt_list)
/*
* check_log_duration
* Determine whether current command's duration should be logged.
- * If log_statement_sample_rate < 1.0, log only a sample.
+ * If log_statement_sample_rate < 1.0, log only a sample and duration
+ * is less than log_statement_sample_limit. log_statement_sample_limit
+ * is used only if this value is different than -1.
* We also check if this statement in this transaction must be logged
* (regardless of its duration).
*
@@ -2217,6 +2219,7 @@ check_log_duration(char *msec_str, bool was_logged)
int usecs;
int msecs;
bool exceeded;
+ bool every_time;
bool in_sample;
TimestampDifference(GetCurrentStatementStartTimestamp(),
@@ -2234,6 +2237,15 @@ check_log_duration(char *msec_str, bool was_logged)
(secs > log_min_duration_statement / 1000 ||
secs * 1000 + msecs >= log_min_duration_statement)));
+ /*
+ * When log_statement_sample_limit is exceeded, then query is
+ * logged every time.
+ */
+ every_time = (log_statement_sample_limit == 0 ||
+ (log_statement_sample_limit > 0 &&
+ (secs > log_statement_sample_limit / 1000 ||
+ secs * 1000 + msecs >= log_statement_sample_limit)));
+
/*
* Do not log if log_statement_sample_rate = 0. Log a sample if
* log_statement_sample_rate <= 1 and avoid unnecessary random() call
@@ -2245,7 +2257,7 @@ check_log_duration(char *msec_str, bool was_logged)
(log_statement_sample_rate == 1 ||
random() <= log_statement_sample_rate * MAX_RANDOM_VALUE);
- if ((exceeded && in_sample) || log_duration || xact_is_sampled)
+ if ((exceeded && (in_sample || every_time)) || log_duration || xact_is_sampled)
{
snprintf(msec_str, 32, "%ld.%03d",
secs * 1000 + msecs, usecs % 1000);
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 1208eb9a68..b0c7d9df0e 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -510,6 +510,7 @@ int log_min_error_statement = ERROR;
int log_min_messages = WARNING;
int client_min_messages = NOTICE;
int log_min_duration_statement = -1;
+int log_statement_sample_limit = -1;
int log_temp_files = -1;
double log_statement_sample_rate = 1.0;
double log_xact_sample_rate = 0;
@@ -2715,6 +2716,19 @@ static struct config_int ConfigureNamesInt[] =
NULL, NULL, NULL
},
+ {
+ {"log_statement_sample_limit", PGC_SUSET, LOGGING_WHEN,
+ gettext_noop("Sets the maximum execution time for sampling "
+ "logged statements."),
+ gettext_noop("Zero effective disables sampling. "
+ "-1 use sampling every time (without limit)."),
+ GUC_UNIT_MS
+ },
+ &log_statement_sample_limit,
+ -1, -1, INT_MAX,
+ NULL, NULL, NULL
+ },
+
{
{"log_autovacuum_min_duration", PGC_SIGHUP, LOGGING_WHAT,
gettext_noop("Sets the minimum execution time above which "
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index e709177c37..8f0c2c59d4 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -252,6 +252,7 @@ extern int log_min_error_statement;
extern PGDLLIMPORT int log_min_messages;
extern PGDLLIMPORT int client_min_messages;
extern int log_min_duration_statement;
+extern int log_statement_sample_limit;
extern int log_temp_files;
extern double log_statement_sample_rate;
extern double log_xact_sample_rate;