问题背景
公司一台运行 MySQL 8.0 的物理服务器(Dell PowerEdge R740xd,128GB DDR4 ECC 内存),作为生产环境的主库。该机器上线约 18 个月,之前从未出现过硬件问题。
故障现象
7 月初开始,这台 MySQL 服务器出现不定时宕机——平均每 2-3 天一次,时间毫无规律:一次是凌晨 3:00,一次是下午 2:30,一次是上午 10:15。宕机后服务器完全无响应,Ping 不通,只能通过 iDRAC 远程控制台强制重启。
每次宕机后检查系统日志:
|
|
宕机前的日志中没有任何异常记录——没有 OOM Killer,没有 kernel panic 堆栈(默认不输出到串口),没有硬件错误的 edac 报告。系统像是被直接拔了电源一样,没有任何临终遗言。
排查过程
第一轮:怀疑温度和电源
通过 iDRAC 查看系统事件日志(SEL):
|
|
CPU 温度确实偏高(85°C),但还在正常运行范围内(Tcase max 约 95°C)。清理了服务器内部灰尘并更换了散热硅脂后,CPU 温度降到 65°C——但宕机仍然发生。
第二轮:怀疑内核崩溃(kdump 无输出)
配置 kdump 来捕捉内核崩溃时的内存转储:
|
|
下一次宕机后检查 /var/crash/——kdump 没有生成任何转储文件。这说明崩溃的类型非常底层,连内核的 crashkernel 都无法正常加载。
第三轮:启用 MCE 详细日志
怀疑是硬件层面的错误触发,在 /etc/default/grub 中添加内核参数:
|
|
通过 iDRAC 的串口重定向功能捕获下一次宕机时的输出。一周后再次宕机,iDRAC 串口日志中终于抓到了关键信息:
|
|
Machine Check Exception (MCE)——CPU 检测到了无法纠正的 ECC 内存错误(Uncorrectable ECC Error),触发了内核 Panic。
关键信息:
- 错误位置:
CPU:0, Channel:1, DIMM: A2 - 错误类型:ECC 不可纠正错误
- 错误地址:
0x00000006f3c82540(刚好落在 MySQL 的 buffer pool 内存区域)
第四轮:确认内存故障模式
虽然 ECC 内存能纠正单比特错误,但当同一个字节出现超过 1 个比特错误时就超过了 ECC 的纠错能力,触发不可纠正错误。而这种偶发性多比特错误通常意味着内存条即将彻底损坏。
|
|
DIMM A2 早在 7 月 3 日就开始出现可纠正错误(CE)——只是没人关注 edac 日志。CE 累积到无法纠正时就变成了 MCE 导致宕机。
解决方案
- 停机更换内存:联系 Dell 售后,确认 DIMM A2 故障,申请 RMA 更换
- 更换后验证:通过 memtest86+ 对新内存条做全量检测(pass > 3 次)
- 重启应用:确认 MySQL 恢复正常,buffer pool 完整性校验通过
更换内存条后,服务器恢复稳定运行,至今未再宕机。
根因分析
直接原因:DIMM A2 内存条硬件老化导致偶发性不可纠正的 ECC 错误,触发 MCE,内核 Panic 使系统直接宕机。kdump 无法捕获 MCE 级别的 Panic 因为内核已经在极端底层崩溃。
深层原因:可纠正错误(CE)的 edac 日志没有被纳入监控告警体系,内存条在"带病工作"了一周后才演变为不可纠正错误导致宕机。
预防措施
- EDAC 监控告警:通过 Zabbix 监控
/sys/devices/system/edac/mc/mc*/ce_count,单条 DIMM 的 CE 数量 >10 即告警 - iDRAC 告警集成:将 Dell iDRAC 的 SNMP Trap 接入监控系统,硬件可纠正错误立即触发
- 定期硬件巡检:每季度对所有服务器的 SEL 日志和 ECC 统计做一次全面巡检
- 建立硬件故障响应流程:CE 告警 → 24 小时内确认 → 48 小时内安排更换窗口
- 关键服务冗余:MySQL 主库升级为主从架构,让单机故障不至于导致完全不可用
总结
硬件故障不是"会不会发生"的问题,而是"什么时候发生"的问题。ECC 内存的可纠正错误(CE)是硬件健康的"矿工金丝雀"——当它开始频繁出现时,意味着那条内存条离彻底损坏不远了。这次故障的教训不是 ECC 不够强,而是 CE 的 edac 日志沉默了一整周而没有人关注。在运维中,比监控"已经宕机"更重要的是监控"即将宕机"的信号。