Skip site navigation (1) Skip section navigation (2)

Re: Streaming replication and non-blocking I/O

From: Magnus Hagander <magnus(at)hagander(dot)net>
To: Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>
Cc: Fujii Masao <masao(dot)fujii(at)gmail(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Streaming replication and non-blocking I/O
Date: 2010-01-14 10:09:45
Message-ID: 9837222c1001140209w7229bf12oe7a974299160a416@mail.gmail.com (view raw or flat)
Thread:
Lists: pgsql-hackers
2010/1/14 Heikki Linnakangas <heikki(dot)linnakangas(at)enterprisedb(dot)com>:
> Fujii Masao wrote:
>> On Wed, Jan 13, 2010 at 7:27 PM, Heikki Linnakangas
>> <heikki(dot)linnakangas(at)enterprisedb(dot)com> wrote:
>>> the frontend always puts the
>>> connection to non-blocking mode, while the backend uses blocking mode.
>>
>> Really? By default (i.e., without the expressly setting by using
>> PQsetnonblocking()), the connection is set to blocking mode even
>> in frontend. Am I missing something?
>
> That's right. The underlying socket is always put to non-blocking mode
> in libpq. PQsetnonblocking() only affects whether libpq commands wait
> and retry if the output buffer is full.
>
>>> At least with SSL, I think it's possible for pq_wait() to return false
>>> positives, if the SSL layer decides to renegotiate the connection
>>> causing data to flow in the other direction in the underlying TCP
>>> connection. A false positive would lead cause walsender to block
>>> indefinitely on the pq_getbyte() call.
>>
>> Sorry. I could not understand that issue scenario. Could you explain
>> it in more detail?
>
> 1. Walsender calls pq_wait() which calls select(), waiting for timeout,
> or data to become available for reading in the underlying socket.
>
> 2. Client issues an SSL renegotiation by sending a message to the server
>
> 3. Server receives the message, and select() returns indicating that
> data has arrived
>
> 4. Walsender calls HandleEndOfRep() which calls pq_getbyte().
> pq_readbyte() calls SSL_read(), which receives the renegotiation message
> and handles it. No application data has arrived, however, so SSL_read()
> blocks for some to arrive. It never does.
>
> I don't understand enough of SSL to know if renegotiation can actually
> happen like that, but the man page of SSL_read() suggests so. But a
> similar thing can happen if an SSL record is broken into two TCP
> packets. select() returns immediately as the first packet arrives, but
> SSL_read() will block until the 2nd packet arrives.

I *think* renegotiation happens based on amount of content, not amount
of time. But it could still happen in cornercases I think. If the
renegotiation happens right after a complete packet has been sent
(which would be the logical place), but not fast enough that the SSL
library gets it in one read() from the socket, you could end up in
that situation. (if the SSL library gets the renegotiation request as
part of the first read(), it would probably do the renegotiation
before returning from that call to SSL_read(), in which case the
socket would be in the correct state before you call select)

-- 
 Magnus Hagander
 Me: http://www.hagander.net/
 Work: http://www.redpill-linpro.com/

In response to

Responses

pgsql-hackers by date

Next:From: Magnus HaganderDate: 2010-01-14 10:12:18
Subject: Re: Clearing global statistics
Previous:From: Pavel StehuleDate: 2010-01-14 10:06:26
Subject: review: More frame options in window functions

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group