Skip to content

Commit 2ebc3be

Browse files
committed
initscript: don't block system start-up by default
This commit should resolve complaints against pg_ctl -w usage from initscript (see rhbz#800534 for more info). The problem is that pg_ctl -w can block whole system startup too long - until the server is fully ready to accept connections. The commit 8c7b2cd thus invented basically bad approach for initscript. Now, the "-w" option is used only if the PGSTARTWAIT is explicitly set to 1 by administrator. In this case, the PGSTARTTIMEOUT numeric value (in seconds) is respected (or limit 30 seconds is set by default). Otherwise, if PGSTARTWAIT is unset (default), initscript keeps checking only for the pidfile existence (at most PGSTARTTIMEOUT seconds). The hardwired 'sleep 2' command (activated before 8c7b2cd commit) is still not used - regular/default system startup should be a bit faster than before. * postgresql.init.in (start): Fix handling of PGDATA, PGPORT, PGOPTS and PGSCLS - to respect special quoting characters inside, we should escape the strings before passing those to command evaluation. Use printf %q as we use bash and we don't care too much about portability. Also, don't call postgresql-ctl with -w option if PGSTARTWAIT is empty or undefined. Implement pidfile polling for the cases PGSTARTWAIT is unset. Return success faster if server is already running. ($PGSTARTWAIT): New env variable. * postgresql-ctl.in: Don't parse $PGPORT into -o option as it is not needed. Unset PGPORT if the variable is empty - postgres server would fail with empty value. * configure.ac: Bump version to 3.3. * NEWS: Document bugfixes.
1 parent d529834 commit 2ebc3be

File tree

4 files changed

+75
-22
lines changed

4 files changed

+75
-22
lines changed

NEWS

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22

3-
New in 3.1 version
3+
Bugfixes in 3.3 version
4+
5+
* The PGPORT/PGOPTS/.. variables should be correctly forwarded down from
6+
the initstcript into postgresql-ctl.
7+
8+
* Initscript's 'start' function again reports success if daemon is already
9+
running.
10+
11+
New in 3.3 version
12+
13+
* New option PGSTARTWAIT for sysvinit systems.
14+
15+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16+
17+
New in 3.2 version
418

519
* The --new-systemd-unit option now cleans the recently created drop-in
620
directory if something goes wrong.

configure.ac

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Use the MAJ.MIN[~SUFF]. Note that X.X > X.X~SUFF!
2-
AC_INIT([postgresql-setup], [3.2], [[email protected]])
2+
AC_INIT([postgresql-setup], [3.3], [[email protected]])
33
AC_CONFIG_AUX_DIR(auxdir)
44
config_aux_dir=auxdir
55
AC_SUBST([config_aux_dir])

postgresql-ctl.in

+6-5
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@
2222
# such extension, not the server itself).
2323
test -n "$PGSCLS" && source scl_source enable $PGSCLS
2424

25-
port=()
26-
if test "$1" = "start" && test -n "$PGPORT"; then
27-
port=(-o "-p $PGPORT")
28-
fi
25+
opts=()
26+
test "$1" = "start" && test -n "$PGOPTS" && opts=(-o "$PGOPTS")
2927

30-
exec @bindir@/pg_ctl "$@" "${port[@]}"
28+
# cleanup possibly empty PGPORT
29+
test -z "$PGPORT" && unset PGPORT
30+
31+
exec @bindir@/pg_ctl "$@" "${opts[@]}"

postgresql.init.in

+53-15
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,26 @@ start()
117117
# The maximum waiting time PGSTARTTIMEOUT is set to 30 second to not hold
118118
# the system too long. See `man pg_ctl & -w option`. This is not issue in
119119
# case of systemd.
120+
#
121+
# PGSTARTWAIT turns on waiting for server to become fully ready to accept
122+
# connection.
123+
124+
# clean the variable if not set to 1
125+
test x1 != x"$PGSTARTWAIT" && PGSTARTWAIT=
126+
127+
# success if already started (pg_ctl -w could fail later)
128+
status -p "$pidfile" postgres &>/dev/null && {
129+
success "$PSQL_START"
130+
echo
131+
exit 0
132+
}
120133

121134
run_cmd_as_dbadmin "\
122-
PGSCLS='${PGSCLS}' \
123-
@libexecdir@/postgresql-ctl start -D ${PGDATA} -s \
124-
-w -t ${PGSTARTTIMEOUT-30}" \
135+
PGSCLS=$(printf %q "$PGSCLS") \
136+
PGOPTS=$(printf %q "$PGOPTS") \
137+
PGPORT=$(printf %q "$PGPORT") \
138+
@libexecdir@/postgresql-ctl start -D $(printf %q "$PGDATA") -s \
139+
${PGSTARTWAIT:+-w -t ${PGSTARTTIMEOUT:-30}}" \
125140
"$PGLOG" "$PGLOG"
126141

127142
if test $? -ne 0; then
@@ -131,18 +146,41 @@ start()
131146
return
132147
fi
133148

134-
pid=`head -n 1 "$PGDATA/postmaster.pid" 2>/dev/null`
135-
if [ "x$pid" != x ]
136-
then
137-
success "$PSQL_START"
138-
touch "$lockfile"
139-
echo $pid > "$pidfile"
140-
echo
141-
else
142-
failure "$PSQL_START"
143-
echo
144-
script_result=1
145-
fi
149+
# pg_ctl succeed, now recognize the pid number
150+
151+
pid=
152+
if test x1 != x"$PGSTARTWAIT" ; then
153+
# We don't wait for the full postgresql server start. In this case,
154+
# wait for pidfile creation only. This should take _very_ short time in
155+
# most cases but on highly overloaded machines - several seconds may
156+
# not be enough. See rhbz#800534 and rhbz#1188942 for more info.
157+
# Original waiting implementation by Jozef Mlích.
158+
159+
decounter=${PGSTARTTIMEOUT:-30}
160+
while test "$decounter" -ge 0; do
161+
pid=$(head -n 1 "$PGDATA/postmaster.pid" 2>/dev/null)
162+
163+
test "x$pid" != x && break
164+
165+
# pidfile does not exist yet, wait a sec more
166+
decounter=$(( decounter - 1 ))
167+
sleep 1
168+
done
169+
else
170+
# pg_ctl -w succeed, pidfile must exist if everything is OK
171+
pid=$(head -n 1 "$PGDATA/postmaster.pid" 2>/dev/null)
172+
fi
173+
174+
if test "x$pid" != x; then
175+
success "$PSQL_START"
176+
touch "$lockfile"
177+
echo "$pid" > "$pidfile"
178+
echo
179+
else
180+
failure "$PSQL_START"
181+
echo
182+
script_result=1
183+
fi
146184
}
147185

148186
stop()

0 commit comments

Comments
 (0)