本文介绍 tcp self connection 产生的原因和解决方法。
简述 tcp self connection (TCP 自连接)
OS (操作系统)把 A 端口给进程用来进行 TCP 连接 (该端口从 net.ipv4.ip_local_port_range 中分配),但是发现目标端也是本机的 A 端口,也就是源 IP 地址和端口与目的 IP 地址和端口一致的情况,这样就产生了一条 tcp self connection (TCP 自连接), 即 local::portA<->local:portA,当然这是一个无效的连接,而且一旦建立,如果 portA 是某个服务的监听端口,还有可能导致该服务启动时监听失败。
问题现象
当 OBServer 的网络线程打印 self connect self 时,(或者启动时候打印 bind failed!(errno=98) 时)证明可能 RPC/MySQL 端口被其他进程占用了,也有可能产生了 tcp self connection。
举例如下。
本机机器原先 RPC/MySQL 端口范围如下。

如果本机器 MySQL 和端口的范围为 2800 2850,那么 ip_local_port_range 范围设置为 2851 64000 比较合适(将 RPC/MySQL 端口排除在 port_range 之外,避免建立连接时 client 使用 RPC/MySQL 端口产生 self connection)。或者将 RPC/MYSQL 端口保留在 ip_local_reserved_ports 中,设置 ip_local_reserved_ports = 2800,2850。
问题原因
产生 self connection 本质的原因是 ip_local_port_range 的设置,将本机 RPC/MySQL 端口排除在这个范围外可以避免问题发生。
解决方法
调整动态端口范围。
a. 打开
/etc/sysctl.conf文件并调整ip_local_port_range选项以排除服务端口。net.ipv4.ip_local_port_range = 2851 64000b. 生效配置。
/sbin/sysctl -p保留服务端口。
a. 在
/etc/sysctl.conf文件中设置ip_local_reserved_ports以保留服务端口。net.ipv4.ip_local_reserved_ports = 2800,2850b. 生效配置。
/sbin/sysctl -p使用 tcpkill 终止 tcp self connection (TCP 自连接)。
如果发现已经有自连接产生,可以使用 tcpkill 命令强制断开连接。
示例。

tcpkill -i any -9 port 46774注意
替换
port为实际的端口号。
适用版本
OceanBase 数据库所有版本。