必须将私网mtu设为9000,否则gc消息因分片严重导致丢包、重传及lms排队,进而引发节点驱逐或ora-600[kjctr_pbmsg:badbmsg2];默认mtu=1500无法满足rac interconnect中几kb至64kb的gc大消息传输需求。
必须改 mtu 到 9000,否则 gc 消息分片严重,丢包、重传、lms 排队会直接引发节点驱逐或 ora-600 [kjctr_pbmsg:badbmsg2]。
为什么默认 MTU=1500 在 RAC Interconnect 上根本不够用
Oracle RAC 的全局缓存(GC)消息动辄几 KB 到 64KB:DB_BLOCK_SIZE × db_file_multiblock_read_count 默认就是 8K × 128 = 1MB(实际按网络路径切分),PARALLEL_EXECUTION_MESSAGE_SIZE 默认 16KB。这些大消息在 MTU=1500 下会被强制分片成大量小包,导致:
- 网卡和内核需频繁做 IP 分片/重组,CPU 开销陡增
- 任意一个分片丢包,整个消息就得重传(UDP 无重传机制,RDS 也依赖底层)
- netstat -s 输出中
packet reassembles failed持续上升,就是典型征兆 - OSWatcher 日志里
reasm_fails增长,基本可判定是 MTU 不足
如何安全地将私网 MTU 设为 9000(Jumbo Frame)
不是所有设备都支持 Jumbo Frame,必须端到端一致;改错会导致心跳中断、节点驱逐。操作前确认:
- 所有 RAC 节点私网网卡(如
eth1)驱动支持 jumbo frame(ethtool eth1查看Supports jumbo frames) - 连接私网的交换机(非管理口、非直连!)已全局启用 jumbo frame(MTU ≥ 9000)
-
/etc/hosts和 DNS 中私网 IP 解析未混用公网接口
生效命令(临时):ip link set dev eth1 mtu 9000
永久配置需写入网卡配置文件(如 RHEL 的 /etc/sysconfig/network-scripts/ifcfg-eth1 加 MTU=9000),重启 network 或 reload systemd-networkd。
UDP 缓冲区和 RDS 协议的选择影响真实吞吐
MTU 改了只是基础,UDP 缓冲太小照样丢包。检查并调大:
-
net.core.rmem_max和net.core.wmem_max至少设为26214400(25MB) -
net.ipv4.udp_mem第三项(max)建议 ≥50000000 - RAC 10.2.0.3+ 可启用
RDS协议(比 UDP 延迟低、CPU 消耗少),需在sqlnet.ora中设ipc.ora相关参数,并确保内核加载rds模块(lsmod | grep rds)
注意:RDS 要求所有节点 OS 内核版本一致且支持,不兼容某些定制化内核;UDP 更通用但必须配够缓冲区。
验证 Interconnect 是否真跑在 9000 MTU + 低丢包上
改完不能只看 ip link show,要测通路有效性:
- 用
ping -M do -s 8972 node2_private_ip测试能否无分片直达(8972 = 9000 − 28 字节 IP+ICMP 头) - 查
netstat -s | grep -A 5 -B 5 "reasm",确认reasm_oks显著上升、reasm_fails归零或极低 - 查
ifconfig eth1输出中TX/RX errors、overruns不再增长;dropped应接近 0 - AWR 报告中 “Global Cache” 部分的
Global cache blocks served与received差值缩小,说明传输效率提升
真正难的是交换机侧配置和跨厂商兼容性——很多“已配 MTU=9000”的交换机,其实只在物理口生效,VLAN 或 LACP 聚合口仍走默认值,这点极易被忽略。











