简体   繁体   English

在多线程环境中使用MySQL C ++ Connector

[英]Use of MySQL C++ Connector in multi-threaded environment

This is in reference to the questions I had asked regarding MySQL C++ Connector and the issues that I am facing regarding it's use in the multi-threaded environment. 这是关于我提出的有关MySQL C ++ Connector的问题以及我在多线程环境中使用的问题。

I have an application that spawns 100 threads. 我有一个产生100个线程的应用程序。 Yes, I spawn 100 of them because most of them would be busy in I/O or other tasks, other than database updates. 是的,我产生了100个,因为除了数据库更新之外,他们中的大多数都会忙于I / O或其他任务。

  1. I have a global sql::Driver * driver variable, that is visible to the entire application. 我有一个全局sql::Driver * driver变量,对整个应用程序可见。 I call driver = get_driver_instance(); 我调用driver = get_driver_instance(); at the very start of the application. 在应用程序的最开始。
  2. I have an array of sql::Connection pointers, connArray which is again, global and before spawning any threads, I open ith connection for the ith thread (using the driver ), and call con->setSchema . 我有一个sql::Connection指针数组,connArray又是全局的,在产生任何线程之前,我打开第i个线程的连接(使用driver ),然后调用con->setSchema I store this connection in the ith location of the connArray array. 我将此连接存储在connArray数组的第i个位置。

Now, this is roughly what I perform in my application (rough code): 现在,这大致是我在我的应用程序中执行的操作(粗略代码):

bool InsertFunction(int threadId)
{
    driver->threadInit(); //Driver is global
    if((connArray[threadId] == NULL) || (connArray[threadId] == NULL && connArray[threadId]->isClosed())
    {
        //Re-Create the connection and store in the connArray
    }
    else
    {
         Create Prepared Statement for Insert
         Set Values
         Execute Update
    }
    driver->threadEnd();
}

bool UpdateFunction(int threadId)
{
    driver->threadInit(); //Driver is global
    if((connArray[threadId] == NULL) || (connArray[threadId] == NULL && connArray[threadId]->isClosed())
    {
        //Re-Create the connection and store in the connArray
    }
    else
    {
         Create Prepared Statement for Update
         Set Values
         Execute Update
    }
    driver->threadEnd();
}

/* Global Region */
sql::Driver * driver;
sql::Connection * connArray[100];

int main()
{
    Array of connections created
    Threads created (I use boost library)
    Post a Job to Boost Thread, RunTask(threadId)
    return 0;
}

RunTask(int threadId)
{
    InsertFunction(threadId);
    pid_t pid = fork();
    if(pid == 0)
       /* Child does some processing */
    else
        /* Parent Waits */
    UpdateFunction(threadId);
}

On executing this code, I get a the following exception intermittently, when I run my application in a quad-core Ubuntu server: 在执行此代码时,当我在四核Ubuntu服务器中运行我的应用程序时,间歇性地得到以下异常:

Lost connection to MySQL server during query Error Code: 2013 SQL State: HY000

Also, sometimes (intermittently again!), executeUpdate from either InsertFunction or UpdateFunction hangs. 此外,有时(间歇性地再次!),来自InsertFunctionUpdateFunction executeUpdate挂起。 I have captured the following backtrace: 我捕获了以下回溯:

(gdb) bt
#0  0x00007fbd55affd2d in read () from /lib/x86_64-linux-gnu/libpthread.so.0
#1  0x00007fbd54398412 in vio_read_buff () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
#2  0x00007fbd5438a51f in ?? () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
#3  0x00007fbd5438b0b8 in my_net_read () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
#4  0x00007fbd543846ba in cli_safe_read () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
#5  0x00007fbd543857e8 in ?? () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
#6  0x00007fbd54381194 in ?? () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
#7  0x00007fbd54381a07 in cli_stmt_execute () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
#8  0x00007fbd54382aed in mysql_stmt_execute () from /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18
#9  0x00007fbd55dddb40 in sql::mysql::NativeAPI::LibmysqlStaticProxy::stmt_execute (this=0x860670,
    stmt=0x7fbd140236c0)
    at /mysql/mysql-src/mysql-connector-c++-1.1.1/driver/nativeapi/libmysql_static_proxy.cpp:475
#10 0x00007fbd55ddfa61 in sql::mysql::NativeAPI::MySQL_NativeStatementWrapper::execute (
    this=0x7fbd1403b0a0)
    at /mysql/mysql-src/mysql-connector-c++-1.1.1/driver/nativeapi/mysql_native_statement_wrapper.cpp:131
#11 0x00007fbd55dbf30d in sql::mysql::MySQL_Prepared_Statement::do_query (this=0x7fbd140233f0)
    at /mysql/mysql-src/mysql-connector-c++-1.1.1/driver/mysql_prepared_statement.cpp:423
#12 0x00007fbd55dbf9be in sql::mysql::MySQL_Prepared_Statement::executeUpdate (this=0x7fbd140233f0)
    at mysql/mysql-src/mysql-connector-c++-1.1.1/driver/mysql_prepared_statement.cpp:531
---Type <return> to continue, or q <return> to quit---
#13 0x0000000000440d96 in SomeNameSpace::SomeClass::InsertFunction (     this=0x7fbd14026930, threadId=11)
    at h/SomeClass.h:295

Can someone please point out where I may be going wrong, or is there anything wrong in the C++ Connector Library of MySQL? 有人可以指出我可能出错的地方,或者MySQL的C ++连接器库有什么问题吗?

If you are using the same connection handle, you need to protect access to it with a lock as MySQL connection API on the low level is not thread-safe. 如果您使用相同的连接句柄,则需要使用锁来保护对它的访问,因为低级别的MySQL连接API不是线程安全的。 If you need to send queries in parallel, consider creating separate MySQL connection handle per thread. 如果需要并行发送查询,请考虑为每个线程创建单独的MySQL连接句柄。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM