Re: [psycopg] #92: psycopg2 connection leaks handles under Windows

psycopg fog at initd.org
Mon Jan 30 04:59:33 CET 2006


#92: psycopg2 connection leaks handles under Windows
------------------------------+---------------------------------------------
 Reporter:  gpd at gpdnet.co.uk  |        Owner:  fog    
     Type:  defect            |       Status:  new    
 Priority:  high              |    Milestone:         
Component:  psycopg2          |      Version:  2.0beta
 Severity:  critical          |   Resolution:         
 Keywords:                    |  
------------------------------+---------------------------------------------
Comment (by jerickso at stickpeople.com):

 I also tried the example listed above (and thanks for a simple test case
 that showed your problem).  I as well was unable to duplicate the problem.
 With the client, I am running Windows XP/SP2, Python 2.4.2 w/ the 2.0b6.2
 psycopg.  The server is a FreeBSD 4.11 machine, running PostgreSQL 8.1.2.
 The server is not on the same LAN as the client.  The ping time from the
 client to the server is 30ms.

 I've also compiled a recent version and reran the test.  Again, it opened
 and closed all 10000.  You can try the new version as well, at:
 [http://www.stickpeople.com/projects/python/win-psycopg/psycopg2-2.0b7-
 r734.win32-py2.4.exe].

 As you indicated, the error message seems to point that psycopg (actually
 libpq) is trying to open up an address/port on the local machine that is
 already in use.  The error 'Address already in use' in libpq is the MS
 error WSAEADDRINUSE.  The strange part is that you typically see the error
 when you are trying to bind to a port already in use (ie. Starting a web
 server when there is already a webserver running and bound to that port).
 The libpq should not care what port it is opening up, since it is
 initializing the connection and should pick the next free port.  Of
 course, if all the ports are in use, that is another matter....


 Running the program and doing a netstat, tho, is showing something that I
 believe is causing the problem (Note: need some win32 unix tools for the
 following command):
   netstat | grep ":5432 " | wc

 The number of 'open' ports to PostgreSQL(5432) starts to increases with
 the number of connections while the script is running.  It levels off
 around 1400-1440.  Now, in fairness, all but 2-3 of the ports are in the
 TIME_WAIT state, with the other 2-3 in the ESTABLISHED state.  Which makes
 sense.  Typically, when a connection closes, the side that requested the
 closure ends up entering a TIME_WAIT state.  The default TIME_WAIT on
 Windows is somewhere between 2 and 4 minutes (Microsoft says it is 240
 seconds, but I'm showing 2 minutes), which matches up with where the
 number of open ports leveled off.  Note that leaving the python prompt
 open for >4minutes after the code finishes running and then running
 netstat shows no ports still open.

 I seem to recall a Windows Server 2003 quirk that would reallocate a port
 that was still in the TIME_WAIT state, but I believe that was fixed in
 SP1.  Not sure if other Windows versions had the same issue.

 If you have a fast network, and you have both a fast client and server
 machine, I can see you running out of ports because of the TIME_WAIT.
 Even thought there are only 65,536 ports available with Windows
 NT/2000/XP/Server*, it only allocates the port numbers up to 5000 for
 outbound connections.  With it starting to allocate somewhere above 1024,
 that leaves less than 4000 ports that one can play with, which corresponds
 with what you were seeing.  If you can create 4000 connections to your
 server in under the timeout, I'm sure this is your culprit.

 What can you do???  There are two options, both of which require adding a
 value to the registry, and you may want to add/change both.  Standard
 disclaimers about editing the registry apply.

 1) Set the TIME_WAIT delay in Windows.
 Add a DWORD key 'TcpTimedWaitDelay' to:
 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

 Value in seconds between 30 and 300.  Default is 2*MSL=240 (MSL is maximum
 segment life of the network).


 2) Increate the Maximum User ports in Windows.
 Add a DWORD key 'MaxUserPorts' to:
 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

 Value between 5000-65534.  Remember that the first 1024 is not used when
 an application requests a port.


 -jason

-- 
Ticket URL: <http://initd.org/tracker/psycopg/ticket/92>
psycopg <http://initd.org/>
psycopg


More information about the Psycopg mailing list