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