ID: 47641
Updated by: [email protected]
Reported By: dima at dimych dot sumy dot ua
Status: Feedback
Bug Type: MySQL related
Operating System: FreeBSD 7.1
PHP Version: 5.2.9
New Comment:
Exactly what mysql version are you trying this with? As for me it works
perfectly fine with PHP compiled with Mysql 5.0.37 client lib.
Tried with:
# php -n -d mysql.connect_timeout=60 -r 'mysql_connect("127.0.0.1",
"test", "");'
Previous Comments:
------------------------------------------------------------------------
[2009-06-02 08:34:17] [email protected]
Exactly what mysql version are you trying this with? As for me it works
perfectly fine with PHP compiled with Mysql 5.0.37 client lib.
Tried with:
# php -n -d mysql.connect_timeout=60 -r 'mysql_connect("127.0.0.1",
"test", "");'
------------------------------------------------------------------------
[2009-03-13 10:49:11] dima at dimych dot sumy dot ua
I`m investigated this bug using mysql client trace file.
For additional debug info I modified mysql client library file
sql-common/client.c. Modifications done in functions mysql_options,
my_connect, wait_for_data. This is diff for source of modified functions
(need for understanding new trace data):
--- client.c 2008-11-14 18:37:28.000000000 +0200
+++ client.c.new 2009-03-13 12:36:36.000000000 +0200
@@ -143,7 +143,14 @@
int my_connect(my_socket fd, const struct sockaddr *name, uint
namelen,
uint timeout)
{
+ DBUG_ENTER("my_connect");
+ DBUG_PRINT("enter", ("socket: %d
name:{%d,%d,[%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d]} namelen: %lu
timeout: %lu",
+ fd, timeout, name->sa_len, name->sa_family,
name->sa_data[0], name->sa_data[1],
+
name->sa_data[2],name->sa_data[3],name->sa_data[4],name->sa_data[5],name->sa_data[6],
+
name->sa_data[7],name->sa_data[8],name->sa_data[9],name->sa_data[10],name->sa_data[11],
+
name->sa_data[12],name->sa_data[13],namelen,timeout));
#if defined(__WIN__) || defined(__NETWARE__)
+ DBUG_RETURN(0);
return connect(fd, (struct sockaddr*) name, namelen);
#else
int flags, res, s_err;
@@ -153,11 +160,14 @@
exactly like the normal connect() call does.
*/
- if (timeout == 0)
+ if (timeout == 0) {
+ DBUG_PRINT("info", ("timeout == 0"));
+ DBUG_RETURN(0);
return connect(fd, (struct sockaddr*) name, namelen);
-
+ }
flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block
*/
#ifdef O_NONBLOCK
+ DBUG_PRINT("info", ("O_NONBLOCK"));
fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags..
*/
#endif
@@ -167,10 +177,15 @@
if ((res != 0) && (s_err != EINPROGRESS))
{
errno= s_err; /* Restore it */
+ DBUG_PRINT("error", ("res != 0. res: %d errno: %d", res, errno));
+ DBUG_RETURN(-1);
return(-1);
}
- if (res == 0) /* Connected quickly!
*/
+ if (res == 0) /* Connected quickly!
*/ {
+ DBUG_PRINT("info", ("res == 0"));
+ DBUG_RETURN(0);
return(0);
+ }
return wait_for_data(fd, timeout);
#endif
}
@@ -187,7 +202,10 @@
static int wait_for_data(my_socket fd, uint timeout)
{
+ DBUG_ENTER("wait_for_data");
+ DBUG_PRINT("enter", ("timeout :%lu", timeout));
#ifdef HAVE_POLL
+ DBUG_PRINT("info:", ("wait using poll"));
struct pollfd ufds;
int res;
@@ -196,20 +214,30 @@
if (!(res= poll(&ufds, 1, (int) timeout*1000)))
{
errno= EINTR;
+ DBUG_PRINT("error:", ("EINTR"));
+ DBUG_RETURN(-1);
return -1;
}
- if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
+ if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI))) {
+ DBUG_PRINT("error:", ("res < 0"));
+ DBUG_RETURN(-1);
return -1;
+ }
+ DBUG_RETURN(0);
return 0;
#else
+ DBUG_PRINT("info:", ("wait using loop"));
SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
fd_set sfds;
struct timeval tv;
time_t start_time, now_time;
int res, s_err;
- if (fd >= FD_SETSIZE) /* Check if
wrong error */
+ if (fd >= FD_SETSIZE) { /* Check if
wrong error */
+ DBUG_PRINT("info:", ("wait using loop"));
+ DBUG_RETURN(0);
return 0; /* Can't use timeout
*/
+ }
/*
Our connection is "in progress." We can use the select() call to
wait
@@ -252,8 +280,11 @@
return -1;
now_time= my_time(0);
timeout-= (uint) (now_time - start_time);
- if (errno != EINTR || (int) timeout <= 0)
+ if (errno != EINTR || (int) timeout <= 0) {
+ DBUG_PRINT("error:", ("errno != EINTR. errno: %d", errno));
+ DBUG_RETURN(-1);
return -1;
+ }
}
/*
@@ -263,14 +294,19 @@
*/
s_err=0;
- if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err,
&s_err_size) != 0)
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err,
&s_err_size) != 0) {
+ DBUG_PRINT("error:", ("getscokopt"));
+ DBUG_RETURN(-1);
return(-1);
-
+ }
if (s_err)
{ /* getsockopt could
succeed */
errno = s_err;
+ DBUG_PRINT("error:", ("getsockopt errno: %d", errno));
+ DBUG_RETURN(-1);
return(-1); /* but return
an error... */
}
+ DBUG_RETURN(0);
return (0); /* ok */
#endif /* HAVE_POLL */
}
@@ -3023,6 +3059,7 @@
DBUG_PRINT("enter",("option: %d",(int) option));
switch (option) {
case MYSQL_OPT_CONNECT_TIMEOUT:
+ DBUG_PRINT("enter",("arg: %lu",*(uint*) arg));
mysql->options.connect_timeout= *(uint*) arg;
break;
case MYSQL_OPT_READ_TIMEOUT:
--- END OF DIFF ---
doing connect using
<?php mysql_connect("127.0.0.1", 'test', 'test'); ?>
trace file contains this:
>mysql_option
| enter: option: 0
| enter: arg: 60
<mysql_option
>mysql_real_connect
| enter: host: 127.0.0.1 db: (Null) user: test
| info: Server name: '127.0.0.1'. TCP sock: 3306
| >vio_new
| | enter: sd: 4
| | >my_malloc
| | | my: size: 152 my_flags: 16
| | | exit: ptr: 0x2972c340
| | <my_malloc
| | >vio_init
| | | enter: type: 1 sd: 4 flags: 2
| | | >my_malloc
| | | | my: size: 16384 my_flags: 16
| | | | exit: ptr: 0x297c6000
| | | <my_malloc
| | <vio_init
| <vio_new
| >my_connect
| | enter: socket: 4 name:{60,0,[2,12,-22,127,0,0,1,0,0,0,0,0,0,0]}
namelen: 0 timeout: 16
| | info:: O_NONBLOCK
| | error:: res != 0. res: -1 errno: 0
| <my_connect
| error: Got error 0 on connect to '127.0.0.1'
| >set_mysql_extended_error
| | enter: error :2003 'Can't connect to MySQL server on '%-.100s'
(%d)'
| <set_mysql_extended_error
| error: message: 2003/HY000 (Can't connect to MySQL server on
'127.0.0.1' (0))
| >end_server
--- END OF TRACE FILE ---
Doing connect with command line utility "mysql":
mysql -u test -ptest -h 127.0.0.1 --connect_timeout=60
--debug=d:t:O,/tmp/client.trace
Trace file contains:
| >my_malloc
| | my: size: 16 my_flags: 16
| | exit: ptr: 0x2840e050
| <my_malloc
| >my_malloc
| | my: size: 520 my_flags: 16
| | exit: ptr: 0x28410000
| <my_malloc
| >my_malloc
| | my: size: 512 my_flags: 48
| | exit: ptr: 0x2842f200
| <my_malloc
| >init_alloc_root
| | enter: root: 0x805f968
| <init_alloc_root
| >init_alloc_root
| | enter: root: 0x805f9a0
| <init_alloc_root
| >mysql_option
| | enter: option: 0
| | enter: arg: 60
| <mysql_option
| >mysql_real_connect
| | enter: host: 127.0.0.1 db: (Null) user: test
| | info: Server name: '127.0.0.1'. TCP sock: 3306
| | >vio_new
| | | enter: sd: 4
| | | >my_malloc
| | | | my: size: 152 my_flags: 16
| | | | exit: ptr: 0x284280c0
| | | <my_malloc
| | | >vio_init
| | | | enter: type: 1 sd: 4 flags: 2
| | | | >my_malloc
| | | | | my: size: 16384 my_flags: 16
| | | | | exit: ptr: 0x28437000
| | | | <my_malloc
| | | <vio_init
| | <vio_new
| | >my_connect
| | | enter: socket: 4 name:{60,0,[2,12,-22,127,0,0,1,0,0,0,0,0,0,0]}
namelen: 0 timeout: 16
| | | info:: O_NONBLOCK
| | | >wait_for_data
| | | | enter: timeout :60
| | | | info:: wait using poll
| | | <wait_for_data
| | | >my_net_init
--- END OF TRACE FILE ---
setting mysql.connect_timeout = -1 in php.ini and doing connect using
<?php mysql_connect("127.0.0.1", 'test', 'test'); ?>
trace file contains this:
>mysql_real_connect
| enter: host: 127.0.0.1 db: (Null) user: test
| info: Server name: '127.0.0.1'. TCP sock: 3306
| >vio_new
| | enter: sd: 4
| | >my_malloc
| | | my: size: 152 my_flags: 16
| | | exit: ptr: 0x2972c340
| | <my_malloc
| | >vio_init
| | | enter: type: 1 sd: 4 flags: 2
| | | >my_malloc
| | | | my: size: 16384 my_flags: 16
| | | | exit: ptr: 0x297c6000
| | | <my_malloc
| | <vio_init
| <vio_new
| >my_connect
| | enter: socket: 4 name:{0,0,[2,12,-22,127,0,0,1,0,0,0,0,0,0,0]}
namelen: 0 timeout: 16
| | info:: timeout == 0
| <my_connect
| >my_net_init
--- END OF TRACE FILE ---
------------------------------------------------------------------------
[2009-03-13 10:31:06] dima at dimych dot sumy dot ua
Description:
------------
connecting to mysql server using TCP
with mysql.connect_timeout set not equal to "-1" in php.ini produces
error:
Can't connect to MySQL server on '127.0.0.1' (0)
Reproduce code:
---------------
1 in php.ini set:
mysql.connect_timeout = 60
2 create user test with password test in local database
3 create file test.php:
<?php
mysql_connect("127.0.0.1", 'test', 'test');
?>
Expected result:
----------------
Successful connection to database like for:
<?php
mysql_connect("localhost", 'test', 'test');
?>
or connection to 127.0.0.1 with mysql.connect_timeout = -1
Actual result:
--------------
PHP Warning: mysql_connect(): Can't connect to MySQL server on
'127.0.0.1' (0) in /usr/home/dima/test.php on line 2
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=47641&edit=1