美文网首页
应用会导致数据库连接超时(timeout)吗?

应用会导致数据库连接超时(timeout)吗?

作者: 重庆八怪 | 来源:发表于2024-08-05 10:29 被阅读0次

    这里我们主要讨论的超时是数据库报警Got timeout writing communication packets,这个错误和net_write_timeout参数相关。

    一、net_write_timeout的生效点

    首先先讨论一下net_write_timeout参数的功能,从代码简单的解析来看,这个参数的生效点主要是在poll上(vio_write函数),大概流程如下,

    • 调用send发送数据
    • 判断send函数的返回码
    • 如果send函数返回的是EAGAIN,大概率就是发送缓存已经满了,如下
    (gdb) p error
    $2 = 11
    (gdb) p SOCKET_EAGAIN
    $3 = 11
    
    • 调用poll对socket链路进行监控,监控事件为POLLOUT ,也就是有socket链路可以写了,这个监控时长接受参数net_write_timeout参数的控制

    如果上面poll出现超时,默认是60秒(net_write_timeout默认值),则会报出日志

    Aborted connection 5 to db: 'unconnected' user: 'test' host: '192.168.1.64' (Got timeout writing communication packets)
    

    二、Got timeout writing communication packets 报警的可能性

    那么结合上面的流程,实际上出现Got timeout writing communication packets的可能性主要有如下,

    • 网络确实有问题
    • 网络实际没问题,应用处理数据的速度太慢了,导致应用的接受缓冲区的数据没有及时取回,这可能附带的应用的压力比较大。

    这两者都可能导致发送缓冲区被占满,对于第二点其实比较隐蔽,一般数据库报错一般都是再找数据库的问题,很少去考虑应用的问题。下面是官方给出的解释也会佐证我们的结论,


    image.png

    其中第一点就是我们说的应用端有问题。这里随意放一张图便于大家理解


    image.png

    三、net buffer和发送缓冲区

    • MySQLD服务端调用read函数从socket的SO_RCVBUF(recv-Q)中读取到SQL语句
    • MySQLD服务端执行语句
    • MySQLD端将查询的每行数据发送到MySQLD 的net buffer
    • 如果MySQLD 的net buffer满,则调用write函数将数据发送到SO_SNDBUF(send-Q

    这里SO_SNDBUF就是发送缓冲区,而SO_RCVBUF就是接收缓冲区

    四、测试

    任何理论都需要测试来验证。这个测试实际上很容易测试,我们只需要mysql客户端堵塞在读取数据的函数上就可以了,并且读取表的数据要比较多,这样才能占满应用端的接受缓冲区和发送端的发送缓冲区。
    下面是我在mysql 客户端的断点生效了,这里就堵塞了应用端接受数据,来模拟应用端处理数据慢,语句就是看到的那个


    image.png

    而在数据库端,的现象如下,


    image.png

    可以看到这个语句的执行事件一直到59秒后,下次就没有了,这个时候回话也断开了。这个就是由于net_write_timeout参数生效了,这个时候服务端会报错日志,


    image.png

    同时这个语句也会造成慢查询,参考,

    相关文章

      网友评论

          本文标题:应用会导致数据库连接超时(timeout)吗?

          本文链接:https://www.haomeiwen.com/subject/epsxkjtx.html