暂无图片
暂无图片
3
暂无图片
暂无图片
暂无图片

Oracle 19c RAC 私网丢块 9831 次,根因竟是 208KB 的 socket 缓冲?

248

实战复盘:AWR 定位异常 → OS 层验证铁证 → 锁定根因 → 分级修复,全程只读、零生产变更。

上周处理了一个 Oracle 19c RAC 的疑难杂症:AWR 里 gc cr block lost 高达9831 次,平均每次等待552ms,占 DB Time15.7%,排到了 Top 2 等待事件。
一开始怀疑是私网物理链路的问题(网线、交换机、CRC 错误),逐层排查到最后发现——罪魁祸首是 RHEL 默认的 208KB socket 缓冲,UDP 一满就丢包。
这篇把完整的排查思路、关键证据和修复方案分享出来,遇到类似问题的朋友可以少走弯路。

一、现象:AWR 报告暴露的异常

诊断对象:11.12.30.107(trmvdb51)/ 11.12.30.108(trmvdb52),双节点 Oracle 19c RAC
问题时段:AWR Snap 23948 → 23949(2026-08-17 12:00:05 ~ 12:30:12,30.13 分钟)
诊断方式:全程只读,未做任何修改

1.1 Top 10 等待事件

事件
次数
总等待(秒)
平均等待
%DB Time
DB CPU
-
8,351.7
-
24.2
gc cr block lost
9,831
5,427.4
552.07ms
15.7
db file sequential read
1,437,573
4,334.6
3.02ms
12.6
read by other session
1,343,079
1,604.2
1.19ms
4.7
gc buffer busy acquire
120,722
404
3.35ms
1.2
enq: TX - row lock contention
1,032
300.5
291.19ms
0.9
gc current block lost
490
267.2
545.32ms
0.8
log file sync
152,597
210.5
1.38ms
0.6
db file parallel read
26,162
191.1
7.31ms
0.6
direct path read
30,508
152.8
5.01ms
0.4

1.2 Wait Class 汇总

Wait Class
总等待(秒)
%DB Time
平均活动会话
DB CPU
8,352
24.2
4.6
Cluster
6,756
19.6
3.7
User I/O
6,382
18.5
3.5
Administrative
500
1.4
0.3
System I/O
342
1.0
0.2
Cluster 等待类占 DB Time 19.6%,仅次于 DB CPU——两节点之间的交互确实存在问题。

1.3 ADDM 的官方结论

Finding:Global Cache Lost Blocks(影响 3.35 active sessions,17.55%)、Global Cache Messaging(3.57,18.69%)
原文:"Cluster communications that were retried due to lost blocks consumed significant database time."
Recommendation 1(Host Configuration):*"Check the configuration of the cluster interconnect. Check OS setup like adapter setting, firmware and driver release.Check that the OS's socket receive buffers are large enough to store an entire multiblock read."*
注意加粗那句——socket receive buffers,Oracle 官方早就把排查方向指出来了。

二、推理:从 AWR 到 OS 层的 4 步排查链

第 1 步:定位异常事件类型

gc cr block lost / gc current block lost 平均等待552ms,远超正常 GCS 消息延迟(几百 μs ~ 1ms)。
这个量级是GCS 消息超时重传的特征,不是普通缓存争用。

第 2 步:排除物理链路故障

AWR Interconnect Statistics 显示 8K 消息平均延迟158μs(在 1ms 可接受范围内);
私网设备 ens224:1 的 send/receive errors、dropped、overrun、frame errors全为 0。
→ 不是网线/交换机质量问题,也不是 CRC 错误。

第 3 步:锁定协议与缓冲区

alert log 显示 interconnect 走IPCLW over UDP(不可靠协议,无重传);
net.core.rmem_max
仅208KB。
UDP 缓冲一满即丢、没有重传,这正是 lost block 的根源。

第 4 步:双向验证

两节点 alert log 都出现 IPC Send timeout,且方向相反(107→实例2,108→实例1),证明问题在共享私网链路而非单边故障。

三、证据:双节点对比 + 参数诊断表

3.1 双节点关键指标对比

指标
107(trmvdb51)
108(trmvdb52)
OS 内核
3.10.0-957.el7.x86_64
3.10.0-957.el7.x86_64
网卡驱动
vmxnet3(VMware 虚拟网卡)
vmxnet3
私网速率
10000Mb/s(万兆)
10000Mb/s
MTU
1500(未开 Jumbo)
1500(未开 Jumbo)
ring buffer RX / TX
1024 / 512(最大 4096)
1024 / 512(最大 4096)
net.core.rmem_max
212992(208KB)
212992(208KB)
net.core.wmem_max
212992(208KB)
212992(208KB)
net.core.netdev_max_backlog
1000
1000
receive buffer errors
7,221,867
6,409,925
= packet receive errors
7,221,867
6,409,925
segments retransmited
9,628,359
9,934,996
fragments dropped after timeout
22,797,666
14,500,821
alert log IPC 超时
IPC Send timeout to 2.1 … Terminating pid
IPC Send timeout to 1.3 … Terminating pid(多处)
THP enabled / defrag
never / always
never / always
HugePages_Total
0
0
最关键的证据:双节点的 receive buffer errors 与 packet receive errors数值完全相等(数百万级)——丢包 100% 来自 UDP 接收缓冲不足,而不是物理链路 FCS/CRC 错误。

3.2 参数诊断对照表

表 A:sysctl 内核网络参数(核心,丢包主因)
关键字
含义
当前实测值
正常/推荐值(Oracle RAC 最佳实践)
判断
net.core.rmem_max
socket 接收缓冲上限
212992(208KB)
≥ 4194304(4MB),高负载建议 16MB
❌ 偏小 20~80 倍
net.core.wmem_max
socket 发送缓冲上限
212992(208KB)
≥ 4194304(4MB)
❌ 偏小
net.core.rmem_default
默认接收缓冲
212992
262144 起,与 max 对齐
❌ 偏小
net.core.wmem_default
默认发送缓冲
212992
同上
❌ 偏小
net.core.netdev_max_backlog
收包队列深度
1000
≥ 5000
❌ 偏小
表 B:网卡参数
关键字
含义
当前实测值
正常/推荐值
判断
MTU(私网 ens224)
单帧大小
1500
9000(Jumbo,两端+交换机需一致)
⚠️ 未优化
ring buffer RX
网卡收包环深度
1024
4096(拉满)
⚠️ 未拉满
ring buffer TX
网卡发包环深度
512
4096(拉满)
⚠️ 未拉满
网卡驱动
-
vmxnet3(虚拟化网卡)
物理网卡更优(现状如此)
⚠️ 虚拟化放大丢包
表 C:netstat 关键指标(丢包性质的「铁证」)
关键字
含义
正常值
实测(656 天累计)
判断
receive buffer errors
接收缓冲不足导致丢包
0 或极小
数百万
❌ 铁证:缓冲太小
packet receive errors
网络层接收错误
0
与上完全相等
❌ 丢包 100% 来自缓冲,非物理链路
segments retransmited
TCP 重传段数
占比极小
962 万 / 993 万
❌ 重传严重
fragments dropped after timeout
IP 分片超时丢弃
0
2279 万 / 1450 万
❌ 分片丢包(MTU 1500 + 大消息)

四、根因结论

vmxnet3 虚拟网卡(万兆) + MTU 1500 + ring 1024 + LMS 未绑核        ↓ 放大效应socket 缓冲仅 208KB(RHEL 默认值,未做 RAC 优化)        ↓GCS 大消息/多块读 → UDP 缓冲溢出 → 丢包(receive buffer errors 数百万)        ↓LMS 收不到响应 → gc cr/current block lost(AWR 9831 次 × 552ms)        ↓IPC Send timeout → Terminating pid(历史反复出现,佐证机制)
主因:interconnect 走 UDP + socket 缓冲 208KB(未优化)。
放大因素:虚拟化 vmxnet3 网卡、未开 Jumbo Frame、ring buffer 未拉满、LMS 未绑核。

一句话总结:UDP 是不可靠协议,缓冲一满就丢包,而 RHEL 默认的 208KB 缓冲根本不够 RAC 私网在高负载下用。


五、修复方案(含修改用户 / 路径 / 文件 / 重启提示)

5.1 修改项总览

#
修改项
当前值
目标值
修改用户
是否需重启
1
net.core.rmem_max
212992
4194304
root
临时生效,实例重启才完全生效
2
net.core.wmem_max
212992
4194304
root
同上
3
net.core.rmem_default
212992
4194304
root
同上
4
net.core.wmem_default
212992
4194304
root
同上
5
net.core.netdev_max_backlog
1000
5000
root
同上
6
ring buffer RX / TX
1024/512
4096/4096
root
ethtool 即时;OS 重启需持久化
7
私网 MTU(Jumbo)
1500
9000
root
需重启网卡(高风险)
8
THP defrag
always
never
root
echo 即时;grub 需 OS 重启
9
LMS 绑核
0-63
按需
oracle
需重启实例
10
HugePages
0
按 SGA
root+oracle
需重启实例

5.2 核心修复:socket 缓冲(优先级最高,解决丢块主因)

修改文件:新建 /etc/sysctl.d/99-oracle-rac.conf(两节点各建一份,内容一致)
修改用户:root
▶ root | /etc/sysctl.d/99-oracle-rac.conf | RAC interconnect socket 缓冲优化net.core.rmem_max = 4194304net.core.wmem_max = 4194304net.core.rmem_default = 4194304net.core.wmem_default = 4194304net.core.netdev_max_backlog = 5000
加载方式:
sysctl -p /etc/sysctl.conf
重启要求(重要):
sysctl -p
立即改写内核当前值,无需重启 OS;
但 Oracle LMS / 前台进程的 socket 在实例启动时已按旧值建立,rmem_max 提升只对新建 socket生效;
因此完全生效需滚动重启数据库实例(或重启 CRS),让 LMS 重新建 socket。
建议路径:先改内核值 → 择变更窗口滚动重启实例 → 观察效果。
验证方法:
sysctl net.core.rmem_max net.core.wmem_max确认新值netstat -s | grep -i 'receive buffer errors' # 观察是否停止增长grep -i 'IPC Send timeout' /u01/app/oracle/diag/rdbms/trmvdb5/trmvdb51/trace/alert_trmvdb51.log | tail # 观察是否再刷

5.3 辅助优化:ring buffer 拉满

修改方式(root,运行时即时生效):
ethtool -G ens224 rx 4096 tx 4096
持久化文件:/etc/rc.d/rc.local(追加命令并 chmod +x /etc/rc.d/rc.local)
▶ root | /etc/rc.d/rc.local | 网卡 ring buffer 持久化ethtool -G ens224 rx 4096 tx 4096
重启要求:ethtool -G 即时生效,但OS 重启后失效,故需 rc.local 持久化。

5.4 辅助优化:私网开 Jumbo Frame(高风险,放最后)

修改文件:/etc/sysconfig/network-scripts/ifcfg-ens224(两节点的私网 IP 对应网卡)
▶ root | /etc/sysconfig/network-scripts/ifcfg-ens224 | 追加 MTUMTU=9000
重启要求:需重启网卡生效(ifdown ens224 && ifup ens224)。
⚠️高风险提示:
重启私网网卡会瞬间中断 interconnect,可能触发 CRS 节点驱逐、VIP 漂移;
Jumbo Frame 要求两端 + VMware 虚拟交换机同时支持且一致,任一端不一致会导致丢包更严重;
必须走变更窗口,逐节点操作,操作前确认 VIP/服务已切换,不建议作为首轮修复项。

5.5 辅助优化:THP defrag 关闭(次要,非丢块主因)

即时生效(root):
echo never > /sys/kernel/mm/transparent_hugepage/defrag
持久化(grub,需 OS 重启):编辑 /etc/default/grub,在 GRUB_CMDLINE_LINUX 追加 transparent_hugepage=never,然后:
grub2-mkconfig -o /boot/grub2/grub.cfg
重启要求:echo 即时生效但重启丢失;grub 方式需 OS 重启。

六、实施顺序与风险提示

建议顺序(按性价比/风险从低到高):
socket 缓冲(5.2)—— 风险最低、收益最大,首轮必做;
ring buffer(5.3)—— 即时生效,可同窗口做;
择变更窗口滚动重启实例,让 socket 缓冲完全生效;
观察 1~2 个业务高峰:receive buffer errors 是否停止增长、alert log 是否还刷 IPC Send timeout、AWR 里 gc cr/current block lost 是否消失;
效果不足再评估Jumbo Frame(5.4,高风险)与LMS 绑定(5.6)。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论