Skip to content

Commit 15ce2d2

Browse files
committed
> 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
1 parent e733510 commit 15ce2d2

File tree

6 files changed

+141
-5
lines changed

6 files changed

+141
-5
lines changed

doc/src/sgml/runtime.sgml

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.171 2003/03/20 03:34:55 momjian Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.172 2003/03/20 04:51:44 momjian Exp $
33
-->
44

55
<Chapter Id="runtime">
@@ -1799,6 +1799,35 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
17991799
</listitem>
18001800
</varlistentry>
18011801

1802+
<varlistentry>
1803+
<term><varname>PRELOAD_LIBRARIES</varname> (<type>string</type>)</term>
1804+
<indexterm><primary>preload_libraries</></>
1805+
<listitem>
1806+
<para>
1807+
This variable specifies one or more shared libraries that are to be
1808+
preloaded at Postmaster start. An initialization function can also be
1809+
optionally specified by adding a colon followed by the name of the
1810+
initialization function after the library name. For example
1811+
<literal>'$libdir/mylib:init_mylib'</literal> would cause <literal>mylib</>
1812+
to be preloaded and <literal>init_mylib</> to be executed. If more than
1813+
one library is to be loaded, they must be delimited with a comma.
1814+
</para>
1815+
1816+
<para>
1817+
If <literal>mylib</> is not found, the postmaster will fail to start.
1818+
However, if <literal>init_mylib</> is not found, <literal>mylib</> will
1819+
still be preloaded without executing the initialization function.
1820+
</para>
1821+
1822+
<para>
1823+
By preloading a shared library (and initializing it if applicable),
1824+
the library startup time is avoided when the library is used later in a
1825+
specific backend. However there is a cost in terms of memory duplication
1826+
as every backend is forked, whether or not the library is used.
1827+
</para>
1828+
</listitem>
1829+
</varlistentry>
1830+
18021831
<varlistentry>
18031832
<term><varname>REGEX_FLAVOR</varname> (<type>string</type>)</term>
18041833
<indexterm><primary>regular expressions</></>

src/backend/postmaster/postmaster.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
*
3838
*
3939
* IDENTIFICATION
40-
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.307 2003/02/23 04:48:19 tgl Exp $
40+
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.308 2003/03/20 04:51:44 momjian Exp $
4141
*
4242
* NOTES
4343
*
@@ -205,6 +205,8 @@ bool LogSourcePort;
205205
bool Log_connections = false;
206206
bool Db_user_namespace = false;
207207

208+
/* list of library:init-function to be preloaded */
209+
char *preload_libraries_string = NULL;
208210

209211
/* Startup/shutdown state */
210212
static pid_t StartupPID = 0,
@@ -645,6 +647,13 @@ PostmasterMain(int argc, char *argv[])
645647
secure_initialize();
646648
#endif
647649

650+
/*
651+
* process any libraries that should be preloaded and
652+
* optionally pre-initialized
653+
*/
654+
if (preload_libraries_string)
655+
process_preload_libraries(preload_libraries_string);
656+
648657
/*
649658
* Fork away from controlling terminal, if -S specified.
650659
*

src/backend/utils/init/miscinit.c

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.100 2003/01/27 00:51:06 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.101 2003/03/20 04:51:44 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1044,3 +1044,92 @@ ValidatePgVersion(const char *path)
10441044
"which is not compatible with this version %s.",
10451045
file_major, file_minor, version_string);
10461046
}
1047+
1048+
/*-------------------------------------------------------------------------
1049+
* Library preload support
1050+
*-------------------------------------------------------------------------
1051+
*/
1052+
1053+
#if defined(__mc68000__) && defined(__ELF__)
1054+
typedef int32 ((*func_ptr) ());
1055+
#else
1056+
typedef char *((*func_ptr) ());
1057+
#endif
1058+
1059+
/*
1060+
* process any libraries that should be preloaded and
1061+
* optionally pre-initialized
1062+
*/
1063+
void
1064+
process_preload_libraries(char *preload_libraries_string)
1065+
{
1066+
char *rawstring;
1067+
List *elemlist;
1068+
List *l;
1069+
1070+
if (preload_libraries_string == NULL)
1071+
return;
1072+
1073+
/* Need a modifiable copy of string */
1074+
rawstring = pstrdup(preload_libraries_string);
1075+
1076+
/* Parse string into list of identifiers */
1077+
if (!SplitIdentifierString(rawstring, ',', &elemlist))
1078+
{
1079+
/* syntax error in list */
1080+
pfree(rawstring);
1081+
freeList(elemlist);
1082+
elog(LOG, "invalid list syntax for preload_libraries configuration option");
1083+
}
1084+
1085+
foreach(l, elemlist)
1086+
{
1087+
char *tok = (char *) lfirst(l);
1088+
char *sep = strstr(tok, ":");
1089+
char *filename = NULL;
1090+
char *funcname = NULL;
1091+
func_ptr initfunc;
1092+
1093+
if (sep)
1094+
{
1095+
/*
1096+
* a colon separator implies there is an initialization function
1097+
* that we need to run in addition to loading the library
1098+
*/
1099+
size_t filename_len = sep - tok;
1100+
size_t funcname_len = strlen(tok) - filename_len - 1;
1101+
1102+
filename = (char *) palloc(filename_len + 1);
1103+
memset(filename, '\0', filename_len + 1);
1104+
snprintf(filename, filename_len + 1, "%s", tok);
1105+
1106+
funcname = (char *) palloc(funcname_len + 1);
1107+
memset(funcname, '\0', funcname_len + 1);
1108+
snprintf(funcname, funcname_len + 1, "%s", sep + 1);
1109+
}
1110+
else
1111+
{
1112+
/*
1113+
* no separator -- just load the library
1114+
*/
1115+
filename = pstrdup(tok);
1116+
funcname = NULL;
1117+
}
1118+
1119+
initfunc = (func_ptr) load_external_function(filename, funcname, false, NULL);
1120+
if (initfunc)
1121+
(*initfunc)();
1122+
1123+
elog(LOG, "preloaded library %s with initialization function %s", filename, funcname);
1124+
1125+
if (filename != NULL)
1126+
pfree(filename);
1127+
1128+
if (funcname != NULL)
1129+
pfree(funcname);
1130+
}
1131+
1132+
pfree(rawstring);
1133+
freeList(elemlist);
1134+
}
1135+

src/backend/utils/misc/guc.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* command, configuration file, and command line options.
66
* See src/backend/utils/misc/README for more information.
77
*
8-
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.116 2003/03/04 21:51:21 tgl Exp $
8+
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.117 2003/03/20 04:51:44 momjian Exp $
99
*
1010
* Copyright 2000 by PostgreSQL Global Development Group
1111
* Written by Peter Eisentraut <peter_e@gmx.net>.
@@ -60,6 +60,7 @@ extern int CheckPointTimeout;
6060
extern bool autocommit;
6161
extern int CommitDelay;
6262
extern int CommitSiblings;
63+
extern char *preload_libraries_string;
6364

6465
#ifdef HAVE_SYSLOG
6566
extern char *Syslog_facility;
@@ -814,6 +815,12 @@ static struct config_string
814815
"C", locale_time_assign, NULL
815816
},
816817

818+
{
819+
{"preload_libraries", PGC_POSTMASTER, GUC_LIST_INPUT | GUC_LIST_QUOTE},
820+
&preload_libraries_string,
821+
"", NULL, NULL
822+
},
823+
817824
{
818825
{"regex_flavor", PGC_USERSET}, &regex_flavor_string,
819826
"advanced", assign_regex_flavor, NULL

src/backend/utils/misc/postgresql.conf.sample

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,4 +214,5 @@
214214
#transform_null_equals = false
215215
#statement_timeout = 0 # 0 is disabled, in milliseconds
216216
#db_user_namespace = false
217+
#preload_libraries = ''
217218

src/include/miscadmin.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
15-
* $Id: miscadmin.h,v 1.116 2003/02/22 05:57:45 tgl Exp $
15+
* $Id: miscadmin.h,v 1.117 2003/03/20 04:51:44 momjian Exp $
1616
*
1717
* NOTES
1818
* some of the information in this file should be moved to
@@ -288,6 +288,7 @@ extern void RecordSharedMemoryInLockFile(unsigned long id1,
288288
unsigned long id2);
289289

290290
extern void ValidatePgVersion(const char *path);
291+
extern void process_preload_libraries(char *preload_libraries_string);
291292

292293
/* these externs do not belong here... */
293294
extern void IgnoreSystemIndexes(bool mode);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy