近日遇到Greenplum数据库执行部份SQL会卡住,最终报向某个节点发包失败的错误,此处记录一下排查过程和解决方法。
数据库状态正常,使用gpstate命令查看状态没有任何异常,可以正常进入数据库并查询任意表的数据,但是业务端反馈查询时一直卡住,没有数据。数据库错误如下:
包含group:
不包含group:
Redistribution需要各个segment之间的相互传输数据,根据之前的报错信息,判断可能是其他segment向172.28.0.148的segment发包失败。
Greenplum为保证效率,segment之间默认使用UDP连接。为确认相关信息,查看数据库参数gp_interconnect_type,该参数解释如下:
使用以下命令查看当前连接协议:
gpconfig -s gp_interconnect_type
可以看出当前连接协议为UDP,尝试修改为TCP连接,命令如下:
gpconfig -c gp_interconnect_type -v tcp
gpstop -arf
修改为TCP连接后,再次执行业务SQL,可以执行成功,至此可以定位为UDP连接问题。
#netstat -s
Ip:
1075974066 total packets received
0 forwarded
0 incoming packets discarded
137873343 incoming packets delivered
3803720 requests sent out
48 dropped because of missing route
1411 fragments dropped after timeout
1072078860 reassemblies required
133978164 packets reassembled ok
239741 packet reassembles failed
215 fragments received ok
1720 fragments created
其中重点关注两个信息:
如果
2.参数调整
1.fragments dropped after timeout场景
当fragments dropped after timeout数值异常时(是否异常可以参考其他节点,现场遇到的正常环境下是5位数,异常环境是10位数),需要调整的参数为net.ipv4.ipfrag_time。
# 检查一下该参数当前数值,内核默认值为30s
#cat /proc/sys/net/ipv4/ipfrag_time
30
# 动态调整
#echo 60 >/proc/sys/net/ipv4/ipfrag_time
#或
#vi sysctl.conf //如果没有该参数就追加
net.ipv4.ipfrag_time = 60
#永久生效
#sysctl -p
#检查是否修改成功
#cat /proc/sys/net/ipv4/ipfrag_time
#60
修改完该参数后可以尝试运行之前不能运行的SQL,如果还是失败,则继续修改下面的参数。
2.packet reassembles failed场景一
该场景下需要注意两个参数,ipfrag_high_thresh和ipfrag_low_thresh,参数简要介绍如下:
需要增大这两个参数值来保证fragment在重组前不被丢弃,具体操作如下:
# 检查一下该参数当前数值
cat /proc/sys/net/ipv4/ipfrag_low_thresh
3145728
cat /proc/sys/net/ipv4/ipfrag_high_thresh
3355443
#将这两个数值增大10倍
# 动态调整
echo 31457280 >/proc/sys/net/ipv4/ipfrag_low_thresh
echo 33554432 >/proc/sys/net/ipv4/ipfrag_high_thresh
#或
#vi sysctl.conf //如果没有该参数就追加
net.ipv4.ipfrag_low_thresh=31457280
net.ipv4.ipfrag_high_thresh=33554430
#永久生效
#sysctl -p
#检查是否修改成功
cat /proc/sys/net/ipv4/ipfrag_low_thresh
31457280
cat /proc/sys/net/ipv4/ipfrag_high_thresh
33554430
修改完该参数后可以尝试运行之前不能运行的SQL,如果还是失败,则继续修改下面的参数。
3.packet reassembles failed场景二
在网络发包的过程中,我们将接收端收到的IP分片依次排队标号,由于网络中有很多其他的流量,属于同一个UDP报文的两个相邻IP分片中间夹杂着其他报文的分片,如果它们编号差(距离)超过ipfrag_max_dist,会导致重组失败。 例如同一个UDP报文的相邻分片距离为95, 而ipfrag_max_dist值设置的小于95,就会造成该分片重组失败。该场景就会造成packet reassembles failed计数增加。需要增大ipfrag_max_dist值,操作如下:
# 检查一下该参数当前数值,一般默认为64
cat /proc/sys/net/ipv4/ipfrag_max_dist
64
#将这两个数值增大至96
# 动态调整
echo 96 >/proc/sys/net/ipv4/ipfrag_max_dist
#或
#vi sysctl.conf //如果没有该参数就追加
net.ipv4.ipfrag_max_dist=96
#永久生效
#sysctl -p
#检查是否修改成功
cat /proc/sys/net/ipv4/ipfrag_max_dist
96