mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
> I can see a couple possible downsides: (a) the library might have some
> weird behavior across fork boundaries; (b) the additional memory space > that has to be duplicated into child processes will cost something per > child launch, even if the child never uses it. But these are only > arguments that it might not *always* be a prudent thing to do, not that > we shouldn't give the DBA the tool to do it if he wants. So fire away. Here is a patch for the above, including a documentation update. It creates a new GUC variable "preload_libraries", that accepts a list in the form: preload_libraries = '$libdir/mylib1:initfunc,$libdir/mylib2' If ":initfunc" is omitted or not found, no initialization function is executed, but the library is still preloaded. If "$libdir/mylib" isn't found, the postmaster refuses to start. In my testing with PL/R, it reduces the first call to a PL/R function (after connecting) from almost 2 seconds, down to about 8 ms. Joe Conway
This commit is contained in:
parent
e733510d5d
commit
15ce2d2e4a
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.171 2003/03/20 03:34:55 momjian Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.172 2003/03/20 04:51:44 momjian Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<Chapter Id="runtime">
|
<Chapter Id="runtime">
|
||||||
@ -1799,6 +1799,35 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>PRELOAD_LIBRARIES</varname> (<type>string</type>)</term>
|
||||||
|
<indexterm><primary>preload_libraries</></>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
This variable specifies one or more shared libraries that are to be
|
||||||
|
preloaded at Postmaster start. An initialization function can also be
|
||||||
|
optionally specified by adding a colon followed by the name of the
|
||||||
|
initialization function after the library name. For example
|
||||||
|
<literal>'$libdir/mylib:init_mylib'</literal> would cause <literal>mylib</>
|
||||||
|
to be preloaded and <literal>init_mylib</> to be executed. If more than
|
||||||
|
one library is to be loaded, they must be delimited with a comma.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
If <literal>mylib</> is not found, the postmaster will fail to start.
|
||||||
|
However, if <literal>init_mylib</> is not found, <literal>mylib</> will
|
||||||
|
still be preloaded without executing the initialization function.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
By preloading a shared library (and initializing it if applicable),
|
||||||
|
the library startup time is avoided when the library is used later in a
|
||||||
|
specific backend. However there is a cost in terms of memory duplication
|
||||||
|
as every backend is forked, whether or not the library is used.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>REGEX_FLAVOR</varname> (<type>string</type>)</term>
|
<term><varname>REGEX_FLAVOR</varname> (<type>string</type>)</term>
|
||||||
<indexterm><primary>regular expressions</></>
|
<indexterm><primary>regular expressions</></>
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.307 2003/02/23 04:48:19 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.308 2003/03/20 04:51:44 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -205,6 +205,8 @@ bool LogSourcePort;
|
|||||||
bool Log_connections = false;
|
bool Log_connections = false;
|
||||||
bool Db_user_namespace = false;
|
bool Db_user_namespace = false;
|
||||||
|
|
||||||
|
/* list of library:init-function to be preloaded */
|
||||||
|
char *preload_libraries_string = NULL;
|
||||||
|
|
||||||
/* Startup/shutdown state */
|
/* Startup/shutdown state */
|
||||||
static pid_t StartupPID = 0,
|
static pid_t StartupPID = 0,
|
||||||
@ -645,6 +647,13 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
secure_initialize();
|
secure_initialize();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* process any libraries that should be preloaded and
|
||||||
|
* optionally pre-initialized
|
||||||
|
*/
|
||||||
|
if (preload_libraries_string)
|
||||||
|
process_preload_libraries(preload_libraries_string);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fork away from controlling terminal, if -S specified.
|
* Fork away from controlling terminal, if -S specified.
|
||||||
*
|
*
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.100 2003/01/27 00:51:06 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.101 2003/03/20 04:51:44 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1044,3 +1044,92 @@ ValidatePgVersion(const char *path)
|
|||||||
"which is not compatible with this version %s.",
|
"which is not compatible with this version %s.",
|
||||||
file_major, file_minor, version_string);
|
file_major, file_minor, version_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Library preload support
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__mc68000__) && defined(__ELF__)
|
||||||
|
typedef int32 ((*func_ptr) ());
|
||||||
|
#else
|
||||||
|
typedef char *((*func_ptr) ());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* process any libraries that should be preloaded and
|
||||||
|
* optionally pre-initialized
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
process_preload_libraries(char *preload_libraries_string)
|
||||||
|
{
|
||||||
|
char *rawstring;
|
||||||
|
List *elemlist;
|
||||||
|
List *l;
|
||||||
|
|
||||||
|
if (preload_libraries_string == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Need a modifiable copy of string */
|
||||||
|
rawstring = pstrdup(preload_libraries_string);
|
||||||
|
|
||||||
|
/* Parse string into list of identifiers */
|
||||||
|
if (!SplitIdentifierString(rawstring, ',', &elemlist))
|
||||||
|
{
|
||||||
|
/* syntax error in list */
|
||||||
|
pfree(rawstring);
|
||||||
|
freeList(elemlist);
|
||||||
|
elog(LOG, "invalid list syntax for preload_libraries configuration option");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(l, elemlist)
|
||||||
|
{
|
||||||
|
char *tok = (char *) lfirst(l);
|
||||||
|
char *sep = strstr(tok, ":");
|
||||||
|
char *filename = NULL;
|
||||||
|
char *funcname = NULL;
|
||||||
|
func_ptr initfunc;
|
||||||
|
|
||||||
|
if (sep)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* a colon separator implies there is an initialization function
|
||||||
|
* that we need to run in addition to loading the library
|
||||||
|
*/
|
||||||
|
size_t filename_len = sep - tok;
|
||||||
|
size_t funcname_len = strlen(tok) - filename_len - 1;
|
||||||
|
|
||||||
|
filename = (char *) palloc(filename_len + 1);
|
||||||
|
memset(filename, '\0', filename_len + 1);
|
||||||
|
snprintf(filename, filename_len + 1, "%s", tok);
|
||||||
|
|
||||||
|
funcname = (char *) palloc(funcname_len + 1);
|
||||||
|
memset(funcname, '\0', funcname_len + 1);
|
||||||
|
snprintf(funcname, funcname_len + 1, "%s", sep + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* no separator -- just load the library
|
||||||
|
*/
|
||||||
|
filename = pstrdup(tok);
|
||||||
|
funcname = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
initfunc = (func_ptr) load_external_function(filename, funcname, false, NULL);
|
||||||
|
if (initfunc)
|
||||||
|
(*initfunc)();
|
||||||
|
|
||||||
|
elog(LOG, "preloaded library %s with initialization function %s", filename, funcname);
|
||||||
|
|
||||||
|
if (filename != NULL)
|
||||||
|
pfree(filename);
|
||||||
|
|
||||||
|
if (funcname != NULL)
|
||||||
|
pfree(funcname);
|
||||||
|
}
|
||||||
|
|
||||||
|
pfree(rawstring);
|
||||||
|
freeList(elemlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* command, configuration file, and command line options.
|
* command, configuration file, and command line options.
|
||||||
* See src/backend/utils/misc/README for more information.
|
* See src/backend/utils/misc/README for more information.
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.116 2003/03/04 21:51:21 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.117 2003/03/20 04:51:44 momjian Exp $
|
||||||
*
|
*
|
||||||
* Copyright 2000 by PostgreSQL Global Development Group
|
* Copyright 2000 by PostgreSQL Global Development Group
|
||||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||||
@ -60,6 +60,7 @@ extern int CheckPointTimeout;
|
|||||||
extern bool autocommit;
|
extern bool autocommit;
|
||||||
extern int CommitDelay;
|
extern int CommitDelay;
|
||||||
extern int CommitSiblings;
|
extern int CommitSiblings;
|
||||||
|
extern char *preload_libraries_string;
|
||||||
|
|
||||||
#ifdef HAVE_SYSLOG
|
#ifdef HAVE_SYSLOG
|
||||||
extern char *Syslog_facility;
|
extern char *Syslog_facility;
|
||||||
@ -814,6 +815,12 @@ static struct config_string
|
|||||||
"C", locale_time_assign, NULL
|
"C", locale_time_assign, NULL
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
{"preload_libraries", PGC_POSTMASTER, GUC_LIST_INPUT | GUC_LIST_QUOTE},
|
||||||
|
&preload_libraries_string,
|
||||||
|
"", NULL, NULL
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
{"regex_flavor", PGC_USERSET}, ®ex_flavor_string,
|
{"regex_flavor", PGC_USERSET}, ®ex_flavor_string,
|
||||||
"advanced", assign_regex_flavor, NULL
|
"advanced", assign_regex_flavor, NULL
|
||||||
|
@ -214,4 +214,5 @@
|
|||||||
#transform_null_equals = false
|
#transform_null_equals = false
|
||||||
#statement_timeout = 0 # 0 is disabled, in milliseconds
|
#statement_timeout = 0 # 0 is disabled, in milliseconds
|
||||||
#db_user_namespace = false
|
#db_user_namespace = false
|
||||||
|
#preload_libraries = ''
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: miscadmin.h,v 1.116 2003/02/22 05:57:45 tgl Exp $
|
* $Id: miscadmin.h,v 1.117 2003/03/20 04:51:44 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* some of the information in this file should be moved to
|
* some of the information in this file should be moved to
|
||||||
@ -288,6 +288,7 @@ extern void RecordSharedMemoryInLockFile(unsigned long id1,
|
|||||||
unsigned long id2);
|
unsigned long id2);
|
||||||
|
|
||||||
extern void ValidatePgVersion(const char *path);
|
extern void ValidatePgVersion(const char *path);
|
||||||
|
extern void process_preload_libraries(char *preload_libraries_string);
|
||||||
|
|
||||||
/* these externs do not belong here... */
|
/* these externs do not belong here... */
|
||||||
extern void IgnoreSystemIndexes(bool mode);
|
extern void IgnoreSystemIndexes(bool mode);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user