mysql 网络io_MySQL的各种网络IO超时的用法和实现

客户端C API

在C API中调用mysql_options()来设置mysql_init() 所创建的连接对象的属性,使用这三个选项可以设置连接超时和读写超时,单位都是秒。读写超时达到后C API的查询发送和结果获取函数会返回超时错误。

MYSQL_OPT_CONNECT_TIMEOUT

MYSQL_OPT_READ_TIMEOUT

MYSQL_OPT_WRITE_TIMEOUT

也可以使用配置文件来设置连接超时和交互超时:

connect-timeout=seconds

interactive-timeout=seconds

当客户端API在向mysql server发起连接connect-timeout秒后没有收到mysql server的相应那么认为连接失败。

interactive-timeout是用于这个客户端连接的交互超时。交互超时用于在交互界面程序(比如mysql这个连接客户端程序)中设置server的会话超时时间,来赋值给wait_timeout会话变量,它通常比较大,因为使用这个交互界面的通常是人类在手动操作,而不是程序执行和发送指令。mysql server默认使用会话变量@@wait_timeout 作为会话的超时,除非在mysql_real_connect中使用CLIENT_INTERACTIVE标志来标识这个连接是用于交互操作,此时如果客户端有interactive-timeout就使用它来作为本会话的会话超时,否则使用服务器端的interactive-timeout作为会话超时设置给wait_timeout。

MySQL Server内部

从下图中可以看出,服务器端关于超时的变量有很多,这里去掉了我们的TDSQL特有的非标准的MySQL/MariaDB的几个超时值。其中的connect_timeout, net_read_timeout, net_write_timeout,slave_net_timeout, interactive_timeout和wait_timeout与网络IO有关。

1b5a176b02a7b0a14aec3a17d9639424.png

其中,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对象销毁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: last_io_errno: 1236是指在最后一次输入/输出操作中出现了错误代码1236。 错误代码1236代表数据库服务器连接超时。这意味着数据库服务器在规定的时间内未响应客户端的请求,可能因为网络问题或服务器负载过高。 当客户端与数据库服务器建立连接后,它会发送查询请求或执行其他操作。服务器必须在一定的时间内响应这些请求。如果服务器在规定时间内未能响应请求,就会发生超时错误。 造成连接超时的原因有很多,如网络延迟、服务器资源不足、数据库负载过高等。解决超时错误的方法包括: 1. 检查网络连接和服务器状况:确保网络连接稳定,并检查服务器的负载和可用资源是否充足,确保数据库服务器能够正常运行。 2. 调整连接超时时间:根据实际情况,适当延长连接超时时间,以便服务器有足够的时间来响应请求。这可以在数据库连接参数中进行相关设置。 3. 优化数据库查询:通过优化查询语句、创建索引和适当调整数据库设计等方式,提高数据库的查询性能,减少响应时间。 4. 分散负载:如果数据库服务器负载过高,可以考虑分散负载到多个服务器上,以提高整体性能。 5. 更新数据库和服务器软件版本:确保数据库和服务器软件版本是最新的,因为软件更新通常会修复一些性能和稳定性问题。 总之,last_io_errno: 1236是连接超时错误的错误代码,通过检查网络连接、服务器负载情况和优化数据库查询等措施,可以解决这个问题。 ### 回答2: last_io_errno: 1236 是MySQL数据库的一个错误代码。该错误代码表示与主从复制相关的问题,具体是指主从数据库之间的连接出现错误。 在MySQL主从复制中,主数据库负责处理所有的操作,并将这些操作的日志记录发送到从数据库进行执行,以保持主从数据库的数据一致性。当从数据库无法连接到主数据库时,就会出现last_io_errno: 1236 错误。 造成last_io_errno: 1236 错误的原因可能有多种,其中包括网络问题、主数据库宕机或者设置的错误等。 解决这个错误的方法可以包括以下几步: 1. 检查网络连接是否正常,确保主数据库和从数据库之间的通信没有问题。 2. 检查主数据库是否正常运行,确保它没有宕机或者出现其他故障。 3. 检查MySQL主从复制的设置是否正确,包括主数据库的binlog配置和从数据库的replication配置是否正确。 4. 尝试重新启动从数据库,以确保它能够重新连接主数据库并进行同步。 如果上述方法无法解决问题,可能需要进一步排查错误的具体原因并根据具体情况采取不同的解决方法。可以通过查看MySQL的错误日志或者运行相应的诊断命令来获取更多的错误信息,以便进行进一步的故障排除。 ### 回答3: last_io_errno: 1236是指最近一次I/O(输入/输出)操作发生的错误代码是1236。 错误代码1236是MySQL数据库中的一个错误代码,表示一个问题出现在处理复制操作时。具体来说,它指示从服务器无法连接到主服务器来获取或处理复制日志事件。 这个错误可能发生在主从复制设置中,当从服务器无法与主服务器建立连接时。可能的原因包括网络问题、访问权限问题或主服务器宕机等。如果无法建立连接,从服务器将无法获取主服务器上的更新日志,并无法进行数据复制。 为了解决这个问题,可以通过以下几个步骤来进行排查: 1. 确保网络连接正常:检查网络连接是否稳定,并确保从服务器能够与主服务器进行通信。 2. 检查访问权限:确保从服务器具有足够的权限来连接和复制主服务器上的数据。检查相关的用户权限和授权设置。 3. 检查主服务器状态:验证主服务器是否处于运行状态,确保没有出现宕机或其他故障。 4. 检查错误日志:查看MySQL错误日志文件,了解更多关于错误的详细信息。错误日志通常位于MySQL安装目录的日志文件夹中。 5. 重新启动从服务器:有时,重新启动从服务器可以解决临时的连接问题。 如果以上步骤都无法解决问题,可以考虑联系数据库管理员或MySQL技术支持人员,以获取更进一步的帮助和支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值