一、背景
客户的 H3C UniServer R4950 G5 服务器(配 13 根 64GB 内存条)需要出货前质检,怀疑存在掉件或不良内存条。本次进行 24 小时内存压力测试,验证每根内存条的稳定性,并输出完整测试日志作为交付凭证。
二、服务器硬件配置
2.1 整机信息
| 项目 | 详情 |
|---|---|
| 服务器型号 | H3C UniServer R4950 G5 |
| OEM 厂商 | New H3C Technologies Co., Ltd. |
| 产品代号 | EthanolX |
| 机箱类型 | Rack(机架式) |
| Wake-up Type | Power Switch |
2.2 CPU 配置
| 项目 | 详情 |
|---|---|
| 型号 | AMD EPYC 7513 32-Core Processor |
| 架构 | x86_64 |
| 物理插槽 | 2(Sockets) |
| 每插槽核心数 | 32 |
| 每核心线程数 | 2(SMT) |
| 总核心/线程 | 128 / 256 |
| CPU 家族 | 25 |
| 步进 | 1 |
| 最大频率 | 3681.6 MHz |
| 最小频率 | 1500.0 MHz |
| NUMA 节点 | 2(node0: 0-31,64-95 / node1: 32-63,96-127) |
| L3 缓存 | 256 MiB × 8 实例 |
| 虚拟化 | AMD-V(支持 SEV/SEV-ES) |
2.3 内存配置
| 项目 | 详情 |
|---|---|
| 总内存 | 818 GiB(约 832 GB) |
| 已使用 | 812 GiB |
| 可用 | 3.7 GiB |
| 内存条数 | 13 根 |
| 单根容量 | 64 GB |
| 类型 | Samsung RDIMM(ECC) |
| Swap | 无(0 B) |
三、压测方案设计
3.1 核心目标
-
对 13 根内存条进行 24 小时满载压力测试
-
覆盖多种内存读写模式,暴露潜在不良件
-
监控 ECC 纠错事件,识别单 bit / 多 bit 翻转
-
输出完整日志作为交付凭证
3.2 工具选型
stress-ng
内存压力测试工具,
stress-ng是stress的增强版,支持 70+ 种压力测试模式。
# 安装
sudo apt-get install stress-ng
核心参数说明:
| 参数 | 含义 |
|---|---|
--vm N |
启动 N 个内存压力进程 |
--vm-bytes SIZE |
每个进程占用的内存量 |
--vm-method MODE |
内存压测算法(如 all、xor、hamming) |
--verify |
写后验证,检测位翻转 |
--timeout SECONDS |
测试时长 |
--metrics-brief |
简化输出指标 |
rasdaemon
Linux RAS(Reliability, Availability, Serviceability)工具,专门捕获和记录 ECC 内存错误。
# 安装
sudo apt-get install rasdaemon
# 启动
sudo systemctl enable rasdaemon
sudo systemctl start rasdaemon
ECC 错误类型说明:
| 类型 | 全称 | 含义 | 严重程度 |
|---|---|---|---|
| CE | Correctable Error | 可纠正错误(单 bit 翻转) | ⚠️ 警告 |
| UE | Uncorrectable Error | 不可纠正错误(多 bit 翻转) | ❌ 严重 |
四、压测脚本详解
4.1 完整脚本内容
#!/bin/bash
LOG_DIR="/root/mem_test_logs"
LOG_FILE="$LOG_DIR/stress_$(date +%Y%m%d_%H%M%S).log"
ECC_LOG="$LOG_DIR/ecc_errors_$(date +%Y%m%d_%H%M%S).log"
DURATION=86400 # 24小时 = 86400秒
mkdir -p "$LOG_DIR"
echo "========================================" | tee -a "$LOG_FILE"
echo "内存压测开始时间: $(date)" | tee -a "$LOG_FILE"
echo "服务器: $(hostname)" | tee -a "$LOG_FILE"
echo "总内存: $(free -h | awk '/Mem/{print $2}')" | tee -a "$LOG_FILE"
echo "压测时长: 24小时" | tee -a "$LOG_FILE"
echo "========================================" | tee -a "$LOG_FILE"
# 后台持续监控 ECC 错误,每60秒采样一次
(
while true; do
echo "--- ECC Check: $(date) ---" >> "$ECC_LOG"
sudo ras-mc-ctl --error-count >> "$ECC_LOG" 2>&1
sudo ras-mc-ctl --status >> "$ECC_LOG" 2>&1
sleep 60
done
) &
ECC_PID=$!
# 启动 stress-ng 压测
echo "开始 stress-ng 压测..." | tee -a "$LOG_FILE"
stress-ng \
--vm 32 \
--vm-bytes 800G \
--vm-method all \
--verify \
--timeout ${DURATION}s \
--metrics-brief \
--log-file "$LOG_FILE" \
2>&1 | tee -a "$LOG_FILE"
STRESS_EXIT=$?
# 停止 ECC 监控
kill $ECC_PID 2>/dev/null
echo "========================================" | tee -a "$LOG_FILE"
echo "压测结束时间: $(date)" | tee -a "$LOG_FILE"
echo "stress-ng 退出码: $STRESS_EXIT" | tee -a "$LOG_FILE"
# 最终 ECC 汇总
echo "--- 最终 ECC 错误统计 ---" | tee -a "$LOG_FILE"
sudo ras-mc-ctl --error-count | tee -a "$LOG_FILE"
if [ $STRESS_EXIT -ne 0 ]; then
echo "⚠️ 压测检测到错误,请检查日志!" | tee -a "$LOG_FILE"
else
echo "✅ 压测完成,未发现错误。" | tee -a "$LOG_FILE"
fi
echo "日志保存在: $LOG_DIR" | tee -a "$LOG_FILE"
4.2 脚本设计逻辑
┌─────────────────────────────────┐
│ 启动 ECC 后台监控 │ ← 每 60s 采样 ras-mc-ctl
│ (后台进程 PID 保存) │
└────────────┬────────────────────┘
│ 并行
▼
┌─────────────────────────────────┐
│ stress-ng 32进程 × 800G │ ← 覆盖所有内存行
│ --vm-method all --verify │ ← 多种算法 + 写后验证
│ timeout = 86400s │ ← 24小时
└────────────┬────────────────────┘
│
▼
┌──────────────┐
│ 压测结束 │
└──────┬───────┘
│
▼
┌─────────────────────────────────┐
│ 停止 ECC 监控,输出最终报告 │
│ 日志写入 LOG_DIR │
└─────────────────────────────────┘
4.3 启动与后台运行
使用
nohup确保 SSH 断开后进程不受影响。
# 创建脚本文件
cat > /root/mem_stress_test.sh << 'EOF'
# (粘贴上方脚本内容)
EOF
chmod +x /root/mem_stress_test.sh
# 创建日志目录(重要!nohup 重定向目标要先存在)
mkdir -p /root/mem_test_logs
# 后台启动
nohup /root/mem_stress_test.sh > /root/mem_test_logs/nohup.log 2>&1 &
echo "压测 PID: $!"
4.4 监控命令汇总
# 查看压测是否运行
ps aux | grep mem_stress
# 实时查看压测日志
tail -f /root/mem_test_logs/nohup.log
# 实时查看 ECC 错误
tail -f /root/mem_test_logs/ecc_errors_*.log
# 查看内存占用
free -h
# 查看 ECC 错误汇总
sudo ras-mc-ctl --error-count
五、测试结果解读
5.1 初始测试数据(测试启动约 10 分钟)
内存使用情况:
total used free shared buff/cache available
Mem: 818Gi 817Gi 1.1Gi 32Mi 167Mi 1.0Gi
Swap: 0B 0B 0B
ECC 错误统计:
| Label | CE | UE |
|---|---|---|
| mc#0csrow#2channel#0 ~ mc#1csrow#3channel#7 | 0 | 0 |
注:rasdaemon 识别出 26 个内存通道槽位,初始状态下所有通道的 CE(Correctable Error)和 UE(Uncorrectable Error)均为 0,未发现任何 ECC 错误。
5.2 判断标准
| 测试结果 | 结论 |
|---|---|
| stress-ng 退出码 = 0,ECC CE/UE 全为 0 | ✅ 内存条正常,全部通过 |
| ECC 有 CE(Correctable Error)计数 > 0 | ⚠️ 存在可纠正错误,软故障,需关注 |
| ECC 有 UE(Uncorrectable Error)计数 > 0 | ❌ 存在不可纠正错误,确认不良件 |
stress-ng 报 verify failure |
❌ 内存读写验证失败,确认不良件 |