Обсуждение: client socket TIME_WAIT state after PQfinish
<div class="WordSection1"><p class="MsoNormal"><span lang="EN-US">Dear all,</span><p class="MsoNormal"><span lang="EN-US"> </span><pclass="MsoNormal">Environement:<p class="MsoNormal"><span lang="EN-US">- OS : Ubuntu 10.04 LTS.</span><pclass="MsoNormal"><span lang="EN-US">- DB: postgresql 8.4.</span><p class="MsoNormal"><span lang="EN-US">-Connection to postgresql using sslmode = disable</span><p class="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal">Scenario :<pclass="MsoListParagraph" style="text-indent:-18.0pt;mso-list:l0 level1 lfo1"><span lang="EN-US"><spanstyle="mso-list:Ignore">1.<span style="font:7.0pt "Times New Roman""> </span></span></span><spanlang="EN-US">I use pgadmin to connect/disconnect to the postgresql server on port 5432 or</span><pclass="MsoListParagraph" style="text-indent:-18.0pt;mso-list:l0 level1 lfo1"><span lang="EN-US"><span style="mso-list:Ignore">2.<spanstyle="font:7.0pt "Times New Roman""> </span></span></span><span lang="EN-US">I usea progam using libpq and make PQconnectdb and PQfinish.</span><p class="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal"><spanlang="EN-US">Bug:</span><p class="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal"><spanlang="EN-US">In both cases, the client socket (pgadmin or my program) remains in TIME_WAIT state.</span><pclass="MsoNormal"><span lang="EN-US">I have used wireshark to sniff the TCP protocol.</span><p class="MsoNormal"><spanlang="EN-US"> </span><p class="MsoNormal"><span lang="EN-US">We have at the end of a connection:</span><pclass="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal"><span lang="EN-US" style="font-family:"CourierNew"">Client Server</span><p class="MsoNormal"><span lang="EN-US" style="font-family:"CourierNew""> ---> FIN,ACK ---></span><p class="MsoNormal"><span lang="EN-US" style="font-family:"CourierNew""> <--- FIN,ACK <---</span><p class="MsoNormal"><span lang="EN-US" style="font-family:"CourierNew""> ---> ACK ---></span><p class="MsoNormal"><span lang="EN-US"> </span><pclass="MsoNormal"><span lang="EN-US">This ends up in a TIME_WAIT state. The TCP protocol should be</span><pclass="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal"><span style="font-family:"Courier New"">Client Server</span><p class="MsoNormal"><span style="font-family:"Courier New""> ---> FIN,ACK ---></span><p class="MsoNormal"><span style="font-family:"Courier New""> <</span><span lang="EN-US" style="font-family:"CourierNew"">--- ACK <---</span><p class="MsoNormal"><span style="font-family:"Courier New""> <--- FIN,ACK <---</span><p class="MsoNormal"><span style="font-family:"Courier New""> </span><span lang="EN-US"style="font-family:"Courier New"">---> ACK ---></span><p class="MsoNormal"><span lang="EN-US"> </span><pclass="MsoNormal"><span lang="EN-US">I suppose there is a bug in the postgresql server that do notsend an ack to the client.</span><p class="MsoNormal"><span lang="EN-US"> </span><p class="MsoNormal"><span lang="EN-US">Couldyou please clarify this situation ? I am a bit lost.</span><p class="MsoNormal"><span lang="EN-US"> </span><pclass="MsoNormal"><span lang="EN-US">Thank you,</span><p class="MsoNormal"><span lang="EN-US"> </span><pclass="MsoNormal"><span lang="EN-US">Franck Lefort</span><p class="MsoNormal"><span lang="EN-US"> </span><pclass="MsoNormal"><span lang="EN-US"> </span></div>
2010/9/27 Guillaume Du Pasquier <guillaume.dupasquier@sensometrix.ch>: > In both cases, the client socket (pgadmin or my program) remains in > TIME_WAIT state. > > I have used wireshark to sniff the TCP protocol. > > We have at the end of a connection: > > Client Server > > ---> FIN,ACK ---> > <--- FIN,ACK <--- > ---> ACK ---> > > This ends up in a TIME_WAIT state. The TCP protocol should be According to the Two Generals' Problem [1], one of the sides necessarily doesn't know whether the other side has received its last packet. Therefore, TCP lets one of the sides sit in TIME_WAIT status for as long as any packets could in principle survive on the network (typically defined as 2 minutes on IP networks IIRC), and potentially disturb a new connection between the same (dst IP, dst port, src IP, src port) combination. [1] <URL:http://en.wikipedia.org/wiki/Two_Generals'_Problem> > Client Server > > ---> FIN,ACK ---> > <--- ACK <--- > <--- FIN,ACK <--- AFAIK, this last ACK (in above packet) is not needed: the server can ACK the client's FIN _while_ it sends its own FIN (by using an appropriate sequence number, as FIN "uses" one byte in the sequence). > ---> ACK ---> > > I suppose there is a bug in the postgresql server that do not send an ack to > the client. I don't think so. Nicolas
On Mon, Sep 27, 2010 at 12:22 PM, Nicolas Barbier <nicolas.barbier@gmail.com> wrote: > According to the Two Generals' Problem [1], one of the sides > necessarily doesn't know whether the other side has received its last > packet. Therefore, TCP lets one of the sides sit in TIME_WAIT status > for as long as any packets could in principle survive on the network > (typically defined as 2 minutes on IP networks IIRC), and potentially > disturb a new connection between the same (dst IP, dst port, src IP, > src port) combination. In other words, this is the way TCP is designed to work, not something specific to PostgreSQL. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise Postgres Company
Dear Nicolas, Dear Robert, Thank you for your quick answers. We do not have such behavior using SSL, how do you explain it ? I suppose that openssl is using the setsockopt SO_LINGER that removes this behavior. Therefore, there is a RST sent to close the socket. We work with an environment that uses a lot of socket connections. Therefore, many file descriptors are opened. If after each Sql requests a TIME_WAIT arises we will end up with many file descriptors opened. By default the maximum number of file descriptors is set to 1024 and we reach that number quite fast. Do you have any advices to get rid of this TIME_WAIT problem ? Our client runs on the same machine as the postgresql server. Would it be possible to use PF_UNIX sockets ? Thank you, Franck -----Original Message----- From: Nicolas Barbier [mailto:nicolas.barbier@gmail.com] Sent: lundi 27 septembre 2010 18:23 To: Guillaume Du Pasquier Cc: pgsql-hackers@postgresql.org Subject: Re: [HACKERS] client socket TIME_WAIT state after PQfinish 2010/9/27 Guillaume Du Pasquier <guillaume.dupasquier@sensometrix.ch>: > In both cases, the client socket (pgadmin or my program) remains in > TIME_WAIT state. > > I have used wireshark to sniff the TCP protocol. > > We have at the end of a connection: > > Client Server > > ---> FIN,ACK ---> > <--- FIN,ACK <--- > ---> ACK ---> > > This ends up in a TIME_WAIT state. The TCP protocol should be According to the Two Generals' Problem [1], one of the sides necessarily doesn't know whether the other side has received its last packet. Therefore, TCP lets one of the sides sit in TIME_WAIT status for as long as any packets could in principle survive on the network (typically defined as 2 minutes on IP networks IIRC), and potentially disturb a new connection between the same (dst IP, dst port, src IP, src port) combination. [1] <URL:http://en.wikipedia.org/wiki/Two_Generals'_Problem> > Client Server > > ---> FIN,ACK ---> > <--- ACK <--- > <--- FIN,ACK <--- AFAIK, this last ACK (in above packet) is not needed: the server can ACK the client's FIN _while_ it sends its own FIN (by using an appropriate sequence number, as FIN "uses" one byte in the sequence). > ---> ACK ---> > > I suppose there is a bug in the postgresql server that do not send an ack to > the client. I don't think so. Nicolas
On Mon, Sep 27, 2010 at 12:56 PM, Guillaume Du Pasquier <guillaume.dupasquier@sensometrix.ch> wrote: > Dear Nicolas, Dear Robert, > > Thank you for your quick answers. > We do not have such behavior using SSL, how do you explain it ? > I suppose that openssl is using the setsockopt SO_LINGER that > removes this behavior. Therefore, there is a RST sent to close > the socket. > > We work with an environment that uses a lot of socket connections. > Therefore, many file descriptors are opened. If after each > Sql requests a TIME_WAIT arises we will end up with many > file descriptors opened. By default the maximum number of file descriptors > is set to 1024 and we reach that number quite fast. Hrm. Does a socket in the TIME_WAIT state count against the number of open file descriptors? Certainly, it shouldn't count against the per-process limit, as the process has already closed it. > Do you have any advices to get rid of this TIME_WAIT problem ? > Our client runs on the same machine as the postgresql server. > Would it be possible to use PF_UNIX sockets ? Yeah, actually that's the default, if you just run "psql" with no parameters. It looks for a socket in /tmp/.s.PGSQL.5432. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise Postgres Company
2010/9/27 Robert Haas <robertmhaas@gmail.com>: > On Mon, Sep 27, 2010 at 12:56 PM, Guillaume Du Pasquier > <guillaume.dupasquier@sensometrix.ch> wrote: > >> Our client runs on the same machine as the postgresql server. >> Would it be possible to use PF_UNIX sockets ? > > Yeah, actually that's the default, if you just run "psql" with no > parameters. It looks for a socket in /tmp/.s.PGSQL.5432. It depends on the interface; e.g., the JDBC driver doesn't support unix sockets, AFAIR. Nicolas