MYSQL的问题,执行mysql_real_query时程序崩溃了,找到问题不知道怎么解决,100分求帮助!

honemay 2010-09-10 10:35:12
我的程序文件名是q.fcgi,C语言写的, 然后用lighttpd启动了3个,3个进程完全一模一样,因为是一个程序嘛
程序启动的时候把数据库里所有数据加载到了内存
每时每刻程序都接收请求并处理,然后我1小时会更新一次内存的数据,就是把数据库新加的数据插入到内存中..

每次定时器启动,如果数据库新加了数据,3个进程前面2个进程执行下面代码会没问题,但第3个进程就会崩溃...
Mysql语句就算执行出错也不会程序崩溃的,我这里估计是执行语句的时候操作内存非法了导致崩溃,有时候2个进程会执行崩溃,但第3个进程很大可能会挂


MYSQL* mysql_insert = new MYSQL;
//初始化数据库
mysql_init(mysql_insert);
if(mysql_insert==NULL)
{
return;
}
//连接数据库
mysql_insert = mysql_real_connect(mysql_insert, m_data.m_IP, m_data.m_UserName, m_data.m_PassWord, NULL, m_data.m_Port, NULL, 0);

if(!mysql_insert) return;
//选择数据库表
if(mysql_select_db(mysql_insert, m_data.m_DBName) != 0) return;

int nCountLrcOld = GlobalData.size();
char sql[100] = {0};
sprintf(sql, "select id, title, artist, lrc from %s where id > %d order by id", m_data.m_DBName, uMaxLrcDataID);
int len =strlen(sql);

//设置mysql编码
mysql_query(mysql_insert,"SET NAMES utf8");
Global_wRunlog.writeFile("ready to query");
if(mysql_real_query(mysql_insert, sql, len)!=0) //执行查询sql语句,在此会出错并且程序崩溃
{
Global_wRunlog.writeFile("last error %s", mysql_error(mysql_insert)); //执行不到
return ;
}

MYSQL_RES *result = NULL;
MYSQL_ROW row;

Global_wRunlog.writeFile("ready to getdata");
//读取查询到的信息
if(!(result=mysql_store_result(mysql_insert))) //上面没崩溃,这里也可能崩溃
{
return ;
}

while(row = mysql_fetch_row(result))
{
//做将数据插入到内存的map表中
}

//释放记录
mysql_free_result(result);
mysql_close(mysql_insert);
delete mysql_insert;
mysql_insert = NULL;
...全文
765 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiao1dian 2012-10-10
  • 打赏
  • 举报
回复
您好,不知道您的问题有没有解决,我的问题和您帖子中很相似。请不吝赐教
honemay 2010-09-13
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 erwin1984 的回复:]
这个有可能是你使用的MYSQL的头文件与链接的 libmysql.lib 版本不一致导致的,

头文件用的新的版本,而lib,dll用了旧的版本, 你可以去MYSQL上下载一个最新的开发版本,将头文件,lib,dll全换成统一的版本,再试试看.

我原来也碰到过类似的莫名其妙的问题, 后面才发现是头文件与lib版本不一致导致的.
[/Quote]
不会.我确定是一致的.
这个跑了1个多月了,是这几天改代码的时候新增加操作MYSQL才导致的
3个进程同时从数据库里读数据,导致某一个进程崩溃!
erwin1984 2010-09-13
  • 打赏
  • 举报
回复
这个有可能是你使用的MYSQL的头文件与链接的 libmysql.lib 版本不一致导致的,

头文件用的新的版本,而lib,dll用了旧的版本, 你可以去MYSQL上下载一个最新的开发版本,将头文件,lib,dll全换成统一的版本,再试试看.

我原来也碰到过类似的莫名其妙的问题, 后面才发现是头文件与lib版本不一致导致的.
honemay 2010-09-13
  • 打赏
  • 举报
回复
我现在就是用信号量锁住了。。不过信号量还需要优化一下,不然全卡死了!
hawk198 2010-09-11
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 honemay 的回复:]

回 hawk198
我拷贝你的代码看看。
我现在在用信号量来控制,主要是代码本身并没问题
但是在3个进程同时执行这个代码的时候
第1,2个进程基本不出问题,但第3个进程很大可能崩溃!!
[/Quote]
如果你多进程同时执行,那么需要看看查询是否返回正确值,在查询失败的情况下如果执行这条语句
mysql_store_result(mysql_insert)

会直接内存错误,所以一定要慎重。
我试过多次载入,发现某次如果执行出错,那么不能立即释放句柄资源,这时候释放mysql_insert,可能会导致问题。
建议你用信号量锁住这个函数,让它同一时间只能执行一次
hawk198 2010-09-10
  • 打赏
  • 举报
回复
用法上面我觉得没什么大问题,关键是细节要看看,如果有返回值的话,多判下总没什么大错误
hawk198 2010-09-10
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>

#ifdef WIN32
#include <winsock2.h>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <process.h>
#else
#include <unistd.h>
#include <string.h>
#endif

#include "mysql5/mysql.h"


#pragma comment(lib, "libmysql.lib")


int main(void)
{
MYSQL* mysql_insert = NULL;
MYSQL_RES *result = NULL;
MYSQL_ROW row;
char sql[100] = {0};
int len = 0;

mysql_insert = mysql_init((MYSQL*)NULL);
//初始化数据库
//mysql_init(mysql_insert);
if(mysql_insert==NULL)
{
return -1;
}
//连接数据库
mysql_insert = mysql_real_connect(mysql_insert, "192.168.1.63", "user", "pwd", NULL, 3306, NULL, 0);

if(!mysql_insert) return -1;
//选择数据库表
if(mysql_select_db(mysql_insert, "db") != 0) return -1;

sprintf(sql, "select id, title, artist, lrc from %s where id > %d order by id", "user", 100);
len =strlen(sql);

//设置mysql编码
mysql_query(mysql_insert,"SET NAMES utf8");
printf("ready to query\n");
if(mysql_real_query(mysql_insert, sql, len)!=0) //执行查询sql语句,在此会出错并且程序崩溃
{
printf("last error %s\n", mysql_error(mysql_insert)); //执行不到
return -1;
}


printf("ready to getdata\n");
//读取查询到的信息
if(!(result=mysql_store_result(mysql_insert))) //上面没崩溃,这里也可能崩溃
{
return -1;
}

while(row = mysql_fetch_row(result))
{
//做将数据插入到内存的map表中
}

//释放记录
mysql_free_result(result);
mysql_close(mysql_insert);
mysql_insert = NULL;

return (0);
}

我改了下你的代码,在我这里跑了,没有发现有什么错误啊,除了这句我修改了
	mysql_insert = mysql_init((MYSQL*)NULL);
//初始化数据库
//mysql_init(mysql_insert);
honemay 2010-09-10
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 void_wuyu 的回复:]
int len =strlen(sql);
好像要+1的说,这个不算\0的
[/Quote]
这个没问题的,不过我参考试试,我每次程序启动也加载了数据库,也是这样用的strlen没问题
乐CC 2010-09-10
  • 打赏
  • 举报
回复
int len =strlen(sql);
好像要+1的说,这个不算\0的
honemay 2010-09-10
  • 打赏
  • 举报
回复


MYSQL* mysql_insert = new MYSQL;
//初始化数据库
mysql_init(mysql_insert);
if(mysql_insert==NULL)
{
return;
}
//连接数据库
mysql_insert = mysql_real_connect(mysql_insert, m_data.m_IP, m_data.m_UserName, m_data.m_PassWord, NULL, m_data.m_Port, NULL, 0);

if(!mysql_insert) return;
//选择数据库表
if(mysql_select_db(mysql_insert, m_data.m_DBName) != 0) return;

int nCountLrcOld = GlobalData.size();
char sql[100] = {0};
sprintf(sql, "select id, title, artist, lrc from %s where id > %d order by id", m_data.m_DBName, uMaxLrcDataID);
int len =strlen(sql);

//设置mysql编码
mysql_query(mysql_insert,"SET NAMES utf8");
Global_wRunlog.writeFile("ready to query");
if(mysql_real_query(mysql_insert, sql, len)!=0) //执行查询sql语句,在此会出错并且程序崩溃
{
Global_wRunlog.writeFile("last error %s", mysql_error(mysql_insert)); //执行不到
return ;
}

MYSQL_RES *result = NULL;
MYSQL_ROW row;

Global_wRunlog.writeFile("ready to getdata");
//读取查询到的信息
if(!(result=mysql_store_result(mysql_insert))) //上面没崩溃,这里也可能崩溃
{
return ;
}

while(row = mysql_fetch_row(result))
{
//做将数据插入到内存的map表中
}

//释放记录
mysql_free_result(result);
mysql_close(mysql_insert);
delete mysql_insert;
mysql_insert = NULL;
honemay 2010-09-10
  • 打赏
  • 举报
回复


MYSQL* mysql_insert = new MYSQL;
//初始化数据库
mysql_init(mysql_insert);
if(mysql_insert==NULL)
{
return;
}
//连接数据库
mysql_insert = mysql_real_connect(mysql_insert, m_data.m_IP, m_data.m_UserName, m_data.m_PassWord, NULL, m_data.m_Port, NULL, 0);

if(!mysql_insert) return;
//选择数据库表
if(mysql_select_db(mysql_insert, m_data.m_DBName) != 0) return;

int nCountLrcOld = GlobalData.size();
char sql[100] = {0};
sprintf(sql, "select id, title, artist, lrc from %s where id > %d order by id", m_data.m_DBName, uMaxLrcDataID);
int len =strlen(sql);

//设置mysql编码
mysql_query(mysql_insert,"SET NAMES utf8");
Global_wRunlog.writeFile("ready to query");
if(mysql_real_query(mysql_insert, sql, len)!=0) //执行查询sql语句,在此会出错并且程序崩溃
{
Global_wRunlog.writeFile("last error %s", mysql_error(mysql_insert)); //执行不到
return ;
}

MYSQL_RES *result = NULL;
MYSQL_ROW row;

Global_wRunlog.writeFile("ready to getdata");
//读取查询到的信息
if(!(result=mysql_store_result(mysql_insert))) //上面没崩溃,这里也可能崩溃
{
return ;
}

while(row = mysql_fetch_row(result))
{
//做将数据插入到内存的map表中
}

//释放记录
mysql_free_result(result);
mysql_close(mysql_insert);
delete mysql_insert;
mysql_insert = NULL;
honemay 2010-09-10
  • 打赏
  • 举报
回复
回 hawk198
我拷贝你的代码看看。
我现在在用信号量来控制,主要是代码本身并没问题
但是在3个进程同时执行这个代码的时候
第1,2个进程基本不出问题,但第3个进程很大可能崩溃!!

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧