MySQL服务器连接的保持与MYSQLPING的实现原理(mysql_ping)

MySQL服务器连接的保持与MYSQLPING的实现原理

MySQL服务器是一个开源的关系数据库管理系统,据统计,其应用范围已经涵盖了99%以上的Linux平台。而在使用MySQL进行开发的过程中,连接MySQL服务器是必不可少的一步。而MySQL服务器连接的保持问题也是使用MySQL时经常会遇到的问题之一。本文将介绍MySQL服务器连接的保持以及MYSQLPING的实现原理。

MySQL服务器连接的保持

MySQL服务器连接的保持通常是指在某个时间段内,MySQL服务器不主动断开与客户端的连接。在实际应用中,由于客户端需要反复向MySQL服务器上的数据库进行查询操作,一些开发者为了节省连接MySQL服务器的时间与开发成本,可能会将MySQL连接池的连接时长设置为无限长,这样一旦数据库连接被关闭了,MySQL连接池会自动尝试重新建立连接。其结果是MySQL连接所占用的资源始终没有被释放,导致MySQL服务器在运行一段时间后内存占用逐渐增大,最终导致MySQL服务器崩溃。

为了解决这个问题,MySQL提供了两种方法:

1. 使用MySQL的connect_timeout和wt_timeout参数

这两个参数可以帮助管理员更好地控制MySQL与客户端之间的连接时长。其中,connect_timeout是在MySQL服务器收到客户端连接请求后,等待客户端发送起始报文的时间,单位为秒,默认为10秒;wt_timeout是在任何阶段的MySQL连接中,等待下一个命令执行命令的时间。如果在等待命令期间没有任何命令请求,那么MySQL服务器将自动关闭TCP连接,单位为秒,默认为28800秒。

2. 使用MYSQLPING命令

MYSQLPING可以在MySQL与客户端之间定期发送心跳包,以维持长时间的连接。MYSQLPING的工作原理是:在MySQL与客户端之间维持一个轻量级的TCP连接,每隔一段时间发送一个常规SQL语句(比如SELECT @@version),在收到MySQL服务器的响应后,MYSQLPING会自动该TCP连接,并开启一个新的TCP连接,以保持一个长时间的连接。

MYSQLPING的实现原理

MYSQLPING是MySQL5.0.3及更高版本才支持的命令,其设计目的是为了保持MySQL服务器与客户端之间的长连接。MYSQLPING支持在MySQL的客户端和MySQL服务器的两端实现。

在MySQL客户端实现:

在MySQL客户端中,MYSQLPING使用了以下代码片段来实现:

“`c++

const unsigned char MYSQL_PING_SQL[] = {0x53, 0x45, 0x4c, 0x45, 0x43, 0x54, 0x20, 0x40, 0x40, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x53, 0x20}; \

const unsigned int MYSQL_PING_SQL_LEN = sizeof(MYSQL_PING_SQL) – 1;

if (!mysql_ping(sock->mysql))

{

/* Ping OK! */

return MYSQL_SUCCESS;

}

mysql_real_query(sock->mysql, MYSQL_PING_SQL, MYSQL_PING_SQL_LEN);

mysql_store_result(sock->mysql);

mysql_free_result(res);

mysql_thread_end();

return MYSQL_SUCCESS;


MYSQLPING在MySQL客户端中发送一条SQL语句(SELECT @@version),并等待MySQL服务器的响应。如果收到响应,MYSQLPING会自动关闭当前连接,开启一个新的连接以与MySQL服务器保持长连接。

在MySQL服务器实现:

在MySQL服务器中,MYSQLPING使用了以下代码片段来实现:

```c++
static int
sysvar_wt_timeout(THD *thd, set_var *var)
{
/*
MYSQL_PING_INTERVAL is time interval between 2 pings for mntn
persistent connection
*/
const uint MYSQL_PING_INTERVAL= 60;

MYSQL_THDVAR_WT_TIMEOUT *max_idle_time=
(MYSQL_THDVAR_WT_TIMEOUT*) thd->system_thread_vars.var_wt_timeout;
DBUG_ENTER("sysvar_wt_timeout");

if (max_idle_time->timeout == var->val->longlong_value)
DBUG_RETURN(sys_var_swap(thd, var));
if (var->session) /* Connection should be alive */
{
if (!max_idle_time->added_handler)
{
/* Is the timeout just the initial wt_timeout? Then don't ping */
if (var->val->longlong_value == wt_timeout)
{
if (wt_timeout == 1)
my_message(ER_WARN_SERVER_RESET, ER(ER_WARN_SERVER_RESET),
MYSQL_ERROR_LOG_COMPONENT);
}
else
{
max_idle_time->added_handler=1;
max_idle_time->last_ping_time=0;
thd->set_persistent_connection=1;
(*(max_idle_time->add_ping_handler))(max_idle_time);
}
}
else /* Connection already alive */
{
DBUG_ASSERT(thd->system_thread_vars.var_wt_timeout !=
&mysql_system_variables.var_wt_timeout);
DBUG_ASSERT(thd->system_thread_vars.var_wt_timeout == var);
DBUG_ASSERT(thd->system_thread_vars.var_wt_timeout !=
system_variables.var_wt_timeout_ptr);
DBUG_ASSERT(var->val->longlong_value >= MYSQL_PING_INTERVAL);

/* Reschedule handling of wt_timeout events */
(*(max_idle_time->add_ping_handler))(max_idle_time);
}
}
else
max_idle_time->added_handler= 0;
DBUG_RETURN(sys_var_swap(thd, var));
}

MYSQLPING在MySQL服务器中使用了名为“MYSQL_THDVAR_WT_TIMEOUT”的结构体来定期发送心跳包。MYSQL_THDVAR_WT_TIMEOUT结构体的作用是在服务器进程中保持长连接的定时器,以保持MySQL服务器与客户端之间的长连接。在MYSQLPING中,会在定时器到期时调用函数 “max_idle_time->add_ping_handler”来发送心跳包,从而保持长连接。

结语

MySQL服务器连接的保持问题是使用MySQL时经常会遇到的问题之一。在实际开发中,可以通过设置MySQL的connect_timeout和wt_timeout参数来解决这个问题;此外,使用MYSQLPING也是一个不错的选择。通过本文的介绍,相信读者对MySQL服务器连接的保持和MYSQLPING的原理会有一个更加清晰的认识。


数据运维技术 » MySQL服务器连接的保持与MYSQLPING的实现原理(mysql_ping)