开发反应说应用的某个接口返回过慢,查看日志后发现确实有一个接口的sql执行了20s
排查
sql优化
输入sql执行发现执行时间很短而且整个数据库的数据量不是很大,所以可以排查sql优化的问题
网络排查
环境:应用在143上面,数据库在142上面,数据库端口13360
利用tcpdump+wireshark 进行抓包
tcpdump -i bond4.128 port 13360 -w ./mysql_cap
使用wireshark打开选中可用的数据流,找到对应的sql数据tcp流
分析发现从tcp握手到数据库密码认证,经历了20秒(52-105),后面执行数据库用的时间并不多(105-116)
可以断定是数据库初始化连接的问题,查询相关信息发现有一个相关配置
[mysqld]
skip-name-resolve
修改该配置后,数据访问正常了
扩展
作用
那个这个 skip-name-resolve
的配置有什么作用 为什么会导致链接超时
这个主要作用是把ip变成host 或者 host映射成ip的功能,然后放到一个host cache里面 相关文档
那Mysql为什么要这样做捏?
因为Mysql会用这个host cache来追踪这个host的错误情况,对应的相关配置 max_connect_errors
流程
详细的数据库连接和对应的host cache建立 也在文档里面有说明
大概流程
- 第一次tcp clinet连接到达的时候,Mysql就会初始化对应的cache实例
- server就会尝试去把 IP to host 或者 name to host 使用 DNS 解析
- 如果该连接发生错误 就会把数据记录下来
最后
这就是为什么在tcp三次握手后会等待大概20秒左右,就是mysql尝试把连接ip解析host的行为
当然了,这个ip是解析不到host的所以就会出现错误,在docker log 可以看到对应错误
为什么说是172.17.0.1
这个ip解析错误捏,不是上述的143这个ip?
那是因为mysql是跑在docker上面的 而流量会经过docker的网卡再到容器里面,而docker的网卡就是172.17.0.1