From 070518ddab2c94afea119f2b1944c05d16792b07 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut <peter_e@gmx.net> Date: Wed, 12 Jun 2013 22:28:24 -0400 Subject: [PATCH] Add session_preload_libraries configuration parameter This is like shared_preload_libraries except that it takes effect at backend start and can be changed without a full postmaster restart. It is like local_preload_libraries except that it is still only settable by a superuser. This can be a better way to load modules such as auto_explain. Since there are now three preload parameters, regroup the documentation a bit. Put all parameters into one section, explain common functionality only once, update the descriptions to reflect current and future realities. Reviewed-by: Dimitri Fontaine <dimitri@2ndQuadrant.fr> --- doc/src/sgml/auto-explain.sgml | 5 +- doc/src/sgml/config.sgml | 281 ++++++++++++++++++------------ src/backend/tcop/postgres.c | 2 +- src/backend/utils/init/miscinit.c | 6 +- src/backend/utils/misc/guc.c | 19 +- src/include/miscadmin.h | 3 +- src/include/utils/guc_tables.h | 1 + 7 files changed, 193 insertions(+), 124 deletions(-) diff --git a/doc/src/sgml/auto-explain.sgml b/doc/src/sgml/auto-explain.sgml index 03b2309da8f..cd0d6d8727c 100644 --- a/doc/src/sgml/auto-explain.sgml +++ b/doc/src/sgml/auto-explain.sgml @@ -24,7 +24,8 @@ LOAD 'auto_explain'; </programlisting> (You must be superuser to do that.) More typical usage is to preload - it into all sessions by including <literal>auto_explain</> in + it into some or all sessions by including <literal>auto_explain</> in + <xref linkend="guc-session-preload-libraries"> or <xref linkend="guc-shared-preload-libraries"> in <filename>postgresql.conf</>. Then you can track unexpectedly slow queries no matter when they happen. Of course there is a price in overhead for @@ -185,7 +186,7 @@ LOAD 'auto_explain'; <programlisting> # postgresql.conf -shared_preload_libraries = 'auto_explain' +session_preload_libraries = 'auto_explain' auto_explain.log_min_duration = '3s' </programlisting> diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 6a4d15fc84d..23ebc11202f 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1252,66 +1252,6 @@ include 'filename' </para> </listitem> </varlistentry> - - <varlistentry id="guc-shared-preload-libraries" xreflabel="shared_preload_libraries"> - <term><varname>shared_preload_libraries</varname> (<type>string</type>)</term> - <indexterm> - <primary><varname>shared_preload_libraries</> configuration parameter</primary> - </indexterm> - <listitem> - <para> - This variable specifies one or more shared libraries - to be preloaded at server start. For example, - <literal>'$libdir/mylib'</literal> would cause - <literal>mylib.so</> (or on some platforms, - <literal>mylib.sl</>) to be preloaded from the installation's - standard library directory. - All library names are converted to lower case unless double-quoted. - If more than one library is to be loaded, separate their names - with commas. This parameter can only be set at server start. - </para> - - <para> - <productname>PostgreSQL</productname> procedural language - libraries can be preloaded in this way, typically by using the - syntax <literal>'$libdir/plXXX'</literal> where - <literal>XXX</literal> is <literal>pgsql</>, <literal>perl</>, - <literal>tcl</>, or <literal>python</>. - </para> - - <para> - By preloading a shared library, the library startup time is avoided - when the library is first used. However, the time to start each new - server process might increase slightly, even if that process never - uses the library. So this parameter is recommended only for - libraries that will be used in most sessions. - </para> - - <note> - <para> - On Windows hosts, preloading a library at server start will not reduce - the time required to start each new server process; each server process - will re-load all preload libraries. However, <varname>shared_preload_libraries - </varname> is still useful on Windows hosts because some shared libraries may - need to perform certain operations that only take place at postmaster start - (for example, a shared library may need to reserve lightweight locks - or shared memory and you can't do that after the postmaster has started). - </para> - </note> - <para> - If a specified library is not found, - the server will fail to start. - </para> - - <para> - Every PostgreSQL-supported library has a <quote>magic - block</> that is checked to guarantee compatibility. - For this reason, non-PostgreSQL libraries cannot be - loaded in this way. - </para> - </listitem> - </varlistentry> - </variablelist> </sect2> @@ -5514,6 +5454,171 @@ SET XML OPTION { DOCUMENT | CONTENT }; </variablelist> </sect2> + + <sect2 id="runtime-config-client-preload"> + <title>Shared Library Preloading</title> + + <para> + Several settings are available for preloading shared libraries into the + server, in order to load additional functionality or achieve performance + benefits. For example, a setting of + <literal>'$libdir/mylib'</literal> would cause + <literal>mylib.so</> (or on some platforms, + <literal>mylib.sl</>) to be preloaded from the installation's standard + library directory. The differences between the settings are when they + take effect and what privileges are required to change them. + </para> + + <para> + <productname>PostgreSQL</productname> procedural language libraries can + be preloaded in this way, typically by using the + syntax <literal>'$libdir/plXXX'</literal> where + <literal>XXX</literal> is <literal>pgsql</>, <literal>perl</>, + <literal>tcl</>, or <literal>python</>. + </para> + + <para> + For each parameter, if more than one library is to be loaded, separate + their names with commas. All library names are converted to lower case + unless double-quoted. + </para> + + <para> + Only shared libraries specifically intended to be used with PostgreSQL + can be loaded this way. Every PostgreSQL-supported library has + a <quote>magic block</> that is checked to guarantee compatibility. For + this reason, non-PostgreSQL libraries cannot be loaded in this way. You + might be able to use operating-system facilities such + as <envar>LD_PRELOAD</envar> for that. + </para> + + <para> + In general, refer to the documentation of a specific module for the + recommended way to load that module. + </para> + + <variablelist> + <varlistentry id="guc-local-preload-libraries" xreflabel="local_preload_libraries"> + <term><varname>local_preload_libraries</varname> (<type>string</type>)</term> + <indexterm> + <primary><varname>local_preload_libraries</> configuration parameter</primary> + </indexterm> + <indexterm> + <primary><filename>$libdir/plugins</></primary> + </indexterm> + <listitem> + <para> + This variable specifies one or more shared libraries that are to be + preloaded at connection start. This parameter cannot be changed after + the start of a particular session. If a specified library is not + found, the connection attempt will fail. + </para> + + <para> + This option can be set by any user. Because of that, the libraries + that can be loaded are restricted to those appearing in the + <filename>plugins</> subdirectory of the installation's + standard library directory. (It is the database administrator's + responsibility to ensure that only <quote>safe</> libraries + are installed there.) Entries in <varname>local_preload_libraries</> + can specify this directory explicitly, for example + <literal>$libdir/plugins/mylib</literal>, or just specify + the library name — <literal>mylib</literal> would have + the same effect as <literal>$libdir/plugins/mylib</literal>. + </para> + + <para> + Unless a module is specifically designed to be used in this way by + non-superusers, this is usually not the right setting to use. Look + at <xref linkend="guc-session-preload-libraries"> instead. + </para> + </listitem> + </varlistentry> + + + <varlistentry id="guc-session-preload-libraries" xreflabel="session_preload_libraries"> + <term><varname>session_preload_libraries</varname> (<type>string</type>)</term> + <indexterm> + <primary><varname>session_preload_libraries</> configuration parameter</primary> + </indexterm> + <listitem> + <para> + This variable specifies one or more shared libraries that are to be + preloaded at connection start. Only superusers can change this setting. + The parameter value only takes effect at the start of the connection. + Subsequent changes have no effect. If a specified library is not + found, the connection attempt will fail. + </para> + + <para> + The intent of this feature is to allow debugging or + performance-measurement libraries to be loaded into specific sessions + without an explicit + <command>LOAD</> command being given. For + example, <xref linkend="auto-explain"> could be enabled for all + sessions under a given user name by setting this parameter + with <command>ALTER ROLE SET</>. Also, this parameter can be changed + without restarting the server (but changes only take effect when a new + session is started), so it is easier to add new modules this way, even + if they should apply to all sessions. + </para> + + <para> + Unlike <xref linkend="guc-shared-preload-libraries">, there is no large + performance advantage to loading a library at session start rather than + when it is first used. There is some advantage, however, when + connection pooling is used. + </para> + </listitem> + </varlistentry> + + <varlistentry id="guc-shared-preload-libraries" xreflabel="shared_preload_libraries"> + <term><varname>shared_preload_libraries</varname> (<type>string</type>)</term> + <indexterm> + <primary><varname>shared_preload_libraries</> configuration parameter</primary> + </indexterm> + <listitem> + <para> + This variable specifies one or more shared libraries to be preloaded at + server start. with commas. This parameter can only be set at server + start. If a specified library is not found, the server will fail to + start. + </para> + + <para> + Some libraries need to perform certain operations that can only take + place at postmaster start, such as allocating shared memory, reserving + light-weight locks, or starting background workers. Those libraries + must be loaded at server start through this parameter. See the + documentation of each library for details. + </para> + + <para> + Other libraries can also be preloaded. By preloading a shared library, + the library startup time is avoided when the library is first used. + However, the time to start each new server process might increase + slightly, even if that process never uses the library. So this + parameter is recommended only for libraries that will be used in most + sessions. Also, changing this parameter requires a server restart, so + this is not the right setting to use for short-term debugging tasks, + say. Use <xref linkend="guc-session-preload-libraries"> for that + instead. + </para> + + <note> + <para> + On Windows hosts, preloading a library at server start will not reduce + the time required to start each new server process; each server process + will re-load all preload libraries. However, <varname>shared_preload_libraries + </varname> is still useful on Windows hosts for libraries that need to + perform operations at postmaster start time.. + </para> + </note> + </listitem> + </varlistentry> + </variablelist> + </sect2> + <sect2 id="runtime-config-client-other"> <title>Other Defaults</title> @@ -5585,62 +5690,6 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' </listitem> </varlistentry> - <varlistentry id="guc-local-preload-libraries" xreflabel="local_preload_libraries"> - <term><varname>local_preload_libraries</varname> (<type>string</type>)</term> - <indexterm> - <primary><varname>local_preload_libraries</> configuration parameter</primary> - </indexterm> - <indexterm> - <primary><filename>$libdir/plugins</></primary> - </indexterm> - <listitem> - <para> - This variable specifies one or more shared libraries that are - to be preloaded at connection start. If more than one library - is to be loaded, separate their names with commas. All library - names are converted to lower case unless double-quoted. - This parameter cannot be changed after the start of a particular - session. - </para> - - <para> - Because this is not a superuser-only option, the libraries - that can be loaded are restricted to those appearing in the - <filename>plugins</> subdirectory of the installation's - standard library directory. (It is the database administrator's - responsibility to ensure that only <quote>safe</> libraries - are installed there.) Entries in <varname>local_preload_libraries</> - can specify this directory explicitly, for example - <literal>$libdir/plugins/mylib</literal>, or just specify - the library name — <literal>mylib</literal> would have - the same effect as <literal>$libdir/plugins/mylib</literal>. - </para> - - <para> - Unlike <xref linkend="guc-shared-preload-libraries">, there is no - performance advantage to loading a library at session - start rather than when it is first used. Rather, the intent of - this feature is to allow debugging or performance-measurement - libraries to be loaded into specific sessions without an explicit - <command>LOAD</> command being given. For example, debugging could - be enabled for all sessions under a given user name by setting - this parameter with <command>ALTER ROLE SET</>. - </para> - - <para> - If a specified library is not found, - the connection attempt will fail. - </para> - - <para> - Every PostgreSQL-supported library has a <quote>magic - block</> that is checked to guarantee compatibility. - For this reason, non-PostgreSQL libraries cannot be - loaded in this way. - </para> - </listitem> - </varlistentry> - </variablelist> </sect2> </sect1> diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index c0667b24e17..ddd60dee4f4 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -3743,7 +3743,7 @@ PostgresMain(int argc, char *argv[], * process any libraries that should be preloaded at backend start (this * likewise can't be done until GUC settings are complete) */ - process_local_preload_libraries(); + process_session_preload_libraries(); /* * Send this backend's cancellation info to the frontend. diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index cb78caf8ebd..ed514f61280 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -1222,6 +1222,7 @@ ValidatePgVersion(const char *path) * GUC variables: lists of library names to be preloaded at postmaster * start and at backend start */ +char *session_preload_libraries_string = NULL; char *shared_preload_libraries_string = NULL; char *local_preload_libraries_string = NULL; @@ -1318,8 +1319,11 @@ process_shared_preload_libraries(void) * process any libraries that should be preloaded at backend start */ void -process_local_preload_libraries(void) +process_session_preload_libraries(void) { + load_libraries(session_preload_libraries_string, + "session_preload_libraries", + false); load_libraries(local_preload_libraries_string, "local_preload_libraries", true); diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 5aefd1b62c5..2b753f81d76 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -591,6 +591,8 @@ const char *const config_group_names[] = gettext_noop("Client Connection Defaults / Statement Behavior"), /* CLIENT_CONN_LOCALE */ gettext_noop("Client Connection Defaults / Locale and Formatting"), + /* CLIENT_CONN_PRELOAD */ + gettext_noop("Client Connection Defaults / Shared Library Preloading"), /* CLIENT_CONN_OTHER */ gettext_noop("Client Connection Defaults / Other Defaults"), /* LOCK_MANAGEMENT */ @@ -2770,7 +2772,18 @@ static struct config_string ConfigureNamesString[] = }, { - {"shared_preload_libraries", PGC_POSTMASTER, RESOURCES_KERNEL, + {"session_preload_libraries", PGC_SUSET, CLIENT_CONN_PRELOAD, + gettext_noop("Lists shared libraries to preload into each backend."), + NULL, + GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY + }, + &session_preload_libraries_string, + "", + NULL, NULL, NULL + }, + + { + {"shared_preload_libraries", PGC_POSTMASTER, CLIENT_CONN_PRELOAD, gettext_noop("Lists shared libraries to preload into server."), NULL, GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY @@ -2781,8 +2794,8 @@ static struct config_string ConfigureNamesString[] = }, { - {"local_preload_libraries", PGC_BACKEND, CLIENT_CONN_OTHER, - gettext_noop("Lists shared libraries to preload into each backend."), + {"local_preload_libraries", PGC_BACKEND, CLIENT_CONN_PRELOAD, + gettext_noop("Lists unprivileged shared libraries to preload into each backend."), NULL, GUC_LIST_INPUT | GUC_LIST_QUOTE }, diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 48985b370fa..edced29f516 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -403,6 +403,7 @@ extern void BaseInit(void); /* in utils/init/miscinit.c */ extern bool IgnoreSystemIndexes; extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress; +extern char *session_preload_libraries_string; extern char *shared_preload_libraries_string; extern char *local_preload_libraries_string; @@ -438,7 +439,7 @@ extern void TouchSocketLockFiles(void); extern void AddToDataDirLockFile(int target_line, const char *str); extern void ValidatePgVersion(const char *path); extern void process_shared_preload_libraries(void); -extern void process_local_preload_libraries(void); +extern void process_session_preload_libraries(void); extern void pg_bindtextdomain(const char *domain); extern bool has_rolreplication(Oid roleid); diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h index 8dcdd4baa1e..4f1f6e0b671 100644 --- a/src/include/utils/guc_tables.h +++ b/src/include/utils/guc_tables.h @@ -88,6 +88,7 @@ enum config_group CLIENT_CONN, CLIENT_CONN_STATEMENT, CLIENT_CONN_LOCALE, + CLIENT_CONN_PRELOAD, CLIENT_CONN_OTHER, LOCK_MANAGEMENT, COMPAT_OPTIONS, -- GitLab