MariaDB 서버가 600초 후 클라이언트 접속 타임아웃
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;
}
서버 프로세스의 stdout이 접속을 타임아웃했다고 보고합니다.
$ 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시간으로 되어 있습니다.
참고로 마리아DB 10.0 및 libmariadb 2.0을 사용하고 있습니다(Ubuntu Xenial Universe repo에서 제공).
편집: 연결 해제를 포착한 tcpdump 캡처 이미지입니다.My Wireshark 필터는tcp.port == 55916
이 1개의 클라이언트 접속으로 송수신 되는 트래픽을 조사합니다.서버가 송신하는 FIN 패킷은, 패킷 1199 로, 앞의 패킷(884)으로부터 정확히 600 초 후에 송신됩니다.
wait_timeout
까다롭습니다.같은 관계에서와 같은
SHOW SESSION VARIABLES LIKE '%timeout%';
SHOW SESSION VARIABLES WHERE VALUE BETWEEN 500 AND 700;
를 실행하여 문제를 해결할 수 있어야 합니다.
mysql_query("SET @@wait_timeout = 22222");
'root'로 연결되어 있습니까?
커넥터 상세:
참조: https://dev.mysql.com/doc/refman/5.5/en/mysql-options.html
CLIENT_INTERACTIVE: 연결을 닫기 전에 interactive_timeout 초가 아닌 interactive_timeout 초를 허용합니다.클라이언트의 session wait_timeout 변수는 session interactive_timeout 변수 값으로 설정됩니다.
https://dev.mysql.com/doc/relnotes/connector-cpp/en/news-1-1-5.html (MySQL 커넥터/C++ 1.1.5)
MySQL_Statement::getQueryTimeout() 및 MySQL_Statement::setQueryTimeout() 메서드를 사용하여 스테이트먼트 실행 시간 제한을 가져오고 설정할 수도 있습니다.
TCP/IP 타임아웃도 있을 수 있습니다.
정확한 이유는 잘 모르겠어요.하지만 난 확신해wait_timeout
여기에 영향을 미치는 것은 그것뿐만이 아닙니다.질문에 포함된 유일한 오류 메시지에 따르면 패킷을 읽는 데 문제가 있었던 것 같습니다.
Got timeout reading communication packets
MariaDB가 접속을 시도한다기보다는 패킷을 읽는 데 문제가 있었던 것 같습니다.MariaDB 클라이언트 라이브러리도 보고 이 블록을 찾았습니다.
if (ma_net_write_command(net,(uchar) command,arg,
length ? length : (ulong) strlen(arg), 0))
{
if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
{
my_set_error(mysql, CR_NET_PACKET_TOO_LARGE, SQLSTATE_UNKNOWN, 0);
goto end;
}
end_server(mysql);
if (mariadb_reconnect(mysql))
goto end;
if (ma_net_write_command(net,(uchar) command,arg,
length ? length : (ulong) strlen(arg), 0))
{
my_set_error(mysql, CR_SERVER_GONE_ERROR, SQLSTATE_UNKNOWN, 0);
goto end;
}
}
https://github.com/MariaDB/mariadb-connector-c/blob/master/libmariadb/mariadb_lib.c
패킷 사이즈의 문제가 발생했을 때, 에러 코드를 server away로 설정하는 것 같습니다.에는 '바꾸준히 .max_allowed_packet
영향을 미치는지 여부를 확인합니다.
SET @@global.max_allowed_packet = <some large value>;
https://mariadb.com/kb/en/library/server-system-variables/ # max _ allowed _ _packet
그것이 도움이 되거나 적어도 문제를 해결할 수 있는 길을 열어주기를 바랍니다.마지막으로 타임아웃에 의존하지 말고 코드로 절단 처리를 해야 한다고 생각합니다.
Haproxy 로드밸런싱을 사용하는 Galera 클러스터.happroxy 설정에서 이 매개 변수 변경
defaults
timeout connect 10s
timeout client 30s
timeout server 30s
언급URL : https://stackoverflow.com/questions/51506416/mariadb-server-times-out-client-connection-after-600-seconds
'source' 카테고리의 다른 글
mysqld: dir를 데이터로 변경할 수 없습니다.서버가 기동하지 않는다 (0) | 2023.01.19 |
---|---|
php에서는 0은 비어 있는 것으로 취급됩니까? (0) | 2023.01.19 |
Python에서 Linux 콘솔 창 너비를 가져오는 방법 (0) | 2023.01.19 |
비트필드에서 비트 엔디안이 문제가 되는 이유는 무엇입니까? (0) | 2023.01.19 |
등록되지 않은 컴포넌트를 기반으로 한 Vue.js 빌드에 실패할 수 있습니까? (0) | 2023.01.19 |