Edit report at http://bugs.php.net/bug.php?id=29074&edit=1

 ID:               29074
 Comment by:       opc dot three at gmail dot com
 Reported by:      david dot blair at nsi1 dot com
 Summary:          mssql_connect fails under heavy load
 Status:           Bogus
 Type:             Bug
 Package:          MSSQL related
 Operating System: MS 2003
 PHP Version:      4.3.7

 New Comment:

I can recreate the behavior described in this report and it does not
seem to be a PHP or SQL Server problem. Further it does not seem to be
affected by the mssql.max_procs setting. Changing the max_procs setting
up, down or to unlimited has no effect in the reproduce code below.
Rather it appears to be related to the underlying driver used in my
particular setup, namely the Microsoft DB-LIB driver ntwdblib.dll, plus
the value of the $new_link parameter being set to true in the call to
mssql_connect. 



I am using ntwdblib.dll version 2000.80.194.0 but have also tried this
with the most current version I could find, 2000.80.2187.0, which is
included in patch set "Microsoft SQL Server 2000 Post-SP4 Rollup".



I am not sure if it is common knowledge but the SQL Server DB-LIB
interface has been officially deprecated since the release of SQL Server
2005. While the server API was left in the product to allow legacy apps
to continue to function, support for new data-types and features are not
being added to the interface and Microsoft discourages new development
from using the interface as it will eventually be dropped from the
product. For example the VARCHAR(MAX), NVARCHAR(MAX) & XML data types
introduced in SQL Server 2005 are not supported by DB-LIB and thus
cannot be reliably communicated to and from the server via the DB-LIB
API.



I think I read somewhere that ntwdblib.dll has a limit of 25 concurrent
connections per process but I cannot seem to find that info now that I
want to reference it. The results from the reproduce code are consistent
with that however as the first 25 connections are made but the 26th
fails. In my environment all connections from all pages in the IIS site
will be opened within the same server process so the limit of open
connections would be 25 per site. I have looked around and I do not see
a way to increase this limit.



For a given web page, setting $new_link to false in the call to
mssql_connect will avoid the issue, however I think the real-world
scenario is when multiple pages within a site are trying to open
connections to the database and the total open connections for the
entire site exceeds 25. Theoretically I think this could be dealt with
by having a dedicated data access layer that emulated a connection pool
to limit the # of open connections from the site to 25 or less.



In my environment I worked arouind the issue by switching to ODBC since
perfromance was not of utmost concern. The odbc libs are slower than the
mssql libs but the SQL Server 2005 Native Client ODBC driver referenced
by my ODBC DSN does not suffer from the concurrent connection limit of
25.





Environment: 

-----------------

 - 32-bit Windows Server 2003 Standard

 - IIS 6

 - PHP 5.2.6

 - SQL Server 2005 Standard w/SP3 (all post-SP3 patches)

 - DB-LIB driver ntwdblib.dll 2000.80.194.0





Reproduce code:

-----------------



<?php

ini_set("display_errors", 1);   // ...so we can see all output, good or
bad

ini_set("mssql.max_procs", 5);  // default is -1 (unlimited) but
changing this has no effect on the results

$new_link = true;               // when true each call to mssql_connect opens a 
new
connection and we see problems after 25 connections



$links = array();

for ($k = 1; $k <= 30; $k++) {

        echo "Connection attempt $k...";

        $link = mssql_connect("localhost", "sa", "hidden", $new_link);

        $links[] = $link;

        echo "<br/>";



}



?>





Expected result:

----------------

Connection attempt 1...

Connection attempt 2...

Connection attempt 3...

Connection attempt 4...

Connection attempt 5...

Connection attempt 6...

Connection attempt 7...

Connection attempt 8...

Connection attempt 9...

Connection attempt 10...

Connection attempt 11...

Connection attempt 12...

Connection attempt 13...

Connection attempt 14...

Connection attempt 15...

Connection attempt 16...

Connection attempt 17...

Connection attempt 18...

Connection attempt 19...

Connection attempt 20...

Connection attempt 21...

Connection attempt 22...

Connection attempt 23...

Connection attempt 24...

Connection attempt 25...

Connection attempt 26...

Connection attempt 27...

Connection attempt 28...

Connection attempt 29...

Connection attempt 30...







Actual result:

--------------



Connection attempt 1...

Connection attempt 2...

Connection attempt 3...

Connection attempt 4...

Connection attempt 5...

Connection attempt 6...

Connection attempt 7...

Connection attempt 8...

Connection attempt 9...

Connection attempt 10...

Connection attempt 11...

Connection attempt 12...

Connection attempt 13...

Connection attempt 14...

Connection attempt 15...

Connection attempt 16...

Connection attempt 17...

Connection attempt 18...

Connection attempt 19...

Connection attempt 20...

Connection attempt 21...

Connection attempt 22...

Connection attempt 23...

Connection attempt 24...

Connection attempt 25...

Connection attempt 26...

Warning: mssql_connect() [function.mssql-connect]: Unable to connect to
server: localhost in D:\phptest\_test_mssql.max_procs.php on line 8



Connection attempt 27...

Warning: mssql_connect() [function.mssql-connect]: Unable to connect to
server: localhost in D:\phptest\_test_mssql.max_procs.php on line 8



Connection attempt 28...

Warning: mssql_connect() [function.mssql-connect]: Unable to connect to
server: localhost in D:\phptest\_test_mssql.max_procs.php on line 8



Connection attempt 29...

Warning: mssql_connect() [function.mssql-connect]: Unable to connect to
server: localhost in D:\phptest\_test_mssql.max_procs.php on line 8



Connection attempt 30...

Warning: mssql_connect() [function.mssql-connect]: Unable to connect to
server: localhost in D:\phptest\_test_mssql.max_procs.php on line 8


Previous Comments:
------------------------------------------------------------------------
[2005-02-03 05:02:49] sni...@php.net

Bogus it is.



------------------------------------------------------------------------
[2005-01-11 22:50:23] david dot blair at nsi1 dot com

We've retired the server that was having the issue...the new production
server is as stable as the development servers...so I'm not sure what to
do with this bug report...



Should it be closed? Handed off? Bogused? Do I scratch this up as a
corrupt install of SQL or PHP or the OS on that server...?

------------------------------------------------------------------------
[2004-10-07 18:15:07] phpbugreport at workboy dot com

If you have access to a packet sniffer and the basic knowhow, I would
recommend sniffing the connection to and from port 1433 of your MSSQL
server (if you are using 1433 that is) and the web server having the
connect problems.  I was able to determine that this problem was on the
SQL side of things by looking at the packet trace.  I would log
mssql_connect failures that were corrected by a second attempt and
matched their times exactly to TCP RESET packets being sent from the
MSSQL server back to the web server requesting a connection to port
1433.  This allowed me to rule out PHP as the source of the failure.



As to why newer versions of PHP cause this more than older versions, all
I can assume is that the newer PHP is more efficient in some way in
opening TCP connections and this is causing greater concurrency in TCP
connection requests to the SQL server.



With a listen backlog of 25 on my SQL server I still see occasional
failures but that is within an acceptable range now as they are handled
by trying again immediately.  If the number starts to go up, I will try
increasing my listen backlog.



I also observed that an entirely separate problem on my SQL server
related to the RAID card increased the failure rate so there appear to
be other mitigating factors on the SQL end.  Fixing the RAID issue make
the connect failures rate drop down to zero again.



Charles

------------------------------------------------------------------------
[2004-09-29 20:29:38] david dot blair at nsi1 dot com

(In response to two posts ago) Charles, I tried your fix by setting the
winsocklistenbacklog to 16.



Didn't work.



Had three more incidents today where the first connection was refused
but on an instant reconnect it worked.

------------------------------------------------------------------------
[2004-09-22 07:37:08] pretenda at pretenda dot com

I am also having the same problem. I have been searching high and low
for an answer, but have found none. I ended up creating a loop in my PHP
connect code too, and it has attempted to connect more than once, 27
times on my development server in the past week.



I am running the following:

Windows 2003 Server

IIS6

PHP 5.01

SQL Server 2000 SP3



A also previously had the issue on 4.3.8, which didn't fail as often.
Unfortunately I need some of the features of PHP5 on my new website.



Cheers,

Matt

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    http://bugs.php.net/bug.php?id=29074


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=29074&edit=1

Reply via email to