Bug #13303 mysql_ping report "Lost connect while query" when mysql server still alive
Submitted: 18 Sep 2005 6:41 Modified: 19 Sep 2005 11:22
Reporter: sanxi wang Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.0.11 OS:Linux (redhat linux 9)
Assigned to: CPU Architecture:Any

[18 Sep 2005 6:41] sanxi wang
Description:
System:
            redhat linux 9
            glibc-2.3.2-27.9.7
Server:
          MySQL-server-5.0.11-0.glibc23
client: 
          MySQL-client-5.0.10-0
          MySQL-devel-5.0.10-0
          MySQL-shared-5.0.11-0.glibc23

If no access to mysql server using a mysql HANDLE after a long time,  when using mysql_ping to test the mysql HANDLE, sometimes , it return false and mysql server is still alive. 
Maybe,  the function "If the connection has gone down, an automatic reconnection is attempted. " is not woking.

How to repeat:
codes:

main.c:

#include <stdio.h>
#include <time.h>
#include "msi.h"

static char db_url[]="mysql://xxx:xxxx@172.25.17.88/xxx";
int dev=32768;

int main()
{
        int retv;
        int i;
        int seconds=1;
        time_t start, now;
        char dt[1024];

        time(&start);
        retv=msi_init_with_url(db_url);
        if(retv!=0) {
                printf( "epcs: connect db %s error: %d\n", db_url, retv);
                return retv;
        }
        printf( "epcs: connect db %s SUCCESS\n", db_url);

        for(i=0; ; i++) {
                while(1) {
                        sleep(1);
                        time(&now);
                        if(now-start>=seconds) {
                                strftime(dt, sizeof(dt), "%F %T", localtime(&now));
                                printf("%s(dev:%ds): ", dt, seconds);
                                time(&start);
                                seconds+=dev;
                                if(msi_ping_test()==0) {
                                        fflush(stdout);
                                        break;
                                } else {
                                        fflush(stdout);
                                        break;
                                }
                        }
                }
        }
        msi_close();
        return 0;
}

msi.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <mysql/mysql.h>
#include <errno.h>

static MYSQL mysql;

#define MYSQL_HEADER    "mysql://"
char username[99], passwd[99], hostname[99], dbname[99];

int parse_mysql_url(char *mysql_url)
{
        char *p,*p1;
        int len=0, ret=0;

        if(mysql_url==NULL)     return -1;

        memset(username, (char)0, sizeof(username));
        memset(passwd, (char)0, sizeof(passwd));
        memset(hostname, (char)0, sizeof(hostname));
        memset(dbname, (char)0, sizeof(dbname));

        if(strncmp(mysql_url,MYSQL_HEADER, strlen(MYSQL_HEADER)))
                return -2;
        p=mysql_url+strlen(MYSQL_HEADER);

        p1 = strchr(p, ':');
        if(!p1) return -3;
        len=p1-p;
        if(len>=sizeof(username)) {
                memcpy(username, p, sizeof(username)-1 );
                ret = 1;
        } else {
                memcpy(username, p, len);
                username[len]=(char)0;
        }
        p=p1+1;

        p1 = strchr(p, '@');
        if(!p1) return -4;
        len=p1-p;
        if(len>=sizeof(passwd)) {
                memcpy(passwd, p, sizeof(passwd)-1 );
                ret = 2;
        } else {
                memcpy(passwd, p, len);
                passwd[len]=(char)0;
        }
        p=p1+1;

        p1 = strchr(p, '/');
        if(!p1) return -5;
        len=p1-p;
        if(len>=sizeof(hostname)) {
                memcpy(hostname, p, sizeof(hostname)-1 );
                ret = 3;
        } else {
                memcpy(hostname, p, len);
                hostname[len]=(char)0;
        }
        p=p1+1;

        len=strlen(p);
        if(len>=sizeof(dbname)) {
                memcpy(dbname, p, sizeof(dbname)-1 );
                ret = 4;
        } else {
                memcpy(dbname, p, len);
                dbname[len]=(char)0;
        }
        return ret;
}

int msi_init(char *hostname, char *dbname, char *username, char *passwd)
{
        if(hostname==NULL || dbname==NULL || username==NULL || passwd==NULL)    return -1;
        if(mysql_init(&mysql)==NULL)    return -2;
        if(!mysql_real_connect(&mysql, hostname, username, passwd, dbname, 0, NULL, CLIENT_MULTI_RESULTS))
        {
                mysql_close(&mysql);
                return -3;
        }

        return 0;
}

int msi_init_with_url(char *mysql_url)
{
        if(parse_mysql_url(mysql_url))   return -1;
        if(msi_init(hostname,dbname,username,passwd))   return -2;
        return 0;
}

int msi_ping_test()
{
        int err;
        err=mysql_ping(&mysql);
        if(err!=0) {
                printf("\tmsi_ping_test Error(%d): %s\n", err, mysql_error(&mysql));
                return -1;
        }
        printf("\tmsi_ping_test Success\n");
        return 0;
}

int msi_close()
{
        mysql_close(&mysql);
        mysql_thread_end();

        return 0;
}

unsigned int msi_errno()
{
        return mysql_errno(&mysql);
}

const char *msi_error()
{
        return mysql_error(&mysql);
}

void msi_thread_init()
{
        mysql_thread_init();
}

void msi_thread_end()
{
        mysql_thread_end();
}

unsigned int msi_thread_safe()
{
        return mysql_thread_safe();
}

compile
gcc -o main main.c msi.c -lmysqlclient_r -lz
[19 Sep 2005 11:22] Hartmut Holzgraefe
works fine for me with wait_timeout=30 (verified that the connection was terminated) and a sleep(60) between mysql_connect() and mysql_ping()
[19 Sep 2005 15:43] sanxi wang
this is a test from another linux machine(test machine: 172.25.17.99, mysql machine 172.25.17.88)
epcs: connect db mysql://xxx:xxx@172.25.17.88/xxxx SUCCESS
2005-09-19 09:17:37(dev:1s):    msi_ping_test Success
2005-09-19 18:23:46(dev:32769s):        msi_ping_test Error(1): Lost connection to MySQL server during query

and this is a test from same machine with mysql server, like this(test program have a little change)
2005-09-19 09:21:57(dev:32s):   msi_ping_test Success
2005-09-19 09:23:01(dev:64s):   msi_ping_test Success
2005-09-19 09:25:09(dev:128s):  msi_ping_test Success
2005-09-19 09:29:25(dev:256s):  msi_ping_test Success
2005-09-19 09:37:57(dev:512s):  msi_ping_test Success
2005-09-19 09:55:01(dev:1024s):         msi_ping_test Success
2005-09-19 10:29:09(dev:2048s):         msi_ping_test Success
2005-09-19 11:37:25(dev:4096s):         msi_ping_test Success
2005-09-19 13:53:57(dev:8192s):         msi_ping_test Success
2005-09-19 18:27:01(dev:16384s):        msi_ping_test Success
2005-09-19 xx:xx:xx(dev:32769s):        msi_ping_test Error(1): Lost connection to MySQL server during query

and , where to set "wait_timeout=30"