On 11/5/2025 11:06 PM, Bryan Green wrote:
> 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.
>
Incorrect extension on the patch. Attached is the correct patch.
--
Bryan Green
EDB: https://www.enterprisedb.com