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.
I have an application that spawns 100 threads. Yes, I spawn 100 of them because most of them would be busy in I/O or other tasks, other than database updates.
sql::Driver * driver
variable, that is visible to the entire application. I call driver = get_driver_instance();
at the very start of the application. 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
. I store this connection in the ith location of the connArray array.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:
Lost connection to MySQL server during query Error Code: 2013 SQL State: HY000
Also, sometimes (intermittently again!), executeUpdate from either InsertFunction
or UpdateFunction
hangs. 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?
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. If you need to send queries in parallel, consider creating separate MySQL connection handle per thread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With