Greetings,
I've discovered that PostgreSQL on Windows has a handle inheritance
problem that prevents clean restarts after the postmaster is killed
while child processes are running.
The issue is that Windows handles (files, sockets, pipes, shared memory)
are inheritable by default. When backends spawn child processes
archive_command, COPY TO PROGRAM, etc.—those children inherit all the
backend's handles. Windows uses reference counting, so inherited handles
keep resources alive even after the owning process exits.
I reproduced this with sockets:
1. Started PostgreSQL on port 6565
2. Connected with psql and ran:
\copy (select 1) to program 'powershell -Command "Start-Sleep 300"'
3. Used Sysinternals handle64.exe to examine handles:
- PowerShell had inherited socket handles (\Device\Afd)
- Same handle values in both processes (proving inheritance, not
separate opens)
4. Killed the postmaster
5. netstat showed port 6565 still LISTENING on the dead postmaster PID
6. Restart failed: "Address already in use"
7. Port only freed after killing PowerShell
The socket fix adds WSA_FLAG_NO_HANDLE_INHERIT to WSASocket() in
pgwin32_socket(), and calls SetHandleInformation() in
BackendInitialize() to mark the inherited client socket non-inheritable.
The latter is needed because handles passed to children become
inheritable again on Windows.
TAP test included that verifies the port is freed immediately after
postmaster exit rather than remaining in a zombie state.
The problem affects multiple handle types:
Files: https://commitfest.postgresql.org/patch/6197/
Sockets: Fixed by attached patch
Pipes: Not yet addressed
Shared memory: Not yet addressed (causes "pre-existing shared memory
block" errors)
Patches for pipes and shared memory will follow over the next couple of
days.
--
Bryan Green
EDB: https://www.enterprisedb.com