ID: 47641 Comment by: dima at dimych dot sumy dot ua 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:
ttyp3[r...@noc-12:35:15]/home/dima# php -n -d mysql.connect_timeout=60 -r 'mysql_connect("127.0.0.1", "test", "");' Fatal error: Call to undefined function mysql_connect() in Command line code on line 1 ttyp3[r...@noc-12:35:19]/home/dima# php -d mysql.connect_timeout=60 -r 'mysql_connect("127.0.0.1", "test", "");' PHP Warning: mysql_connect(): Can't connect to MySQL server on '127.0.0.1' (0) in Command line code on line 1 ttyp3[r...@noc-12:36:17]/home/dima# php -d mysql.connect_timeout=60 -r 'mysql_connect("localhost", "test", "");' PHP Warning: mysql_connect(): Access denied for user 'test'@'localhost' (using password: NO) in Command line code on li ne 1 ttyp3[r...@noc-12:37:05]/home/dima# mysql -V mysql Ver 14.14 Distrib 5.1.32, for portbld-freebsd7.1 (i386) using 5.2 Previous Comments: ------------------------------------------------------------------------ [2009-06-02 08:34:17] j...@php.net 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