BUG #14199: The pg_ctl status check on server start is not compatible with the silent_mode=on

From: sobomax(at)freebsd(dot)org
To: pgsql-bugs(at)postgresql(dot)org
Subject: BUG #14199: The pg_ctl status check on server start is not compatible with the silent_mode=on
Date: 2016-06-18 04:28:12
Message-ID: 20160618042812.5798.85609@wrigleys.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs pgsql-hackers

The following bug has been logged on the website:

Bug reference: 14199
Logged by: Maksym Sobolyev
Email address: sobomax(at)freebsd(dot)org
PostgreSQL version: 9.1.22
Operating system: FreeBSD 10.3-RELEASE amd64
Description:

There is a problem with pg_ctl when it tries to start server with the
"silent_mode=on" option enabled in postgresql.conf. Specifically, this
option causes postgres to fork once more after start. There are two problems
caused by that:

1. The pm_pid recorded by the pg_ctl when doing fork+execve no longer
matches the PID in the postmaster.pid file. This causes pg_ctl bail out
immediately.

2. Method that pg_ctl uses to poll if postgres exited prematurely no longer
works. In POSIX "child of my child is not my child", therefore it is
impossible to waitpid() on that process even if we use a correct PID from
the postmaster.pid file, while waitpid() on the original process would cause
race condition, since that process just does fork() and exit, so by the time
when real postgres has a chance to fully populate postmaster.pid it might
already be gone.

Attached patch fixes that issue by changing the way pg_ctl polls on the
child status. Instead of using waitpid(), which as described above could not
work even in principle for the "grand-children" processes, we create a
socketpair (i.e. pipe) one end of which is then passed into forked pg_ctl
and hence inherited by the postgres itself after execve.

In the unlikely event of postgres exiting prematurely that pipe would get
closed by the kernel and so that the pg_ctl would get EOF trying to do
non-blocking read on its own end, thereby being able to bail out quickly
instead of waiting for the timeout to happen. This should work nicely no
matter how many times child forks after execve().

This problem is exposed by the fact that FreeBSD port has that option set in
its default server configuration file for the version 9.1 .

https://svnweb.freebsd.org/ports/head/databases/postgresql91-server/files/patch-src%3Abackend%3Autils%3Amisc%3Apostgresql.conf.sample?annotate=340725

For some reason it was not a problem until recently. I think it might be
brought into the limelight by some internal changes in the PG's handling of
the said option.

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Maxim Sobolev 2016-06-18 04:33:29 BUG #14199: The pg_ctl status check on server start is not compatible with the silent_mode=on
Previous Message Martín Marqués 2016-06-18 00:27:08 Re: pg_dump doesn't dump new objects created in schemas from extensions

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2016-06-18 04:36:12 Re: pgsql: Try again to fix the way the scanjoin_target is used with partia
Previous Message Josh Berkus 2016-06-18 04:20:06 Re: 10.0