In MySQL 8, when a connection exceeds the wait_timeout period, the server sends an error packet with code 4031. However, gent_tcp:recv successfully receives this packet while the connection is actually closed. This causes test_connection to mistakenly treat it as a valid connection.
The error packet structure is:
{error_packet, 0, 4031, <<"HY000">>, "The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior."}
test_connection(Conn, StayLocked) ->
case catch emysql_tcp:send_and_recv_packet(Conn#emysql_connection.socket, <<?COM_PING>>, 0) of
{'EXIT', _} ->
case reset_connection(emysql_conn_mgr:pools(), Conn, StayLocked) of
NewConn when is_record(NewConn, emysql_connection) ->
NewConn;
{error, FailedReset} ->
exit({connection_down, {and_conn_reset_failed, FailedReset}})
end;
_ ->
NewConn = Conn#emysql_connection{last_test_time = now_seconds()},
case StayLocked of
pass -> emysql_conn_mgr:replace_connection_as_available(Conn, NewConn);
keep -> emysql_conn_mgr:replace_connection_as_locked(Conn, NewConn)
end,
NewConn
end.
When sending a ping package, should we only consider the connection healthy if an OK packet is received? Would this be a better approach?
test_connection(Conn, StayLocked) ->
case catch emysql_tcp:send_and_recv_packet(Conn#emysql_connection.socket, <<?COM_PING>>, 0) of
#ok_packet{} ->
NewConn = Conn#emysql_connection{last_test_time = now_seconds()},
case StayLocked of
pass -> emysql_conn_mgr:replace_connection_as_available(Conn, NewConn);
keep -> emysql_conn_mgr:replace_connection_as_locked(Conn, NewConn)
end,
NewConn
_ ->
case reset_connection(emysql_conn_mgr:pools(), Conn, StayLocked) of
NewConn when is_record(NewConn, emysql_connection) ->
NewConn;
{error, FailedReset} ->
exit({connection_down, {and_conn_reset_failed, FailedReset}})
end;
end.
In MySQL 8, when a connection exceeds the wait_timeout period, the server sends an error packet with code 4031. However, gent_tcp:recv successfully receives this packet while the connection is actually closed. This causes test_connection to mistakenly treat it as a valid connection.
The error packet structure is:
{error_packet, 0, 4031, <<"HY000">>, "The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior."}When sending a ping package, should we only consider the connection healthy if an OK packet is received? Would this be a better approach?