必须将私网mtu设为9000,否则gc消息因分片严重导致丢包、重传、lms排队,最终引发节点驱逐或ora-600[kjctr_pbmsg:badbmsg2];因rac全局缓存消息可达几kb至64kb,默认mtu=1500强制分片数十上百包,引发cpu飙升、全包重传及分片重组失败。
必须把私网 mtu 设为 9000,否则 gc 消息分片导致丢包、重传、lms 排队,最终触发节点驱逐或 ora-600 [kjctr_pbmsg:badbmsg2]。这不是可选项,是硬性前提。
为什么默认 mtu=1500 在 RAC Interconnect 上必然失效
RAC 的全局缓存(GC)消息不是小包: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持续上涨,就是 MTU 不足的铁证 - OSWatcher 日志里
reasm_fails增长,基本可锁定问题根源
如何安全设置 mtu=9000 并验证端到端生效
改错会导致心跳中断、节点驱逐,必须端到端确认支持:
- 所有 RAC 节点私网网卡(如
eth1)驱动支持巨帧:ethtool eth1查看Supports jumbo frames - 连接私网的交换机(非管理口!非直连!)已全局启用巨帧,MTU ≥
9000 -
/etc/hosts和 DNS 中私网 IP 解析未混用公网接口 - 临时生效:
ip link set dev eth1 mtu 9000 - 永久生效:在网卡配置文件(如
/etc/sysconfig/network-scripts/ifcfg-eth1)中加MTU=9000,再重启网络服务
验证不能只看 ip link show:
- 用
ping -M do -s 8972 node2_private_ip测试能否无分片直达(8972 = 9000 − 28 字节 IP+ICMP 头) - 检查
netstat -s | grep "reassembles failed"是否归零或不再增长
udp 缓冲区和 rds 协议必须同步调优
MTU 改了只是基础,缓冲区太小照样丢包:
-
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 相关参数,并确保内核加载rds模块(lsmod | grep rds) -
rds要求所有节点 OS 内核版本一致且原生支持,某些定制化内核不兼容;UDP 更通用,但缓冲区必须配足
真正难的不是改几个参数,而是确认交换机、网卡驱动、内核模块、Oracle 协议栈四者协同工作——任何一环掉链子,mtu=9000 就只是个无效数字。











