On Mon, Nov 22, 2021 at 8:19 AM Lars Kanis <l...@greiz-reinsdorf.de> wrote: > The other way around would be to make sure on the client side, that the > last message is retrieved before the RST packet arrives, so that no data > is lost. This works mostly well through the sync API of libpq, but with > the async API the trigger for data reception is outside of the scope of > libpq, so that there's no way to ensure recv() is called quick enough, > after the data was received but before RST arrives. On a local > client+server combination there is only a gap of 0.5 milliseconds or so. > I also didn't find a way to retrieve the enqueued data after RST > arrived. Maybe there's a nasty hack to retrieve the data afterwards, but > I didn't dig into assembly code and memory layout of Winsock internals.
Hmm. Well, if I understand how this works (and I'm not too familiar with this Windows code so I maybe I don't), the postmaster duplicates the socket into the child process (see {write,read}_inheritable_socket()) and then closes its own handle (see ServerLoop()'s call to StreamClose(port->sock)). What if the postmaster kept the socket open, and then closed its copy after the child exits? Then, I guess, maybe, Winsock socket state would live on with a non-zero reference count and be able to perform the proper graceful TCP shutdown dance, at least as long as the postmaster itself is up. Various other ideas: don't do that, but duplicate the socket back into the postmaster before exit, or into some other process, or rewrite PostgreSQL to use threads...