Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1so5w2-008Fr8-9a for pgsql-hackers@arkaria.postgresql.org; Tue, 10 Sep 2024 18:49:55 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1so5w1-000NKa-Sy for pgsql-hackers@arkaria.postgresql.org; Tue, 10 Sep 2024 18:49:53 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1so5w1-000NJx-IJ for pgsql-hackers@lists.postgresql.org; Tue, 10 Sep 2024 18:49:53 +0000 Received: from mail-oa1-x2a.google.com ([2001:4860:4864:20::2a]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1so5vx-000VXV-T1 for pgsql-hackers@lists.postgresql.org; Tue, 10 Sep 2024 18:49:51 +0000 Received: by mail-oa1-x2a.google.com with SMTP id 586e51a60fabf-277dd761926so3820212fac.2 for ; Tue, 10 Sep 2024 11:49:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; t=1725994189; x=1726598989; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=l3cC5iLIJ+SkbYQv9jHvsp4Eo6d4Ph7QZVRcGZLrLZs=; b=iU1qK9T+uwNlcJbQVCvYM1WM192TGXkvgaaeKcw8QUuLrUyGH5JqLCwdyPJ+EgqXy5 bGWJ0BhukgceZvtphJ1eM1z4inMorMI0gayOSfH+uoY7Syar++1BeRiQ5OBqf4TeBhnI pWAUOQnj0HN8LE3IAOJdPPfyi48h7ausa3fgo6rGUy77upaxWe4MyY78ksmSniE7OOJA juQ8DNIn6vsE5//giOJ8BnnfPD0yBZPND60jnIq5+r7kGSyJy6J9rMM1H6pu+FpF78XL 1bHRV/f/K7CkZ+4NMkPYNQjPTLIIARJeM8ah4T0EK3f4tixCKv9zOL3XLS7+EBdmZKNa DPNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725994189; x=1726598989; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=l3cC5iLIJ+SkbYQv9jHvsp4Eo6d4Ph7QZVRcGZLrLZs=; b=kgSzPKSaoRr21wJznuVndlf3ZFqxb5rMRi0FMjJsK+Wk+ggVlaITpUxITgHpKh1i22 YIScbceAqTW/YrlWXdPbC7nPu1sjhGubjNL7OyZ0jdHY0FZN9IgfQE9PrNjrZZacsNeX u1e5XDvxQFSS8u7OqwLw/QxO5ZGd3guBhIUbJHnHUEZz176J/5EYLpYjcANDliRpHuxT 81mDR+81YYUO/+ZHQWPhVvuYlAfCRVCUMlJXpjyiuSTCGbjmIKMqcBKDFssAqgj/bCY/ bkRd4oMouGJl1bV3sH/+XmufmEzXAndHPg7buHULDrsk5qM635Q2UQly4z5OQdSiXliM xQIA== X-Gm-Message-State: AOJu0YxjDLdCr2MmNABpO+jdfp9uaO5Bgi9PnEXLbjZvRGFYnCeg17QK EqBFoikK46/h1eBSPS4xvKfm9ECxLZuvlPv1X5/tgmX8mUfHm/yiEjvgxOC1wJsLDOi3A6ZYxBh UXCuD8eYDT1GTDysWErXoHEiF8Q1WwXoRKTo3VuhVfsy7O9RYlw== X-Google-Smtp-Source: AGHT+IHgc0w50cTqB1NBGhWV/NW9CTkyRJC+69wdVmNN6Fi4eRm5zXl/qLfSPSg0YDnk1UzIuKqq96ZKWH1cmc4XRrg= X-Received: by 2002:a05:6870:9a96:b0:268:2189:f0d with SMTP id 586e51a60fabf-27b82fc5ab6mr15904247fac.33.1725994189293; Tue, 10 Sep 2024 11:49:49 -0700 (PDT) MIME-Version: 1.0 References: <2039ac58-d3e0-434b-ac1a-2a987f3b4cb1@greiz-reinsdorf.de> In-Reply-To: <2039ac58-d3e0-434b-ac1a-2a987f3b4cb1@greiz-reinsdorf.de> From: Jacob Champion Date: Tue, 10 Sep 2024 11:49:38 -0700 Message-ID: Subject: Re: libpq: Process buffered SSL read bytes to support records >8kB on async API To: Lars Kanis Cc: pgsql-hackers@lists.postgresql.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Sun, Sep 8, 2024 at 1:08=E2=80=AFPM Lars Kanis = wrote: > I'm the maintainer of ruby-pg the ruby interface to the PostgreSQL > database. This binding uses the asynchronous API of libpq by default to > facilitate the ruby IO wait and scheduling mechanisms. > > This works well with the vanilla postgresql server, but it leads to > starvation with other types of servers using the postgresql wire > protocol 3. This is because the current functioning of the libpq async > interface depends on a maximum size of SSL records of 8kB. Thanks for the report! I wanted evidence that this wasn't a ruby-pg-specific problem, so I set up a test case with Python/psycopg2. I was able to reproduce a hang when all of the following were true: - psycopg2's async mode was enabled - the client performs a PQconsumeInput/PQisBusy loop, waiting on socket read events when the connection is busy (I used psycopg2.extras.wait_select() for this) - the server splits a large message over many large TLS records - the server packs the final ReadyForQuery message into the same record as the split message's final fragment Gory details of the packet sizes, if it's helpful: - max TLS record size is 12k, because it made the math easier - server sends DataRow of 32006 bytes, followed by DataRow of 806 bytes, followed by CommandComplete/ReadyForQuery - so there are three TLS records on the wire containing 1) DataRow 1 fragment 1 (12k bytes) 2) DataRow 1 fragment 2 (12k bytes) 3) DataRow 1 fragment 3 (7430 bytes) + DataRow 2 (806 bytes) + CommandComplete + ReadyForQuery > To fix this issue the attached patch calls pqReadData() repeatedly in > PQconsumeInput() until there is no buffered SSL data left to be read. > Another solution could be to process buffered SSL read bytes in > PQisBusy() instead of PQconsumeInput() . I agree that PQconsumeInput() needs to ensure that the transport buffers are all drained. But I'm not sure this is a complete solution; doesn't GSS have the same problem? And are there any other sites that need to make the same guarantee before returning? I need to switch away from this for a bit. Would you mind adding this to the next Commitfest as a placeholder? https://commitfest.postgresql.org/50/ Thanks, --Jacob