NOIR 2019-05-23 21:25 采纳率: 0%
浏览 416

CentOS6.9 (MySql v5.7.22) 使用mysql C API mysql_real_query 导致内存溢出

当我开始循环调用sql语法,比如 UPDATE ** SET ** , mysql_real_query API会导致系统内存持续不断的增长,直到测试进程崩溃或者系统崩溃。我使用top命令查看系统内存的分配情况,很奇怪的是mysqld 和我的测试程序 sqltest都没有看到内存的增加,而系统的free内存一直在减少,used内存一直在增加,最后导致系统崩溃。 代码我实在是检查过很多遍了看不出什么问题, 大神帮我看下。

int ThreadExeSQL(MYSQL* lpSQLConn, char * sql, int iLen)
{

    if (mysql_real_query(lpSQLConn, sql, iLen))
    {
        MYSQL_RES* lpGetSQLRes = mysql_store_result(lpSQLConn);
        mysql_free_result(lpGetSQLRes);
        return -1;
    }

    //mysql_errno(lpSQLConn);
    //mysql_error(lpSQLConn);

    MYSQL_RES* lpGetSQLRes = mysql_store_result(lpSQLConn);
    mysql_free_result(lpGetSQLRes); // release sql memory

    return 0; // success
}

void* ThreadSQL_HexWrite(void* lpGet)
{

    LPThreadParam getParam = (LPThreadParam)lpGet;

    MYSQL* lpSQLConn = (MYSQL*)&getParam->lpSQLConn;
    int iThreadIdx = getParam->iThreadIdx;

    printf("ID:%d\n", iThreadIdx);

    mysql_thread_init();

    lpSQLConn = mysql_init(NULL);


    if (!mysql_real_connect(lpSQLConn, g_host_name, g_user_name, g_password, g_db_name, g_db_port, NULL, 0))
    {
        ThreadSQLError(lpSQLConn, NULL);
        return;
    }
    else
    {
        printf("mysql_real_connect OK!\n");
    }


    for (int i = 0; i < 1000000; i++)
    {

        char lpCmdStr[8192] = "\0";
        sprintf(lpCmdStr, "update %s set %s=0x%d where id=%d\0", "tb_Data", "Info", i, 1);

        if (ThreadExeSQL(lpSQLConn, (char*)lpCmdStr, strlen(lpCmdStr)))
        {
            MySQLError getError = ThreadSQLError(lpSQLConn, NULL);
            HandleMySqlError(getError);

            return; //erroe
        }
        else
        {
            printf("ok. ");
        }

        usleep(1000 * 10);
    }

    mysql_close(lpSQLConn);

    mysql_thread_end();


    printf("ThreadSQL_HexWrite OK!\n");
}


MYSQL* g_MySQLConnList[100];

void main()
{

    if (mysql_library_init(0, NULL, NULL))
    {
        printf("could not initialize MySQL client library\n");
        exit(1);
    }


    int thread_num = 1;

    //while (true)
    {
        pthread_t *pTh = new pthread_t[thread_num];


        for (int i = 0; i < thread_num; i++)
        {

            LPThreadParam lpSetParam = new ThreadParam;
            lpSetParam->lpSQLConn = (MYSQL*)&g_MySQLConnList[i];
            lpSetParam->iThreadIdx = i;

            printf("---create thread idx:%d\n", i);
            if (0 != pthread_create(&pTh[i], NULL, ThreadSQL_HexWrite, lpSetParam))
            {
                printf("pthread_create failed\n");
                continue;
            }
        }

        for (int i = 0; i < thread_num; i++)
        {
            pthread_join(pTh[i], NULL);
        }

        delete[] pTh;
    }

    mysql_library_end();

    printf("All Done!\n");

} 
  • 写回答

1条回答 默认 最新

  • 憧憬blog 2023-03-15 07:20
    关注

    根据你的描述,可能存在内存泄漏导致内存溢出的问题。在你的代码中,每次迭代循环都会创建一个新的MYSQL实例,但在循环结束后没有释放它们。这可能会导致内存泄漏并最终导致内存溢出。

    另外,你的代码也没有使用连接池来管理MYSQL连接。每次创建新连接时,MySQL服务器都会将连接添加到其连接池中,这可能会导致内存占用高并且最终导致系统崩溃。

    建议你将MYSQL连接池集成到你的代码中,并重构循环以使用已经存在的连接池中的连接。另外,使用Valgrind等工具来检测内存泄漏,以便及时发现和修复问题。

    评论

报告相同问题?

悬赏问题

  • ¥15 我想在一个软件里添加一个优惠弹窗,应该怎么写代码
  • ¥15 fluent的在模拟压强时使用希望得到一些建议
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用
  • ¥15 Web.config连不上数据库
  • ¥15 我想付费需要AKM公司DSP开发资料及相关开发。
  • ¥15 怎么配置广告联盟瀑布流