背景:某一天开发反馈在宿主机宕机后,交易过程中,有监控告警交易超时,当时找了DBA进行kill会话,表象是可看见TX锁。而且在DBA kill的会话后,应用也做了重启,但是开发纠结的地方是,为啥该链接解决2个小时10分钟才释放。下面是在测试环境进行实验场景:

数据库超时参数以及TCP半开探究_TCP

1、JAVA脚本开始跑
2、DBA提交变更语句
 update TCP_TEST_LXZ set TYPE = '04' where UUID = '123456';
3、DBA看下库里的锁情况
4、运维执行stress --vm 200 --vm-bytes 25M --vm-keep 将内存打爆
5、DBA看下库里的锁情况,同步第二步执行情况,处于执行中,获取不到锁
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

开始连库时间

数据库超时参数以及TCP半开探究_报文交换_02

断开数据库的时间

数据库超时参数以及TCP半开探究_TCP_03

连库时间持续20分左右。

数据库主机keepalive参数如下:
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_probes=30
net.ipv4.tcp_keepalive_intvl=30

保活时间(tcp_keepalive_time)默认:300秒
保活时间间隔(tcp_keepalive_intvl)默认:30秒
探测循环次数(tcp_keepalive_probes)默认:30次
也就是默认情况下一条TCP连接在5分钟(300秒)都没有报文交换后,会开始进行保活
探测,若再经过30*30秒=15分钟循环探测都未收到探测响应,即共计:20分后会自动断开TCP连接。
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

而我们的生产库,是默认参数

[root@vm01 ipv4]# sysctl -a | grep keepalive
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75
  • 1.
  • 2.
  • 3.
  • 4.

也就是默认情况下一条TCP连接在2小时(7200秒)都没有报文交换后,会开始进行保活探测,若再经过9*75秒=11分钟15秒的循环探测都未收到探测响应,即共计:2小时11分钟15秒后会自动断开TCP连接。