实战复盘: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 等待事件
| | | | |
|---|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| enq: TX - row lock contention | | | | |
| | | | |
| | | | |
| | | | |
| | | | |
1.2 Wait Class 汇总
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(不可靠协议,无重传);UDP 缓冲一满即丢、没有重传,这正是 lost block 的根源。第 4 步:双向验证
两节点 alert log 都出现 IPC Send timeout,且方向相反(107→实例2,108→实例1),证明问题在共享私网链路而非单边故障。
三、证据:双节点对比 + 参数诊断表
3.1 双节点关键指标对比
| | |
|---|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| net.core.netdev_max_backlog | | |
| | |
| | |
| | |
| fragments dropped after timeout | | |
| IPC Send timeout to 2.1 … Terminating pid | IPC Send timeout to 1.3 … Terminating pid(多处) |
| | |
| | |
最关键的证据:双节点的 receive buffer errors 与 packet receive errors数值完全相等(数百万级)——丢包 100% 来自 UDP 接收缓冲不足,而不是物理链路 FCS/CRC 错误。3.2 参数诊断对照表
表 A:sysctl 内核网络参数(核心,丢包主因) | | | | |
|---|
| | | ≥ 4194304(4MB),高负载建议 16MB | |
| | | | |
| | | | |
| | | | |
| net.core.netdev_max_backlog | | | | |
表 C:netstat 关键指标(丢包性质的「铁证」) | | | | |
|---|
| | | | |
| | | | |
| | | | |
| fragments dropped after timeout | | | | |
四、根因结论
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 修改项总览
| | | | | |
|---|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| net.core.netdev_max_backlog | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
5.2 核心修复:socket 缓冲(优先级最高,解决丢块主因)
修改文件:新建 /etc/sysctl.d/99-oracle-rac.conf(两节点各建一份,内容一致)▶ 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
但 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 拉满
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 关闭(次要,非丢块主因)
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)。