DatabaseCampaign: MySQL / concurrency fixes
According to <http://dev.mysql.com/doc/refman/5.5/en/c-api-threaded-clients.html>, a MySQL connection handle must not be used concurrently with an open result set and mysql_use_result() in one thread (DatabaseCampaign::run()), and mysql_query() in another (DatabaseCampaign::collect_result_thread()). This indeed leads to crashes when bounding the outgoing job queue (SERVER_OUT_QUEUE_SIZE), and maybe even more insidous effects in other cases. The solution is to create separate connections for both threads. Additionally, call mysql_library_init() before spawning any threads. Change-Id: I2981f2fdc67c9a2cbe8781f1a21654418f621aeb
This commit is contained in:
@ -13,8 +13,9 @@
|
||||
namespace fail {
|
||||
|
||||
class DatabaseProtobufAdapter {
|
||||
Database *db;
|
||||
Database *db, *db_insert;
|
||||
MYSQL_STMT *stmt;
|
||||
std::stringstream insert_stmt;
|
||||
|
||||
void error_create_table();
|
||||
|
||||
@ -192,8 +193,20 @@ class DatabaseProtobufAdapter {
|
||||
|
||||
|
||||
public:
|
||||
DatabaseProtobufAdapter() : db(0), top_level_msg(0, 0, 0) {}
|
||||
void set_database_handle(Database *db) { this->db = db; }
|
||||
DatabaseProtobufAdapter() : db(0), db_insert(0), stmt(0), top_level_msg(0, 0, 0) {}
|
||||
void set_database_handle(Database *db)
|
||||
{
|
||||
this->db = db;
|
||||
if (!db_insert) {
|
||||
db_insert = db;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set a different database handle to be used in insert_row(). Necessary
|
||||
* if INSERTs are done in a separate thread, while the handle set with
|
||||
* set_database_handle() is still in use concurrently.
|
||||
*/
|
||||
void set_insert_database_handle(Database *db) { db_insert = db; }
|
||||
void create_table(const google::protobuf::Descriptor *);
|
||||
bool insert_row(const google::protobuf::Message *msg);
|
||||
std::string result_table() { return result_table_name; }
|
||||
|
||||
Reference in New Issue
Block a user