简体   繁体   中英

MySQL server-side timeout

I have some connection code that causes a timeout when queries take too long. The connection options are setup like this ( timeout is an integer):

sql::ConnectOptionsMap com;
com["hostName"] = url; // Some string
com["userName"] = user; // Some string
com["password"] = pwd; // Some string
com["OPT_RECONNECT"] = true;
com["OPT_READ_TIMEOUT"] = timeout; // Usually 1 (second)
com["OPT_WRITE_TIMEOUT"] = timeout; // Usually 1 (second)

After testing the timeout setup above what I found is that a throw does occur but MySQL continues trying to execute the query. In other words, the below try goes to the catch after the configured timeout with error code 2013 but it doesn't stop MySQL from trying to execute the query (2013 is an error code related to lost connection):

// Other code

try
{
    stmt = con->createStatement();

    stmt->execute("DROP DATABASE IF EXISTS MySQLManagerTest_TimeoutRead");
    stmt->execute("CREATE DATABASE MySQLManagerTest_TimeoutRead");

    stmt->execute("USE MySQLManagerTest_TimeoutRead");
    stmt->execute("CREATE TABLE foo (bar INT)");

    for (int i = 0; i < 100; i++)
        stmt->execute("INSERT INTO foo (bar) VALUES (" + LC(i) + ")");


    // A bit of playing is needed in the loop condition
    // Make it longer than a second but not too long
    // Using 10000 seems to take roughly 5 seconds

    stmt->execute(
        "CREATE FUNCTION waitAWhile() "
            "RETURNS INT READS SQL DATA "
        "BEGIN "
            "DECLARE baz INT DEFAULT 0; "
            "WHILE baz < 10000 DO "
                "SET baz = baz + 1; "
            "END WHILE; "
            "RETURN baz; "
        "END;"
    );

    res = stmt->executeQuery("SELECT 1 FROM foo WHERE bar = waitAWhile()");

} catch (sql::SQLException &e) {
    std::cout << e.getErrorCode() << std::endl;
}

// Other code

I was able to notice that MySQL did not stop by running "top" at the same time as the above testing code. Making the above MySQL waitAWhile() function instead be an infinite loop further confirmed that MySQL was not stopping because I had to kill the MySQL process to make it stop

This kind of timeout is not what I wanted, I wanted MySQL to give up on a query if it took too long. Can this be done (so that both my execution and MySQL stop doing work)? Additionally, can this be specified only for INSERT queries?

You can do it in regular SQL by having SQL Server set a max query execution time. However, it doesn't look like MySQL supports this; see the following accepted SO answer for more details: MySQL - can I limit the maximum time allowed for a query to run?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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