在C API中调用mysql_options()来设置mysql_init() 所建立的链接对象的属性,使用这三个选项能够设置链接超时和读写超时,单位都是秒。读写超时达到后C API的查询发送和结果获取函数会返回超时错误。mysql
MYSQL_OPT_CONNECT_TIMEOUTsql
MYSQL_OPT_READ_TIMEOUT数据库
MYSQL_OPT_WRITE_TIMEOUT服务器
也能够使用配置文件来设置链接超时和交互超时:网络
connect-timeout=secondssocket
interactive-timeout=seconds函数
当客户端API在向mysql server发起链接connect-timeout秒后没有收到mysql server的相应那么认为链接失败。post
interactive-timeout是用于这个客户端链接的交互超时。交互超时用于在交互界面程序(好比mysql这个链接客户端程序)中设置server的会话超时时间,来赋值给wait_timeout会话变量,它一般比较大,由于使用这个交互界面的一般是人类在手动操做,而不是程序执行和发送指令。mysql server默认使用会话变量@@wait_timeout 做为会话的超时,除非在mysql_real_connect中使用CLIENT_INTERACTIVE标志来标识这个链接是用于交互操做,此时若是客户端有interactive-timeout就使用它来做为本会话的会话超时,不然使用服务器端的interactive-timeout做为会话超时设置给wait_timeout。spa
从下图中能够看出,服务器端关于超时的变量有不少,这里去掉了咱们的TDSQL特有的非标准的MySQL/MariaDB的几个超时值。其中的connect_timeout, net_read_timeout, net_write_timeout,slave_net_timeout, interactive_timeout和wait_timeout与网络IO有关。线程
其中,connect_timeout 被用于在用户登陆期间,也就是创建数据库链接期间,做为mysql server端的网络读写超时。这与文档上面的说法并不相同,可是代码中确实是这样子的。
net_read_timeout 和net_write_timeout是数据库会话建立好以后mysql server端使用的读写超时。若是读取或者写入操做在等待了达到超时后服务器认为客户端链接断开,执行错误处理。
而slave_net_timeout是slave的io线程使用客户端C API链接master时候,调用mysql_options()来设置MYSQL_OPT_CONNECT_TIMEOUT,MYSQL_OPT_READ_TIMEOUT,MYSQL_OPT_WRITE_TIMEOUT这三个超时选项使用的值。IO线程链接master使用的都是标准的客户端C API代码和通讯协议。
最后,wait_timeout是mysqld server的默认的会话超时,若是一个数据库链接(会话)在这么长时间以后没有任何读写动做,那么这个链接被关闭。interactive_timeout是默认的交互式链接的会话超时,会设置给wait_timeout,若是客户端有自定义的值,那么那个值会被优先使用来设置给wait_timeout。
全部这些超时能够分为链接超时,读写超时和会话超时三类,下面就讲一下这些超时机制是如何实现的。
在Linux的connect(), recv, send, read(), write()等系统调用中,并不能够简单地阻塞等待一段指定时间后再返回错误,而是要么把文件句柄设置为非阻塞的(使用fcntl()和O_NONBLOCK标志,或者对于recv/send()能够每次调用使用MSG_DONTWAIT)而且马上返回,要么一直阻塞等待。因此,要实现超时仍是要一点小技巧的。另外,MySQL中网络IO的代码不管是客户端C API的网络IO功能仍是服务器内部使用的网络通讯功能,都是同一份代码实现,所以下文不须要区分客户端和服务器端。
相关函数:vio_socket_connect(),vio_io_wait()
首先,若是有链接超时时间的话,就设置socket fd为非阻塞的,而后调用标准的socket函数connect()来发起链接,这个函数会当即返回-1而且设置errno为 EINPROGRESS或者EALREADY。而后,调用vio_io_wait()来使用poll()来阻塞等待这个链接能够写入,使用链接超时值做为poll()的超时参数。这样,在等待超时后就认为链接失败,不然链接就成功了。这里并无使用网络协议本身的链接超时,由于那样的话没法在不影响其余进程的状况下随时灵活更改这个超时时间。
相关函数:vio_read(), vio_write(), vio_socket_io_wait()
首先,调用标准的recv()/send()系统调用来读取或者写入,若是有读写超时时间的话,就使用MSG_DONTWAIT做为最后一个flags参数,这样若是没有数据能够读取或者没法写入(好比网络拥塞)这个函数会马上返回SOCKET_EAGAIN 或者SOCKET_EWOULDBLOCK,因而,调用vio_socket_io_wait()来阻塞等待这个socket fd能够读或者写,这个函数主要是调用了poll(),而且用读写超时值做为poll()的等待超时时间。
这里的会话(Session)其实就是数据库链接,在mysql内部对应于THD类。会话超时是Mysql server端才有的机制,在客户端没有。实现方法是:Mysql server内部线程按期检查全部THD会话对象的状态,将会话超时的THD对象销毁。