On Wed, Jul 16, 2025 at 11:11 AM Andres Freund <and...@anarazel.de> wrote: > If one modifies libpq to use openssl readahead (which does result in speedups, > because otherwise openssl think it's useful to do lots of 5 byte reads from > the socket), I see occasional hangs in libpq.
Now that is a very interesting coincidence, because the patch I'm working on is about to add an assertion that readahead is turned *off*. :D Based on my understanding of [1], readahead makes this overall problem much worse by opportunistically slurping bytes off the wire and doing absolutely nothing with them until you call SSL_read() enough times to finally get to them. It would even hide those bytes from the pending count: > Therefore, it is possible for no more bytes to be readable from the > underlying BIO (because OpenSSL has already read them) and for > SSL_pending() to return 0, even though readable application data bytes > are available (because the data is in unprocessed buffered records). That seems like the polar opposite of what we want. If clients are polling on the raw socket, those pending bytes must be accounted for. > It does seem ... weird ... that pqGetCopyData3() just processes whatever is > already in the libpq buffer and then waits for the socket to become readable, > before ever calling pqReadData(). What guarantees, even without the change > above, that a) there's no pending data inside openssl b) that we're not > waiting for a write? (a) is the bug discussed here, AFAICT? I have not considered (b) yet, but that seems like a separate problem. > If I make pqGetCopyData3() call pqReadData() before the pqWait() and continue > if it returns 1, the hang vanishes. Sure, but that's cheating. I think I'd expect that adding extra "unnecessary" reads would help cover up the problem that readahead has caused. > What are the limits for the maximum amount of data this could make us buffer > in addition to what we are buffering right now? I still need to make sure, but I believe it should be an additional 16k due to the current limits on GSS token sizes and TLS record sizes. In normal operation, I think we basically immediately double the input buffer sizes (which start at 16k) as soon as a long message comes in. So that order of magnitude didn't immediately seem worrisome to me. > It's not entirely obvious to > me that a loop around pqReadData() as long as there is pending data couldn't > make us buffer a lot of data. FWIW, I'm not planning to loop around it; I'm planning to add a pgsecure_* primitive that drains whatever the transport is holding onto. > Do you have a WIP patch? I'm working on one now. --Jacob [1] https://docs.openssl.org/3.5/man3/SSL_pending/#synopsis