whitwhoa
whitwhoa

Reputation: 2489

MariaDB C++ Connector errors when attempting connections from multiple threads

Using the MariaDB C++ Connector on ubuntu 20.04, and gcc compiler. During load test of a webserver application it was discovered that anytime there was more than a single concurrent connection the server would crash. This was narrowed down to the connect member of the mariadb driver. The errors that were being reported were always one of the following two:

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid
Aborted (core dumped)

terminate called after throwing an instance of 'std::invalid_argument'
  what():  stoi
Aborted (core dumped)

As it wouldn't be feasible to post the source of the server, I have reproduced a minimal working example that uses only standard library and mariadb/conncpp.hpp:

#include <mariadb/conncpp.hpp>
#include <iostream>
#include <thread>
#include <string>

sql::Driver* driver = sql::mariadb::get_driver_instance();
sql::SQLString connectionUrl = "jdbc:mariadb://localhost:3306/the_database_name";
sql::Properties properties = {{"user", "the_username"}, {"password", "the_password"}};

int main()
{
    // simulate 2 concurrent connections each making 500 requests
    std::vector<std::function<void()>> t1cbs;
    std::vector<std::function<void()>> t2cbs;
    for(int i = 0; i < 500; i++) // if does not fail for you at 500 up the number until it does
    {
        t1cbs.push_back([&]{
            std::unique_ptr<sql::Connection> conn(driver->connect(connectionUrl, properties));
            std::cout << "t1:" << conn->getHostname().c_str() << std::endl;
        });

        // comment out this block to keep the second thread from executing, and you will see 
        // that no errors occur
        t2cbs.push_back([&]{
            std::unique_ptr<sql::Connection> conn(driver->connect(connectionUrl, properties));
            std::cout << "t2:" << conn->getHostname().c_str() << std::endl;
        });
    }

    std::thread t1([&]{
        for(auto& cb : t1cbs)
            cb();
    });

    std::thread t2([&]{
        for(auto& cb : t2cbs)
            cb();
    });

    t1.join();
    t2.join();

    return 0;
}

Curious if there's something perhaps I'm not seeing that's going on that someone else might be able to point out? Although after going through the documentation, it seems pretty straight forward...the only thing maybe is that something's going on in the driver->connect that's not thread safe maybe? Not sure...quite confused...any ideas greatly appreciated!

EDIT After some more research I discovered the following example where it's mentioned that if you have multiple threads then issues could occur...however still trying to figure out how one might circumvent this.

Upvotes: 0

Views: 598

Answers (1)

Georg Richter
Georg Richter

Reputation: 7476

It is a bug in Connector/C++. To track progress, please check https://jira.mariadb.org/browse/CONCPP-105

Upvotes: 1

Related Questions