I've written a small patch for following TODO item:
«Add GUC variable to run a command on database
panic or smart/fast/immediate shutdown.»
It adds two GUC variables as:
enable_atexit_script_file
atexit_script_file
postmaster will run related script file with passing shutdown type
(like "smart", "fast" or "immediate") as parameter to script file
on database shutdown. (Sorry, I'm not so good on PostgreSQL internals,
thus couldn't handle "panic" situation at the moment.)
I know, it's not the perfect one but I'd be so apprecited to hear
suggestions for fixing lost/wrong parts of it.
Regards.
--
"We are the middle children of history, raised by television to believe
that someday we'll be millionaires and movie stars and rock stars, but
we won't. And we're just learning this fact," Tyler said. "So don't
fuck with us."
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/postmaster/postmaster.c,v
retrieving revision 1.476
diff -u -r1.476 postmaster.c
--- src/backend/postmaster/postmaster.c 22 Nov 2005 18:17:18 -0000 1.476
+++ src/backend/postmaster/postmaster.c 10 Dec 2005 18:28:04 -0000
@@ -254,6 +254,7 @@
static void ConnFree(Port *port);
static void reset_shared(int port);
static void SIGHUP_handler(SIGNAL_ARGS);
+static void RunAtexitScriptFile(const char *);
static void pmdie(SIGNAL_ARGS);
static void reaper(SIGNAL_ARGS);
static void sigusr1_handler(SIGNAL_ARGS);
@@ -1856,6 +1858,21 @@
errno = save_errno;
}
+/*
+ * RunAtexitScriptFile -- run configured atexit script.
+ */
+static void
+RunAtexitScriptFile(const char *shuttype)
+{
+ if (enable_atexit_script_file && atexit_script_file)
+ {
+ int l = strlen(atexit_script_file) +
strlen(shuttype) + 2;
+ char buf[l];
+
+ sprintf(buf, "%s %s", atexit_script_file, shuttype);
+ system(buf);
+ }
+}
/*
* pmdie -- signal handler for processing various postmaster signals.
@@ -1885,6 +1902,7 @@
Shutdown = SmartShutdown;
ereport(LOG,
(errmsg("received smart shutdown
request")));
+ RunAtexitScriptFile("smart");
/*
* We won't wait out an autovacuum iteration ...
@@ -1931,6 +1949,7 @@
Shutdown = FastShutdown;
ereport(LOG,
(errmsg("received fast shutdown
request")));
+ RunAtexitScriptFile("fast");
if (DLGetHead(BackendList) || AutoVacPID != 0)
{
@@ -1978,6 +1997,8 @@
*/
ereport(LOG,
(errmsg("received immediate shutdown
request")));
+ RunAtexitScriptFile("immediate");
+
if (StartupPID != 0)
kill(StartupPID, SIGQUIT);
if (BgWriterPID != 0)
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.301
diff -u -r1.301 guc.c
--- src/backend/utils/misc/guc.c 22 Nov 2005 18:17:26 -0000 1.301
+++ src/backend/utils/misc/guc.c 10 Dec 2005 18:28:24 -0000
@@ -145,6 +145,7 @@
/*
* GUC option variables that are exported from this module
*/
+bool enable_atexit_script_file = false;
#ifdef USE_ASSERT_CHECKING
bool assert_enabled = true;
#endif
@@ -181,6 +182,7 @@
char *HbaFileName;
char *IdentFileName;
char *external_pid_file;
+char *atexit_script_file;
int tcp_keepalives_idle;
int tcp_keepalives_interval;
@@ -391,6 +393,14 @@
static struct config_bool ConfigureNamesBool[] =
{
{
+ {"enable_atexit_script_file", PGC_POSTMASTER, FILE_LOCATIONS,
+ gettext_noop("Enables usage of atexit script file on
postmaster shutdown."),
+ NULL
+ },
+ &enable_atexit_script_file,
+ false, NULL, NULL
+ },
+ {
{"enable_seqscan", PGC_USERSET, QUERY_TUNING_METHOD,
gettext_noop("Enables the planner's use of
sequential-scan plans."),
NULL
@@ -2119,6 +2129,16 @@
NULL, assign_canonical_path, NULL
},
+ {
+ {"atexit_script_file", PGC_POSTMASTER, FILE_LOCATIONS,
+ gettext_noop("Executes specified atexit script file on
database shutdown."),
+ NULL,
+ GUC_SUPERUSER_ONLY
+ },
+ &atexit_script_file,
+ NULL, assign_canonical_path, NULL
+ },
+
/* End-of-list marker */
{
{NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL
@@ -2856,6 +2876,47 @@
free(configdir);
+ /*
+ * Access permission check for atexit_script_file.
+ */
+ if (enable_atexit_script_file)
+ {
+ int xmask;
+
+ if (!atexit_script_file)
+ {
+ write_stderr("You must specify an atexit script file
when you "
+ "enabled its usage.\n");
+ return false;
+ }
+ else if (stat(atexit_script_file, &stat_buf) != 0)
+ {
+ write_stderr("%s cannot access atexit script file to
run on server "
+ "shutdown.\n\"%s\": %s\n",
+ progname, atexit_script_file,
strerror(errno));
+ return false;
+ }
+
+ /*
+ * FIXME: Below execution masks require editing
+ * (like S_IXROOT) for some platforms (like Netware).
+ */
+ if (stat_buf.st_uid == getuid())
+ xmask = S_IXUSR;
+ else if (stat_buf.st_uid == getgid())
+ xmask = S_IXGRP;
+ else
+ xmask = S_IXOTH;
+
+ if ((stat_buf.st_mode&xmask) == 0 || S_ISDIR(stat_buf.st_mode))
+ {
+ write_stderr("%s doesn't have execution permissions on
script "
+ "file to run on server
shutdown.\n\"%s\": %s\n",
+ progname, atexit_script_file,
strerror(errno));
+ return false;
+ }
+ }
+
return true;
}
Index: src/backend/utils/misc/postgresql.conf.sample
===================================================================
RCS file:
/projects/cvsroot/pgsql/src/backend/utils/misc/postgresql.conf.sample,v
retrieving revision 1.171
diff -u -r1.171 postgresql.conf.sample
--- src/backend/utils/misc/postgresql.conf.sample 17 Nov 2005 22:14:54
-0000 1.171
+++ src/backend/utils/misc/postgresql.conf.sample 10 Dec 2005 18:28:25
-0000
@@ -39,6 +39,9 @@
# If external_pid_file is not explicitly set, no extra pid file is written.
#external_pid_file = '(none)' # write an extra pid file
+# atexit script file to run on database shutdown.
+#enable_atexit_script_file = off
+#atexit_script_file = '(none)'
#---------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
Index: src/include/utils/guc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/guc.h,v
retrieving revision 1.63
diff -u -r1.63 guc.h
--- src/include/utils/guc.h 15 Oct 2005 02:49:46 -0000 1.63
+++ src/include/utils/guc.h 10 Dec 2005 19:14:00 -0000
@@ -103,6 +103,7 @@
#define GUC_QUALIFIER_SEPARATOR '.'
/* GUC vars that are actually declared in guc.c, rather than elsewhere */
+extern bool enable_atexit_script_file;
extern bool log_duration;
extern bool Debug_print_plan;
extern bool Debug_print_parse;
@@ -133,6 +134,7 @@
extern char *HbaFileName;
extern char *IdentFileName;
extern char *external_pid_file;
+extern char *atexit_script_file;
extern int tcp_keepalives_idle;
extern int tcp_keepalives_interval;
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?
http://archives.postgresql.org