我的mariadb服务器在600秒(10分钟)的不活动状态后正在超时我的c++客户机(使用libmariadb),我不知道为什么,因为我找不到任何指定该数字的已配置超时。
下面是我的代码,我执行一个简单的select查询,等待11分钟,然后再次运行同一个查询,得到一个“server gone”错误:
# include <iostream>
# include <unistd.h>
# include <errmsg.h>
# include <mysql.h>
int main(int, char**)
{
// connect to the database
MYSQL* connection = mysql_init(NULL);
my_bool reconnect = 0;
mysql_options(connection, MYSQL_OPT_RECONNECT, &reconnect); // don't implicitly reconnect
mysql_real_connect(connection, "127.0.0.1", "testuser", "password",
"my_test_db", 3306, NULL, 0);
// run a simple query
mysql_query(connection, "select 5");
mysql_free_result(mysql_store_result(connection));
std::cout << "First query done...\n";
// sleep for 11 minutes
sleep(660);
// run the query again
if(! mysql_query(connection, "select 5"))
{
std::cout << "Second query succeeded after " << seconds << " seconds\n";
mysql_free_result(mysql_store_result(connection));
}
else
{
if(mysql_errno(connection) == CR_SERVER_GONE_ERROR)
{
//****this happens every time****
std::cout << "Server went away after " << seconds << " seconds\n";
}
}
// close the connection
mysql_close(connection);
connection = nullptr;
return 0;
}
服务器进程的标准输出报告我的连接超时:
$ sudo journalctl -u mariadb
...
Jul 24 17:58:31 myhost mysqld[407]: 2018-07-24 17:58:31 139667452651264 [Warning] Aborted connection 222 to db: 'my_test_db' user: 'testuser' host: 'localhost' (Got timeout reading communication packets)
...
查看tcpdump捕获,我还可以看到服务器向客户机发送一个tcp fin数据包,从而关闭连接。
我被难倒的原因是我没有更改任何默认超时值,没有一个值是600秒:
MariaDB [(none)]> show variables like '%timeout%';
+-------------------------------------+----------+
| Variable_name | Value |
+-------------------------------------+----------+
| connect_timeout | 10 |
| deadlock_timeout_long | 50000000 |
| deadlock_timeout_short | 10000 |
| delayed_insert_timeout | 300 |
| innodb_flush_log_at_timeout | 1 |
| innodb_lock_wait_timeout | 50 |
| innodb_print_lock_wait_timeout_info | OFF |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| thread_pool_idle_timeout | 60 |
| wait_timeout | 28800 |
+-------------------------------------+----------+
那为什么服务器会让我的连接超时呢?根据文件,我以为是因为 wait_timeout
服务器变量,但默认为8小时。。。
顺便说一句,我正在使用mariadb 10.0和libmariadb 2.0(来自ubuntuxenial universe repo)
编辑:下面是一个tcpdump捕获捕获断开连接的图像。我的有线鲨鱼过滤器是 tcp.port == 55916
,所以我正在查看与此单客户端连接之间的通信量。服务器发送的fin数据包是数据包1199,正好比前一个数据包(884)晚600秒。
3条答案
按热度按时间7eumitmz1#
wait_timeout
这很棘手。来自同一个连接吗您应该能够通过执行
您是否以“root”身份连接?
更多连接器详细信息:
see:httpshttp://dev.mysql.com/doc/refman/5.5/en/mysql-options.html
客户端交互:在关闭连接之前,允许交互的不活动超时秒数(而不是等待超时秒数)。客户端的session wait \u timeout变量设置为session interactive \u timeout变量的值。
https://dev.mysql.com/doc/relnotes/connector-cpp/en/news-1-1-5.html (mysql连接器/c++1.1.5)
还可以使用mysql\u statement::getquerytimeout()和mysql\u statement::setquerytimeout()方法获取和设置语句执行时间限制。
也可能存在tcp/ip超时。
huwehgph2#
具有haproxy负载平衡的galera集群。在haproxy设置中更改此参数
gcmastyq3#
我不确定确切的原因。但我肯定
wait_timeout
并不是唯一对这有影响的东西。根据您的问题中包含的唯一错误消息,似乎在读取数据包时出现了问题。我认为这更像是mariadb在读取数据包时遇到了问题,而不是试图连接。我还查看了mariadb客户端库,发现了这个块;
https://github.com/mariadb/mariadb-connector-c/blob/master/libmariadb/mariadb_lib.c
因此,当服务器遇到数据包大小问题时,它似乎会将错误代码设置为“服务器消失”。我建议你换个房间
max_allowed_packet
变量到某个较大的值,看它是否有任何影响。https://mariadb.com/kb/en/library/server-system-variables/#max_allowed_packet
我希望它会有所帮助,或者至少它会让您找到解决问题的方法:)最后,我认为您应该处理代码中的断开连接,而不是依赖超时。