必须将私网MTU设为9000,因其是Jumbo Frame标准上限,减去IP/ICMP头后支持8972字节无分片ping;设7000则交换机/驱动通常不识别为巨帧,仍走1500路径;且需ethtool、modinfo、/sys/class/net三处全验证,集群须停机统一配置,否则无效或引发驱逐。
为什么必须把私网MTU设成9000,而不是7000或随便调大
oracle 19c rac的gc(global cache)消息常达几kb到64kb,比如db_block_size × db_file_multiblock_read_count 默认就是8k × 128 = 1mb(实际按路径切分),parallel_execution_message_size 默认16kb。mtu=1500时,这些消息必然被ip层分片——任意一个分片丢包,整个udp消息就得重传(udp无重传机制),直接触发ora-600 [kjctr_pbmsg:badbmsg2]或节点驱逐。
设成9000不是拍脑袋:它对应以太网Jumbo Frame标准上限,减去28字节(20字节IP头 + 8字节ICMP头)后,刚好支持ping -M do -s 8972无分片直达。设7000看似“够用”,但交换机/网卡驱动常只认9000为Jumbo Frame启用阈值,设7000大概率仍走标准帧路径,白调。
ethtool、modinfo、/sys/class/net三处必须全过,缺一不可
内核允许ip link set dev eth1 mtu 9000 ≠ 网卡真能收发9000字节帧。常见失败就卡在这三层验证漏项:
- 运行
ethtool eth1,确认输出含Supports jumbo frames: Yes;若为No,换驱动或网卡是唯一解 - 查驱动参数:
modinfo ixgbe | grep jumbo必须有jumbo_frames字段且默认启用;某些定制内核里该参数被disable,需加options ixgbe jumbo_frames=1到/etc/modprobe.d/ixgbe.conf -
cat /sys/class/net/eth1/mtu显示9000只是内核软设置,不等于硬件生效;Solaris用户还得看dladm show-linkprop -p mtu中POSSIBLE上限是否≥9000
停集群统一改MTU,滚动重启会静默失效
Oracle Clusterware和ASM在启动时固化网络配置,运行中改MTU对已启动实例无效,且可能引发驱逐。别信“先改一个节点试试”——RAC私网是链路敏感型通道,一环掉链子整条链路退化回MTU=1500。
正确操作顺序:
- 所有节点执行
crsctl stop crs,彻底停集群 - 统一执行
ip link set dev eth1 mtu 9000(禁用ifconfig,它在部分内核版本不持久,也不触发驱动重初始化) - 确认
sysctl net.ipv4.ip_forward = 0(私网开转发会导致UDP包路径异常) - 重启前跑
cluvfy comp nodecon -n all -verbose,报告MTU不一致就别硬启
抓包验证UDP GC流量是否真用了巨帧,别只看ip link show
配置全对,Oracle默认仍可能发小包——GC流量走UDP端口12560,但包大小受_gc_affinity_time、TCP MSS协商或底层限制压制。
验证真实效果:
- 用
tshark -i eth1 -f "udp port 12560" -T fields -e frame.len | sort -u抓包,看是否出现>1500的帧(如8972) - 查
netstat -s | grep -i "fragments",若reasm_fails或frag creates持续增长,说明某处链路MTU仍卡在1500 -
lsof -i :12560输出必须含UDP;若看到TCP,说明_use_adaptive_networking被关或网络异常触发回退
真正难的不是改数字,是端到端每一环都得咬死:网卡驱动、交换机端口、直连DAC规格、Oracle UDP栈、甚至OS内核对udp_mem的缓冲区限制——漏掉任何一环,9000就只是个好看的数字。











