Allow compute_query_id to be set to 'auto' and make it default
Allowing only on/off meant that all either all existing configuration guides would become obsolete if we disabled it by default, or that we would have to accept a performance loss in the default config if we enabled it by default. By allowing 'auto' as a middle ground, the performance cost is only paid by those who enable pg_stat_statements and similar modules. I only edited the release notes to comment-out a paragraph that is now factually wrong; further edits are probably needed to describe the related change in more detail. Author: Julien Rouhaud <rjuju123@gmail.com> Reviewed-by: Justin Pryzby <pryzby@telsasoft.com> Discussion: https://postgr.es/m/20210513002623.eugftm4nk2lvvks3@nol
This commit is contained in:
parent
30d8bad494
commit
cafde58b33
@ -369,6 +369,12 @@ _PG_init(void)
|
|||||||
if (!process_shared_preload_libraries_in_progress)
|
if (!process_shared_preload_libraries_in_progress)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Inform the postmaster that we want to enable query_id calculation if
|
||||||
|
* compute_query_id is set to auto.
|
||||||
|
*/
|
||||||
|
EnableQueryId();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define (or redefine) custom GUC variables.
|
* Define (or redefine) custom GUC variables.
|
||||||
*/
|
*/
|
||||||
|
@ -1,2 +1 @@
|
|||||||
shared_preload_libraries = 'pg_stat_statements'
|
shared_preload_libraries = 'pg_stat_statements'
|
||||||
compute_query_id = on
|
|
||||||
|
@ -7627,7 +7627,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
|
|||||||
<variablelist>
|
<variablelist>
|
||||||
|
|
||||||
<varlistentry id="guc-compute-query-id" xreflabel="compute_query_id">
|
<varlistentry id="guc-compute-query-id" xreflabel="compute_query_id">
|
||||||
<term><varname>compute_query_id</varname> (<type>boolean</type>)
|
<term><varname>compute_query_id</varname> (<type>enum</type>)
|
||||||
<indexterm>
|
<indexterm>
|
||||||
<primary><varname>compute_query_id</varname> configuration parameter</primary>
|
<primary><varname>compute_query_id</varname> configuration parameter</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
@ -7643,7 +7643,12 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
|
|||||||
identifier to be computed. Note that an external module can
|
identifier to be computed. Note that an external module can
|
||||||
alternatively be used if the in-core query identifier computation
|
alternatively be used if the in-core query identifier computation
|
||||||
method is not acceptable. In this case, in-core computation
|
method is not acceptable. In this case, in-core computation
|
||||||
must be disabled. The default is <literal>off</literal>.
|
must be always disabled.
|
||||||
|
Valid values are <literal>off</literal> (always disabled),
|
||||||
|
<literal>on</literal> (always enabled) and <literal>auto</literal>,
|
||||||
|
which lets modules such as <xref linkend="pgstatstatements"/>
|
||||||
|
automatically enable it.
|
||||||
|
The default is <literal>auto</literal>.
|
||||||
</para>
|
</para>
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
|
@ -18,18 +18,14 @@
|
|||||||
<xref linkend="guc-shared-preload-libraries"/> in
|
<xref linkend="guc-shared-preload-libraries"/> in
|
||||||
<filename>postgresql.conf</filename>, because it requires additional shared memory.
|
<filename>postgresql.conf</filename>, because it requires additional shared memory.
|
||||||
This means that a server restart is needed to add or remove the module.
|
This means that a server restart is needed to add or remove the module.
|
||||||
|
In addition, query identifier calculation must be enabled in order for the
|
||||||
|
module to be active, which is done automatically if <xref linkend="guc-compute-query-id"/>
|
||||||
|
is set to <literal>auto</literal> or <literal>on</literal>, or any third-party
|
||||||
|
module that calculates query identifiers is loaded.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The module will not track statistics unless query
|
When <filename>pg_stat_statements</filename> is active, it tracks
|
||||||
identifiers are calculated. This can be done by enabling <xref
|
|
||||||
linkend="guc-compute-query-id"/> or using a third-party module that
|
|
||||||
computes its own query identifiers. Note that all statistics tracked
|
|
||||||
by this module must be reset if the query identifier method is changed.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
When <filename>pg_stat_statements</filename> is loaded, it tracks
|
|
||||||
statistics across all databases of the server. To access and manipulate
|
statistics across all databases of the server. To access and manipulate
|
||||||
these statistics, the module provides views
|
these statistics, the module provides views
|
||||||
<structname>pg_stat_statements</structname> and
|
<structname>pg_stat_statements</structname> and
|
||||||
|
@ -3181,10 +3181,12 @@ Author: Bruce Momjian <bruce@momjian.us>
|
|||||||
Move query hash computation from pg_stat_statements to the core server (Julien Rouhaud)
|
Move query hash computation from pg_stat_statements to the core server (Julien Rouhaud)
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<!--
|
||||||
<para>
|
<para>
|
||||||
Extension pg_stat_statements will now need to enable query hash computation to function properly.
|
Extension pg_stat_statements will now need to enable query hash computation to function properly.
|
||||||
This can be done by enabling the server variable compute_query_id or by using an extension with a custom hash computation method.
|
This can be done by enabling the server variable compute_query_id or by using an extension with a custom hash computation method.
|
||||||
</para>
|
</para>
|
||||||
|
-->
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -245,7 +245,7 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
|
|||||||
es->summary = (summary_set) ? es->summary : es->analyze;
|
es->summary = (summary_set) ? es->summary : es->analyze;
|
||||||
|
|
||||||
query = castNode(Query, stmt->query);
|
query = castNode(Query, stmt->query);
|
||||||
if (compute_query_id)
|
if (IsQueryIdEnabled())
|
||||||
jstate = JumbleQuery(query, pstate->p_sourcetext);
|
jstate = JumbleQuery(query, pstate->p_sourcetext);
|
||||||
|
|
||||||
if (post_parse_analyze_hook)
|
if (post_parse_analyze_hook)
|
||||||
|
@ -124,7 +124,7 @@ parse_analyze(RawStmt *parseTree, const char *sourceText,
|
|||||||
|
|
||||||
query = transformTopLevelStmt(pstate, parseTree);
|
query = transformTopLevelStmt(pstate, parseTree);
|
||||||
|
|
||||||
if (compute_query_id)
|
if (IsQueryIdEnabled())
|
||||||
jstate = JumbleQuery(query, sourceText);
|
jstate = JumbleQuery(query, sourceText);
|
||||||
|
|
||||||
if (post_parse_analyze_hook)
|
if (post_parse_analyze_hook)
|
||||||
@ -163,7 +163,7 @@ parse_analyze_varparams(RawStmt *parseTree, const char *sourceText,
|
|||||||
/* make sure all is well with parameter types */
|
/* make sure all is well with parameter types */
|
||||||
check_variable_parameters(pstate, query);
|
check_variable_parameters(pstate, query);
|
||||||
|
|
||||||
if (compute_query_id)
|
if (IsQueryIdEnabled())
|
||||||
jstate = JumbleQuery(query, sourceText);
|
jstate = JumbleQuery(query, sourceText);
|
||||||
|
|
||||||
if (post_parse_analyze_hook)
|
if (post_parse_analyze_hook)
|
||||||
|
@ -521,6 +521,7 @@ typedef struct
|
|||||||
pg_time_t first_syslogger_file_time;
|
pg_time_t first_syslogger_file_time;
|
||||||
bool redirection_done;
|
bool redirection_done;
|
||||||
bool IsBinaryUpgrade;
|
bool IsBinaryUpgrade;
|
||||||
|
bool auto_query_id_enabled;
|
||||||
int max_safe_fds;
|
int max_safe_fds;
|
||||||
int MaxBackends;
|
int MaxBackends;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -6168,6 +6169,7 @@ save_backend_variables(BackendParameters *param, Port *port,
|
|||||||
|
|
||||||
param->redirection_done = redirection_done;
|
param->redirection_done = redirection_done;
|
||||||
param->IsBinaryUpgrade = IsBinaryUpgrade;
|
param->IsBinaryUpgrade = IsBinaryUpgrade;
|
||||||
|
param->auto_query_id_enabled = auto_query_id_enabled;
|
||||||
param->max_safe_fds = max_safe_fds;
|
param->max_safe_fds = max_safe_fds;
|
||||||
|
|
||||||
param->MaxBackends = MaxBackends;
|
param->MaxBackends = MaxBackends;
|
||||||
@ -6401,6 +6403,7 @@ restore_backend_variables(BackendParameters *param, Port *port)
|
|||||||
|
|
||||||
redirection_done = param->redirection_done;
|
redirection_done = param->redirection_done;
|
||||||
IsBinaryUpgrade = param->IsBinaryUpgrade;
|
IsBinaryUpgrade = param->IsBinaryUpgrade;
|
||||||
|
auto_query_id_enabled = param->auto_query_id_enabled;
|
||||||
max_safe_fds = param->max_safe_fds;
|
max_safe_fds = param->max_safe_fds;
|
||||||
|
|
||||||
MaxBackends = param->MaxBackends;
|
MaxBackends = param->MaxBackends;
|
||||||
|
@ -704,7 +704,7 @@ pg_analyze_and_rewrite_params(RawStmt *parsetree,
|
|||||||
|
|
||||||
query = transformTopLevelStmt(pstate, parsetree);
|
query = transformTopLevelStmt(pstate, parsetree);
|
||||||
|
|
||||||
if (compute_query_id)
|
if (IsQueryIdEnabled())
|
||||||
jstate = JumbleQuery(query, query_string);
|
jstate = JumbleQuery(query, query_string);
|
||||||
|
|
||||||
if (post_parse_analyze_hook)
|
if (post_parse_analyze_hook)
|
||||||
|
@ -101,6 +101,7 @@
|
|||||||
#include "utils/plancache.h"
|
#include "utils/plancache.h"
|
||||||
#include "utils/portal.h"
|
#include "utils/portal.h"
|
||||||
#include "utils/ps_status.h"
|
#include "utils/ps_status.h"
|
||||||
|
#include "utils/queryjumble.h"
|
||||||
#include "utils/rls.h"
|
#include "utils/rls.h"
|
||||||
#include "utils/snapmgr.h"
|
#include "utils/snapmgr.h"
|
||||||
#include "utils/tzparser.h"
|
#include "utils/tzparser.h"
|
||||||
@ -402,6 +403,23 @@ static const struct config_enum_entry backslash_quote_options[] = {
|
|||||||
{NULL, 0, false}
|
{NULL, 0, false}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Although only "on", "off", and "auto" are documented, we accept
|
||||||
|
* all the likely variants of "on" and "off".
|
||||||
|
*/
|
||||||
|
static const struct config_enum_entry compute_query_id_options[] = {
|
||||||
|
{"auto", COMPUTE_QUERY_ID_AUTO, false},
|
||||||
|
{"on", COMPUTE_QUERY_ID_ON, false},
|
||||||
|
{"off", COMPUTE_QUERY_ID_OFF, false},
|
||||||
|
{"true", COMPUTE_QUERY_ID_ON, true},
|
||||||
|
{"false", COMPUTE_QUERY_ID_OFF, true},
|
||||||
|
{"yes", COMPUTE_QUERY_ID_ON, true},
|
||||||
|
{"no", COMPUTE_QUERY_ID_OFF, true},
|
||||||
|
{"1", COMPUTE_QUERY_ID_ON, true},
|
||||||
|
{"0", COMPUTE_QUERY_ID_OFF, true},
|
||||||
|
{NULL, 0, false}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Although only "on", "off", and "partition" are documented, we
|
* Although only "on", "off", and "partition" are documented, we
|
||||||
* accept all the likely variants of "on" and "off".
|
* accept all the likely variants of "on" and "off".
|
||||||
@ -534,7 +552,6 @@ extern const struct config_enum_entry dynamic_shared_memory_options[];
|
|||||||
/*
|
/*
|
||||||
* GUC option variables that are exported from this module
|
* GUC option variables that are exported from this module
|
||||||
*/
|
*/
|
||||||
bool compute_query_id = false;
|
|
||||||
bool log_duration = false;
|
bool log_duration = false;
|
||||||
bool Debug_print_plan = false;
|
bool Debug_print_plan = false;
|
||||||
bool Debug_print_parse = false;
|
bool Debug_print_parse = false;
|
||||||
@ -1441,15 +1458,6 @@ static struct config_bool ConfigureNamesBool[] =
|
|||||||
true,
|
true,
|
||||||
NULL, NULL, NULL
|
NULL, NULL, NULL
|
||||||
},
|
},
|
||||||
{
|
|
||||||
{"compute_query_id", PGC_SUSET, STATS_MONITORING,
|
|
||||||
gettext_noop("Compute query identifiers."),
|
|
||||||
NULL
|
|
||||||
},
|
|
||||||
&compute_query_id,
|
|
||||||
false,
|
|
||||||
NULL, NULL, NULL
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
{"log_parser_stats", PGC_SUSET, STATS_MONITORING,
|
{"log_parser_stats", PGC_SUSET, STATS_MONITORING,
|
||||||
gettext_noop("Writes parser performance statistics to the server log."),
|
gettext_noop("Writes parser performance statistics to the server log."),
|
||||||
@ -4619,6 +4627,16 @@ static struct config_enum ConfigureNamesEnum[] =
|
|||||||
NULL, NULL, NULL
|
NULL, NULL, NULL
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
{"compute_query_id", PGC_SUSET, STATS_MONITORING,
|
||||||
|
gettext_noop("Compute query identifiers."),
|
||||||
|
NULL
|
||||||
|
},
|
||||||
|
&compute_query_id,
|
||||||
|
COMPUTE_QUERY_ID_AUTO, compute_query_id_options,
|
||||||
|
NULL, NULL, NULL
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{"constraint_exclusion", PGC_USERSET, QUERY_TUNING_OTHER,
|
{"constraint_exclusion", PGC_USERSET, QUERY_TUNING_OTHER,
|
||||||
gettext_noop("Enables the planner to use constraints to optimize queries."),
|
gettext_noop("Enables the planner to use constraints to optimize queries."),
|
||||||
|
@ -604,7 +604,7 @@
|
|||||||
|
|
||||||
# - Monitoring -
|
# - Monitoring -
|
||||||
|
|
||||||
#compute_query_id = off
|
#compute_query_id = auto
|
||||||
#log_statement_stats = off
|
#log_statement_stats = off
|
||||||
#log_parser_stats = off
|
#log_parser_stats = off
|
||||||
#log_planner_stats = off
|
#log_planner_stats = off
|
||||||
|
@ -39,6 +39,12 @@
|
|||||||
|
|
||||||
#define JUMBLE_SIZE 1024 /* query serialization buffer size */
|
#define JUMBLE_SIZE 1024 /* query serialization buffer size */
|
||||||
|
|
||||||
|
/* GUC parameters */
|
||||||
|
int compute_query_id = COMPUTE_QUERY_ID_AUTO;
|
||||||
|
|
||||||
|
/* True when compute_query_id is ON, or AUTO and a module requests them */
|
||||||
|
bool query_id_enabled = false;
|
||||||
|
|
||||||
static uint64 compute_utility_query_id(const char *str, int query_location, int query_len);
|
static uint64 compute_utility_query_id(const char *str, int query_location, int query_len);
|
||||||
static void AppendJumble(JumbleState *jstate,
|
static void AppendJumble(JumbleState *jstate,
|
||||||
const unsigned char *item, Size size);
|
const unsigned char *item, Size size);
|
||||||
@ -96,6 +102,8 @@ JumbleQuery(Query *query, const char *querytext)
|
|||||||
{
|
{
|
||||||
JumbleState *jstate = NULL;
|
JumbleState *jstate = NULL;
|
||||||
|
|
||||||
|
Assert(IsQueryIdEnabled());
|
||||||
|
|
||||||
if (query->utilityStmt)
|
if (query->utilityStmt)
|
||||||
{
|
{
|
||||||
query->queryId = compute_utility_query_id(querytext,
|
query->queryId = compute_utility_query_id(querytext,
|
||||||
@ -132,6 +140,19 @@ JumbleQuery(Query *query, const char *querytext)
|
|||||||
return jstate;
|
return jstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enables query identifier computation.
|
||||||
|
*
|
||||||
|
* Third-party plugins can use this function to inform core that they require
|
||||||
|
* a query identifier to be computed.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
EnableQueryId(void)
|
||||||
|
{
|
||||||
|
if (compute_query_id != COMPUTE_QUERY_ID_OFF)
|
||||||
|
query_id_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute a query identifier for the given utility query string.
|
* Compute a query identifier for the given utility query string.
|
||||||
*/
|
*/
|
||||||
|
@ -247,7 +247,6 @@ extern bool log_btree_build_stats;
|
|||||||
extern PGDLLIMPORT bool check_function_bodies;
|
extern PGDLLIMPORT bool check_function_bodies;
|
||||||
extern bool session_auth_is_superuser;
|
extern bool session_auth_is_superuser;
|
||||||
|
|
||||||
extern bool compute_query_id;
|
|
||||||
extern bool log_duration;
|
extern bool log_duration;
|
||||||
extern int log_parameter_max_length;
|
extern int log_parameter_max_length;
|
||||||
extern int log_parameter_max_length_on_error;
|
extern int log_parameter_max_length_on_error;
|
||||||
|
@ -52,7 +52,36 @@ typedef struct JumbleState
|
|||||||
int highest_extern_param_id;
|
int highest_extern_param_id;
|
||||||
} JumbleState;
|
} JumbleState;
|
||||||
|
|
||||||
const char *CleanQuerytext(const char *query, int *location, int *len);
|
/* Values for the compute_query_id GUC */
|
||||||
JumbleState *JumbleQuery(Query *query, const char *querytext);
|
typedef enum
|
||||||
|
{
|
||||||
|
COMPUTE_QUERY_ID_OFF,
|
||||||
|
COMPUTE_QUERY_ID_ON,
|
||||||
|
COMPUTE_QUERY_ID_AUTO
|
||||||
|
} ComputeQueryIdType;
|
||||||
|
|
||||||
|
/* GUC parameters */
|
||||||
|
extern int compute_query_id;
|
||||||
|
|
||||||
|
|
||||||
|
extern const char *CleanQuerytext(const char *query, int *location, int *len);
|
||||||
|
extern JumbleState *JumbleQuery(Query *query, const char *querytext);
|
||||||
|
extern void EnableQueryId(void);
|
||||||
|
|
||||||
|
extern bool query_id_enabled;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns whether query identifier computation has been enabled, either
|
||||||
|
* directly in the GUC or by a module when the setting is 'auto'.
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
IsQueryIdEnabled(void)
|
||||||
|
{
|
||||||
|
if (compute_query_id == COMPUTE_QUERY_ID_OFF)
|
||||||
|
return false;
|
||||||
|
if (compute_query_id == COMPUTE_QUERY_ID_ON)
|
||||||
|
return true;
|
||||||
|
return query_id_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* QUERYJUMBLE_H */
|
#endif /* QUERYJUMBLE_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user