开发反应说应用的某个接口返回过慢,查看日志后发现确实有一个接口的sql执行了20s

log

排查

sql优化

输入sql执行发现执行时间很短而且整个数据库的数据量不是很大,所以可以排查sql优化的问题

网络排查

环境:应用在143上面,数据库在142上面,数据库端口13360

利用tcpdump+wireshark 进行抓包

tcpdump -i bond4.128 port 13360 -w ./mysql_cap

使用wireshark打开选中可用的数据流,找到对应的sql数据tcp流

cap

分析发现从tcp握手到数据库密码认证,经历了20秒(52-105),后面执行数据库用的时间并不多(105-116)

cap1

可以断定是数据库初始化连接的问题,查询相关信息发现有一个相关配置

[mysqld]
skip-name-resolve

修改该配置后,数据访问正常了

扩展

作用

那个这个 skip-name-resolve的配置有什么作用 为什么会导致链接超时

这个主要作用是把ip变成host 或者 host映射成ip的功能,然后放到一个host cache里面 相关文档

那Mysql为什么要这样做捏?

因为Mysql会用这个host cache来追踪这个host的错误情况,对应的相关配置 max_connect_errors

doc

流程

详细的数据库连接和对应的host cache建立 也在文档里面有说明

大概流程

  • 第一次tcp clinet连接到达的时候,Mysql就会初始化对应的cache实例
  • server就会尝试去把 IP to host 或者 name to host 使用 DNS 解析
  • 如果该连接发生错误 就会把数据记录下来

doc

最后

这就是为什么在tcp三次握手后会等待大概20秒左右,就是mysql尝试把连接ip解析host的行为

当然了,这个ip是解析不到host的所以就会出现错误,在docker log 可以看到对应错误

mysql-log
为什么说是172.17.0.1这个ip解析错误捏,不是上述的143这个ip?

那是因为mysql是跑在docker上面的 而流量会经过docker的网卡再到容器里面,而docker的网卡就是172.17.0.1

docker-bridge