mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +03:00
Adjust postmaster to recognize that a lockfile containing its parent's PID
must be stale. Tweak example startup scripts to not use pg_ctl but launch the postmaster directly, thereby ensuring that only the postmaster's direct parent shell will be a postgres-owned process. In combination these should fix the longstanding problem of the postmaster sometimes refusing to start during reboot because it thinks the old lockfile is not stale.
This commit is contained in:
@ -48,7 +48,7 @@ prefix="/usr/local/pgsql"
|
|||||||
# Data directory
|
# Data directory
|
||||||
PGDATA="/usr/local/pgsql/data"
|
PGDATA="/usr/local/pgsql/data"
|
||||||
|
|
||||||
# Who to run pg_ctl as, should be "postgres".
|
# Who to run the postmaster as, usually "postgres". (NOT "root")
|
||||||
PGUSER="postgres"
|
PGUSER="postgres"
|
||||||
|
|
||||||
# the logfile path and name (NEEDS to be writeable by PGUSER)
|
# the logfile path and name (NEEDS to be writeable by PGUSER)
|
||||||
@ -68,8 +68,13 @@ ROTATESEC="604800"
|
|||||||
# The path that is to be used for the script
|
# The path that is to be used for the script
|
||||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||||
|
|
||||||
# What to use to start up the postmaster
|
# What to use to start up the postmaster (we do NOT use pg_ctl for this,
|
||||||
DAEMON="$prefix/bin/pg_ctl"
|
# as it adds no value and can cause the postmaster to misrecognize a stale
|
||||||
|
# lock file)
|
||||||
|
DAEMON="$prefix/bin/postmaster"
|
||||||
|
|
||||||
|
# What to use to shut down the postmaster
|
||||||
|
PGCTL="$prefix/bin/pg_ctl"
|
||||||
|
|
||||||
# The apache log rotation utility
|
# The apache log rotation utility
|
||||||
LOGUTIL="/usr/sbin/rotatelogs"
|
LOGUTIL="/usr/sbin/rotatelogs"
|
||||||
@ -80,27 +85,28 @@ StartService () {
|
|||||||
if [ "${POSTGRESQLSERVER:=-NO-}" = "-YES-" ]; then
|
if [ "${POSTGRESQLSERVER:=-NO-}" = "-YES-" ]; then
|
||||||
ConsoleMessage "Starting PostgreSQL database server"
|
ConsoleMessage "Starting PostgreSQL database server"
|
||||||
if [ "${ROTATELOGS}" = "1" ]; then
|
if [ "${ROTATELOGS}" = "1" ]; then
|
||||||
sudo -u $PGUSER sh -c "${DAEMON} start -D ${PGDATA} -s | ${LOGUTIL} ${PGLOG} ${ROTATESEC} &"
|
sudo -u $PGUSER sh -c "${DAEMON} -D '${PGDATA}' | ${LOGUTIL} '${PGLOG}' ${ROTATESEC} &"
|
||||||
else
|
else
|
||||||
sudo -u $PGUSER $DAEMON start -D "$PGDATA" -s -l $PGLOG
|
sudo -u $PGUSER sh -c "${DAEMON} -D '${PGDATA}' &" >>$PGLOG 2>&1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
StopService () {
|
StopService () {
|
||||||
ConsoleMessage "Stopping PostgreSQL database server"
|
ConsoleMessage "Stopping PostgreSQL database server"
|
||||||
sudo -u $PGUSER $DAEMON stop -D "$PGDATA" -s -m fast
|
sudo -u $PGUSER $PGCTL stop -D "$PGDATA" -s -m fast
|
||||||
}
|
}
|
||||||
|
|
||||||
RestartService () {
|
RestartService () {
|
||||||
if [ "${POSTGRESQLSERVER:=-NO-}" = "-YES-" ]; then
|
if [ "${POSTGRESQLSERVER:=-NO-}" = "-YES-" ]; then
|
||||||
ConsoleMessage "Restarting PostgreSQL database server"
|
ConsoleMessage "Restarting PostgreSQL database server"
|
||||||
|
# should match StopService:
|
||||||
|
sudo -u $PGUSER $PGCTL stop -D "$PGDATA" -s -m fast
|
||||||
|
# should match StartService:
|
||||||
if [ "${ROTATELOGS}" = "1" ]; then
|
if [ "${ROTATELOGS}" = "1" ]; then
|
||||||
# StopService
|
sudo -u $PGUSER sh -c "${DAEMON} -D '${PGDATA}' | ${LOGUTIL} '${PGLOG}' ${ROTATESEC} &"
|
||||||
# StartService
|
|
||||||
sudo -u $PGUSER sh -c "${DAEMON} restart -D ${PGDATA} -s -m fast | ${LOGUTIL} ${PGLOG} ${ROTATESEC} &"
|
|
||||||
else
|
else
|
||||||
sudo -u $PGUSER $DAEMON restart -D "$PGDATA" -s -m fast
|
sudo -u $PGUSER sh -c "${DAEMON} -D '${PGDATA}' &" >>$PGLOG 2>&1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
StopService
|
StopService
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# Created through merger of the Linux start script by Ryan Kirkpatrick
|
# Created through merger of the Linux start script by Ryan Kirkpatrick
|
||||||
# and the script in the FreeBSD ports collection.
|
# and the script in the FreeBSD ports collection.
|
||||||
|
|
||||||
# $PostgreSQL: pgsql/contrib/start-scripts/freebsd,v 1.3 2003/11/29 19:51:35 pgsql Exp $
|
# $PostgreSQL: pgsql/contrib/start-scripts/freebsd,v 1.4 2004/10/01 18:30:21 tgl Exp $
|
||||||
|
|
||||||
## EDIT FROM HERE
|
## EDIT FROM HERE
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ prefix=/usr/local/pgsql
|
|||||||
# Data directory
|
# Data directory
|
||||||
PGDATA="/usr/local/pgsql/data"
|
PGDATA="/usr/local/pgsql/data"
|
||||||
|
|
||||||
# Who to run pg_ctl as, should be "postgres".
|
# Who to run the postmaster as, usually "postgres". (NOT "root")
|
||||||
PGUSER=postgres
|
PGUSER=postgres
|
||||||
|
|
||||||
# Where to keep a log file
|
# Where to keep a log file
|
||||||
@ -27,24 +27,31 @@ PGLOG="$PGDATA/serverlog"
|
|||||||
# The path that is to be used for the script
|
# The path that is to be used for the script
|
||||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||||
|
|
||||||
# What to use to start up the postmaster
|
# What to use to start up the postmaster (we do NOT use pg_ctl for this,
|
||||||
DAEMON="$prefix/bin/pg_ctl"
|
# as it adds no value and can cause the postmaster to misrecognize a stale
|
||||||
|
# lock file)
|
||||||
|
DAEMON="$prefix/bin/postmaster"
|
||||||
|
|
||||||
|
# What to use to shut down the postmaster
|
||||||
|
PGCTL="$prefix/bin/pg_ctl"
|
||||||
|
|
||||||
|
# Only start if we can find the postmaster.
|
||||||
test -x "$DAEMON" || exit 0
|
test -x "$DAEMON" || exit 0
|
||||||
|
|
||||||
case $1 in
|
case $1 in
|
||||||
start)
|
start)
|
||||||
su -l $PGUSER -c "$DAEMON start -D '$PGDATA' -s -l $PGLOG"
|
su -l $PGUSER -c "$DAEMON -D '$PGDATA' &" >>$PGLOG 2>&1
|
||||||
echo -n ' postgresql'
|
echo -n ' postgresql'
|
||||||
;;
|
;;
|
||||||
stop)
|
stop)
|
||||||
su -l $PGUSER -c "$DAEMON stop -D '$PGDATA' -s -m fast"
|
su -l $PGUSER -c "$PGCTL stop -D '$PGDATA' -s -m fast"
|
||||||
;;
|
;;
|
||||||
restart)
|
restart)
|
||||||
su -l $PGUSER -c "$DAEMON restart -D '$PGDATA' -s -m fast"
|
su -l $PGUSER -c "$PGCTL stop -D '$PGDATA' -s -m fast -w"
|
||||||
|
su -l $PGUSER -c "$DAEMON -D '$PGDATA' &" >>$PGLOG 2>&1
|
||||||
;;
|
;;
|
||||||
status)
|
status)
|
||||||
su -l $PGUSER -c "$DAEMON status -D '$PGDATA'"
|
su -l $PGUSER -c "$PGCTL status -D '$PGDATA'"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# Print help
|
# Print help
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
# Original author: Ryan Kirkpatrick <pgsql@rkirkpat.net>
|
# Original author: Ryan Kirkpatrick <pgsql@rkirkpat.net>
|
||||||
|
|
||||||
# $PostgreSQL: pgsql/contrib/start-scripts/linux,v 1.6 2003/11/29 19:51:36 pgsql Exp $
|
# $PostgreSQL: pgsql/contrib/start-scripts/linux,v 1.7 2004/10/01 18:30:21 tgl Exp $
|
||||||
|
|
||||||
## EDIT FROM HERE
|
## EDIT FROM HERE
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ prefix=/usr/local/pgsql
|
|||||||
# Data directory
|
# Data directory
|
||||||
PGDATA="/usr/local/pgsql/data"
|
PGDATA="/usr/local/pgsql/data"
|
||||||
|
|
||||||
# Who to run pg_ctl as, should be "postgres".
|
# Who to run the postmaster as, usually "postgres". (NOT "root")
|
||||||
PGUSER=postgres
|
PGUSER=postgres
|
||||||
|
|
||||||
# Where to keep a log file
|
# Where to keep a log file
|
||||||
@ -54,38 +54,44 @@ fi
|
|||||||
# The path that is to be used for the script
|
# The path that is to be used for the script
|
||||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||||
|
|
||||||
# What to use to start up the postmaster
|
# What to use to start up the postmaster (we do NOT use pg_ctl for this,
|
||||||
DAEMON="$prefix/bin/pg_ctl"
|
# as it adds no value and can cause the postmaster to misrecognize a stale
|
||||||
|
# lock file)
|
||||||
|
DAEMON="$prefix/bin/postmaster"
|
||||||
|
|
||||||
|
# What to use to shut down the postmaster
|
||||||
|
PGCTL="$prefix/bin/pg_ctl"
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Only start if we can find pg_ctl.
|
# Only start if we can find the postmaster.
|
||||||
test -f $DAEMON || exit 0
|
test -x $DAEMON || exit 0
|
||||||
|
|
||||||
# Parse command line parameters.
|
# Parse command line parameters.
|
||||||
case $1 in
|
case $1 in
|
||||||
start)
|
start)
|
||||||
$ECHO_N "Starting PostgreSQL: "$ECHO_C
|
$ECHO_N "Starting PostgreSQL: "$ECHO_C
|
||||||
su - $PGUSER -c "$DAEMON start -D '$PGDATA' -s -l $PGLOG"
|
su - $PGUSER -c "$DAEMON -D '$PGDATA' &" >>$PGLOG 2>&1
|
||||||
echo "ok"
|
echo "ok"
|
||||||
;;
|
;;
|
||||||
stop)
|
stop)
|
||||||
echo -n "Stopping PostgreSQL: "
|
echo -n "Stopping PostgreSQL: "
|
||||||
su - $PGUSER -c "$DAEMON stop -D '$PGDATA' -s -m fast"
|
su - $PGUSER -c "$PGCTL stop -D '$PGDATA' -s -m fast"
|
||||||
echo "ok"
|
echo "ok"
|
||||||
;;
|
;;
|
||||||
restart)
|
restart)
|
||||||
echo -n "Restarting PostgreSQL: "
|
echo -n "Restarting PostgreSQL: "
|
||||||
su - $PGUSER -c "$DAEMON restart -D '$PGDATA' -s -m fast -l $PGLOG"
|
su - $PGUSER -c "$PGCTL stop -D '$PGDATA' -s -m fast -w"
|
||||||
|
su - $PGUSER -c "$DAEMON -D '$PGDATA' &" >>$PGLOG 2>&1
|
||||||
echo "ok"
|
echo "ok"
|
||||||
;;
|
;;
|
||||||
reload)
|
reload)
|
||||||
echo -n "Reload PostgreSQL: "
|
echo -n "Reload PostgreSQL: "
|
||||||
su - $PGUSER -c "$DAEMON reload -D '$PGDATA' -s"
|
su - $PGUSER -c "$PGCTL reload -D '$PGDATA' -s"
|
||||||
echo "ok"
|
echo "ok"
|
||||||
;;
|
;;
|
||||||
status)
|
status)
|
||||||
su - $PGUSER -c "$DAEMON status -D '$PGDATA'"
|
su - $PGUSER -c "$PGCTL status -D '$PGDATA'"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# Print help
|
# Print help
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.132 2004/08/29 05:06:50 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.133 2004/10/01 18:30:25 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -526,10 +526,22 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
|||||||
/*
|
/*
|
||||||
* Check to see if the other process still exists
|
* Check to see if the other process still exists
|
||||||
*
|
*
|
||||||
|
* If the PID in the lockfile is our own PID or our parent's PID,
|
||||||
|
* then the file must be stale (probably left over from a previous
|
||||||
|
* system boot cycle). We need this test because of the likelihood
|
||||||
|
* that a reboot will assign exactly the same PID as we had in the
|
||||||
|
* previous reboot. Also, if there is just one more process launch
|
||||||
|
* in this reboot than in the previous one, the lockfile might mention
|
||||||
|
* our parent's PID. We can reject that since we'd never be launched
|
||||||
|
* directly by a competing postmaster. We can't detect grandparent
|
||||||
|
* processes unfortunately, but if the init script is written carefully
|
||||||
|
* then all but the immediate parent shell will be root-owned processes
|
||||||
|
* and so the kill test will fail with EPERM.
|
||||||
|
*
|
||||||
* Normally kill() will fail with ESRCH if the given PID doesn't
|
* Normally kill() will fail with ESRCH if the given PID doesn't
|
||||||
* exist. BeOS returns EINVAL for some silly reason, however.
|
* exist. BeOS returns EINVAL for some silly reason, however.
|
||||||
*/
|
*/
|
||||||
if (other_pid != my_pid)
|
if (other_pid != my_pid && other_pid != getppid())
|
||||||
{
|
{
|
||||||
if (kill(other_pid, 0) == 0 ||
|
if (kill(other_pid, 0) == 0 ||
|
||||||
(errno != ESRCH
|
(errno != ESRCH
|
||||||
@ -544,12 +556,16 @@ CreateLockFile(const char *filename, bool amPostmaster,
|
|||||||
errmsg("lock file \"%s\" already exists",
|
errmsg("lock file \"%s\" already exists",
|
||||||
filename),
|
filename),
|
||||||
isDDLock ?
|
isDDLock ?
|
||||||
errhint("Is another %s (PID %d) running in data directory \"%s\"?",
|
(encoded_pid < 0 ?
|
||||||
(encoded_pid < 0 ? "postgres" : "postmaster"),
|
errhint("Is another postgres (PID %d) running in data directory \"%s\"?",
|
||||||
(int) other_pid, refName) :
|
(int) other_pid, refName) :
|
||||||
errhint("Is another %s (PID %d) using socket file \"%s\"?",
|
errhint("Is another postmaster (PID %d) running in data directory \"%s\"?",
|
||||||
(encoded_pid < 0 ? "postgres" : "postmaster"),
|
(int) other_pid, refName)) :
|
||||||
(int) other_pid, refName)));
|
(encoded_pid < 0 ?
|
||||||
|
errhint("Is another postgres (PID %d) using socket file \"%s\"?",
|
||||||
|
(int) other_pid, refName) :
|
||||||
|
errhint("Is another postmaster (PID %d) using socket file \"%s\"?",
|
||||||
|
(int) other_pid, refName))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user