Add support for systemd service notifications

Insert sd_notify() calls at server start and stop for integration with
systemd.  This allows the use of systemd service units of type "notify",
which greatly simplifies the systemd configuration.

Reviewed-by: Pavel Stěhule <pavel.stehule@gmail.com>
This commit is contained in:
Peter Eisentraut 2015-11-17 06:46:17 -05:00
parent ac7238dc0f
commit 7d17e683fc
8 changed files with 147 additions and 0 deletions

49
configure vendored
View File

@ -709,6 +709,7 @@ with_libxml
XML2_CONFIG
UUID_EXTRA_OBJS
with_uuid
with_systemd
with_selinux
with_openssl
krb_srvtab
@ -830,6 +831,7 @@ with_ldap
with_bonjour
with_openssl
with_selinux
with_systemd
with_readline
with_libedit_preferred
with_uuid
@ -1518,6 +1520,7 @@ Optional Packages:
--with-bonjour build with Bonjour support
--with-openssl build with OpenSSL support
--with-selinux build with SELinux support
--with-systemd build with systemd support
--without-readline do not use GNU Readline nor BSD Libedit for editing
--with-libedit-preferred
prefer BSD Libedit over GNU Readline
@ -5694,6 +5697,41 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_selinux" >&5
$as_echo "$with_selinux" >&6; }
#
# Systemd
#
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with systemd support" >&5
$as_echo_n "checking whether to build with systemd support... " >&6; }
# Check whether --with-systemd was given.
if test "${with_systemd+set}" = set; then :
withval=$with_systemd;
case $withval in
yes)
$as_echo "#define USE_SYSTEMD 1" >>confdefs.h
;;
no)
:
;;
*)
as_fn_error $? "no argument expected for --with-systemd option" "$LINENO" 5
;;
esac
else
with_systemd=no
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_systemd" >&5
$as_echo "$with_systemd" >&6; }
#
# Readline
#
@ -10473,6 +10511,17 @@ fi
done
fi
if test "$with_systemd" = yes ; then
ac_fn_c_check_header_mongrel "$LINENO" "systemd/sd-daemon.h" "ac_cv_header_systemd_sd_daemon_h" "$ac_includes_default"
if test "x$ac_cv_header_systemd_sd_daemon_h" = xyes; then :
else
as_fn_error $? "header file <systemd/sd-daemon.h> is required for systemd support" "$LINENO" 5
fi
fi
if test "$with_libxml" = yes ; then

View File

@ -699,6 +699,15 @@ PGAC_ARG_BOOL(with, selinux, no, [build with SELinux support])
AC_SUBST(with_selinux)
AC_MSG_RESULT([$with_selinux])
#
# Systemd
#
AC_MSG_CHECKING([whether to build with systemd support])
PGAC_ARG_BOOL(with, systemd, no, [build with systemd support],
[AC_DEFINE([USE_SYSTEMD], 1, [Define to build with systemd support. (--with-systemd)])])
AC_SUBST(with_systemd)
AC_MSG_RESULT([$with_systemd])
#
# Readline
#
@ -1249,6 +1258,10 @@ if test "$with_pam" = yes ; then
[AC_MSG_ERROR([header file <security/pam_appl.h> or <pam/pam_appl.h> is required for PAM.])])])
fi
if test "$with_systemd" = yes ; then
AC_CHECK_HEADER(systemd/sd-daemon.h, [], [AC_MSG_ERROR([header file <systemd/sd-daemon.h> is required for systemd support])])
fi
if test "$with_libxml" = yes ; then
AC_CHECK_HEADER(libxml/parser.h, [], [AC_MSG_ERROR([header file <libxml/parser.h> is required for XML support])])
fi

View File

@ -812,6 +812,22 @@ su - postgres
</listitem>
</varlistentry>
<varlistentry>
<term><option>--with-systemd</option></term>
<listitem>
<para>
Build with support
for <application>systemd</application><indexterm><primary>systemd</primary></indexterm>
service notifications. This improves integration if the server binary
is started under <application>systemd</application> but has no impact
otherwise; see <xref linkend="server-start"> for more
information. <application>libsystemd</application> and the
associated header files need to be installed to be able to use this
option.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--without-readline</option></term>
<listitem>

View File

@ -369,6 +369,41 @@ fi
<filename>contrib/start-scripts/linux</filename> in the
<productname>PostgreSQL</productname> source distribution.
</para>
<para>
When using <application>systemd</application>, you can use the following
service unit file (e.g.,
at <filename>/etc/systemd/system/postgresql.service</filename>):<indexterm><primary>systemd</primary></indexterm>
<programlisting>
[Unit]
Description=PostgreSQL database server
Documentation=man:postgres(1)
[Service]
Type=notify
User=postgres
ExecStart=/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
TimeoutSec=0
[Install]
WantedBy=multi-user.target
</programlisting>
Using <literal>Type=notify</literal> requires that the server binary was
built with <literal>configure --with-systemd</literal>.
</para>
<para>
Consider carefully the timeout
setting. <application>systemd</application> has a default timeout of 90
seconds as of this writing and will kill a process that does not notify
readiness within that time. But a <productname>PostgreSQL</productname>
server that might have to perform crash recovery at startup could take
much longer to become ready. The suggested value of 0 disables the
timeout logic.
</para>
</listitem>
<listitem>

View File

@ -184,6 +184,7 @@ with_python = @with_python@
with_tcl = @with_tcl@
with_openssl = @with_openssl@
with_selinux = @with_selinux@
with_systemd = @with_systemd@
with_libxml = @with_libxml@
with_libxslt = @with_libxslt@
with_system_tzdata = @with_system_tzdata@

View File

@ -45,6 +45,10 @@ LIBS := $(filter-out -lpgport -lpgcommon, $(LIBS)) $(LDAP_LIBS_BE)
# The backend doesn't need everything that's in LIBS, however
LIBS := $(filter-out -lz -lreadline -ledit -ltermcap -lncurses -lcurses, $(LIBS))
ifeq ($(with_systemd),yes)
LIBS += -lsystemd
endif
##########################################################################
all: submake-libpgport submake-schemapg postgres $(POSTGRES_IMP)

View File

@ -87,6 +87,10 @@
#include <dns_sd.h>
#endif
#ifdef USE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
#ifdef HAVE_PTHREAD_IS_THREADED_NP
#include <pthread.h>
#endif
@ -2533,6 +2537,9 @@ pmdie(SIGNAL_ARGS)
Shutdown = SmartShutdown;
ereport(LOG,
(errmsg("received smart shutdown request")));
#ifdef USE_SYSTEMD
sd_notify(0, "STOPPING=1");
#endif
if (pmState == PM_RUN || pmState == PM_RECOVERY ||
pmState == PM_HOT_STANDBY || pmState == PM_STARTUP)
@ -2585,6 +2592,9 @@ pmdie(SIGNAL_ARGS)
Shutdown = FastShutdown;
ereport(LOG,
(errmsg("received fast shutdown request")));
#ifdef USE_SYSTEMD
sd_notify(0, "STOPPING=1");
#endif
if (StartupPID != 0)
signal_child(StartupPID, SIGTERM);
@ -2645,6 +2655,9 @@ pmdie(SIGNAL_ARGS)
Shutdown = ImmediateShutdown;
ereport(LOG,
(errmsg("received immediate shutdown request")));
#ifdef USE_SYSTEMD
sd_notify(0, "STOPPING=1");
#endif
TerminateChildren(SIGQUIT);
pmState = PM_WAIT_BACKENDS;
@ -2787,6 +2800,10 @@ reaper(SIGNAL_ARGS)
ereport(LOG,
(errmsg("database system is ready to accept connections")));
#ifdef USE_SYSTEMD
sd_notify(0, "READY=1");
#endif
continue;
}
@ -4916,6 +4933,11 @@ sigusr1_handler(SIGNAL_ARGS)
if (XLogArchivingAlways())
PgArchPID = pgarch_start();
#ifdef USE_SYSTEMD
if (!EnableHotStandby)
sd_notify(0, "READY=1");
#endif
pmState = PM_RECOVERY;
}
if (CheckPostmasterSignal(PMSIGNAL_BEGIN_HOT_STANDBY) &&
@ -4930,6 +4952,10 @@ sigusr1_handler(SIGNAL_ARGS)
ereport(LOG,
(errmsg("database system is ready to accept read only connections")));
#ifdef USE_SYSTEMD
sd_notify(0, "READY=1");
#endif
pmState = PM_HOT_STANDBY;
/* Some workers may be scheduled to start now */
StartWorkerNeeded = true;

View File

@ -833,6 +833,9 @@
/* Define to 1 to use Intel SSSE 4.2 CRC instructions with a runtime check. */
#undef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK
/* Define to build with systemd support. (--with-systemd) */
#undef USE_SYSTEMD
/* Define to select SysV-style semaphores. */
#undef USE_SYSV_SEMAPHORES