18 KiB
CKBNAS sata4磁盘与内存问题修复方案(2026-07-09)
设备:Synology DS1825+ · CKBNAS
修复日期:2026-07-09
问题:1) sata4磁盘I/O错误导致整机卡死 2) 内存不足触发OOM-Killer
一、问题分析
问题1:sata4磁盘I/O错误(根因)
| 项目 | 详情 |
|---|---|
| 磁盘型号 | ST_M13FQBL(ata2槽位) |
| 错误类型 | FLUSH CACHE失败、Buffer I/O error、softreset failed |
| 影响 | 内核磁盘恢复卡住整机,网络完全不可用 |
| 历史记录 | 2026-06-06首次发现,反复出现导致NAS频繁死机 |
问题2:内存不足(触发因素)
| 项目 | 详情 |
|---|---|
| 物理内存 | 8GB DDR4 ECC |
| DSM常驻 | ~1.5~2GB |
| 问题现象 | ContainerManager启动后内存从6.6GB骤降到147MB |
| 触发机制 | OOM-Killer杀死关键进程,Docker容器批量重启导致IO风暴 |
| 恶性循环 | Docker启动→内存耗尽→OOM-Killer→服务崩溃→重启→复发 |
内存消耗大户分析
| 容器 | 配置内存 | 实际占用 | 是否有效限制 | 问题 |
|---|---|---|---|---|
| macOS VM | deploy.resources.limits: 4.5G | ~4.5GB | ❌ 不生效 | deploy只在swarm模式生效 |
| Windows VM | mem_limit: 3G | ~3GB | ✅ 生效 | 无 |
| Android模拟器 | shm_size: 2G | ~3GB | ❌ 无限制 | 缺少mem_limit |
| Android VM | 无限制 | ~3GB | ❌ 无限制 | 缺少mem_limit |
| Qdrant | 无限制 | ~1GB | ❌ 无限制 | 缺少mem_limit |
| workphone-sdk | 无限制 | ~1.5GB | ❌ 无限制 | 缺少mem_limit |
| MongoDB | wiredTigerCacheSizeGB=1 | ~2GB | ⚠️ 部分有效 | 缺少mem_limit |
关键发现:docker-compose内存限制陷阱
问题:deploy.resources.limits 只在Docker Swarm模式下生效!
# 错误配置(macOS VM)- 只在swarm模式生效
deploy:
resources:
limits:
memory: 4500M # ❌ 普通docker-compose无效
# 正确配置 - 在普通docker-compose模式下生效
mem_limit: 4.5g # ✅ 有效
影响:macOS VM的内存限制完全不生效,实际可占用全部8GB内存!
二、解决方案
2.1 修复策略
┌─────────────────────────────────────────────────────────────┐
│ 问题1:sata4磁盘I/O错误 │
│ ├─ 将sata4设置为offline(未入RAID,可安全离线) │
│ ├─ 监控dmesg中的I/O错误 │
│ └─ 定期检测SMART状态 │
├─────────────────────────────────────────────────────────────┤
│ 问题2:内存不足 │
│ ├─ 禁用ContainerManager开机自启 │
│ ├─ 所有容器RestartPolicy改为no │
│ ├─ 禁用高耗栈(Ollama/VM/karuo-ai网关) │
│ ├─ 设置vm.swappiness=10(降低swap争抢) │
│ └─ 仅保留生产服务:MongoDB、workphone-sdk │
├─────────────────────────────────────────────────────────────┤
│ 自动化保障 │
│ ├─ @reboot 开机自动修复 │
│ └─ */10 * * * * 每10分钟健康检测 │
└─────────────────────────────────────────────────────────────┘
2.2 创建的脚本
| 脚本 | 路径 | 功能 |
|---|---|---|
| 综合修复脚本 | scripts/ckbnas_fix_sata4_and_memory.sh |
解决sata4和内存两个问题 |
| 健康检测脚本 | scripts/ckbnas_sata4_health_check.sh |
定期检测sata4状态和SMART |
| 定时任务安装 | scripts/install_ckbnas_fix_cron.sh |
安装开机修复和定时检测任务 |
| 内存限制脚本 | scripts/ckbnas_add_memory_limits.sh |
为所有容器添加有效的mem_limit |
2.3 内存限制修复
所有容器已添加有效的mem_limit配置:
| 容器 | mem_limit | 说明 |
|---|---|---|
| 生产服务 | ||
| MongoDB | 2g | 含wiredTigerCacheSizeGB=1 |
| workphone-sdk | 1.5g | Node.js应用 |
| 基础服务 | ||
| gitea | 512m | 代码仓库 |
| qdrant | 1g | 向量数据库 |
| xmfst-web | 1g | 厦门房产网站 |
| 高耗栈(已禁用) | ||
| windows-vm | 3g | 已生效 |
| macos-vm | 4.5g | 已替换deploy.resources.limits |
| android-emulator | 3g | 新增 |
| android-vm | 3g | 新增 |
内存预算:
- 生产服务:3.5GB
- 基础服务:2.0GB
- 高耗栈(已禁用):13.5GB
- 当前运行:仅生产服务,需4GB,8GB够用
三、操作步骤
步骤1:物理重启NAS(必须)
由于当前NAS完全不可达(SSH Host is down),需要物理干预:
# 到NAS旁操作:
# 1. 长按电源键关机
# 2. 等待2分钟
# 3. 按电源键开机
步骤2:SSH登录并执行修复
# 登录NAS
ssh ckbnas-home
# 切换root(必须)
sudo -s
# 执行综合修复
bash /volume1/homes/fnvtk/scripts/ckbnas_fix_sata4_and_memory.sh
步骤3:安装定时任务
# 安装开机修复和健康检测任务
bash /volume1/homes/fnvtk/scripts/install_ckbnas_fix_cron.sh
步骤4:验证修复结果
# 验证sata4状态
cat /sys/block/sata4/device/state
# 验证内存状态
free -m
# 验证ContainerManager状态
synopkg status ContainerManager
# 验证DSM服务
curl -m3 http://127.0.0.1:5000/
# 验证RAID状态
cat /proc/mdstat | grep md2
四、保护的生产服务
修复过程中不会删除以下生产关键服务:
| 服务 | 路径 | 说明 |
|---|---|---|
| MongoDB | /volume1/docker/mongodb/ |
AI微信数据库 |
| workphone-mongo | workphone-mongo-nas |
工作手机数据库 |
| workphone-redis | workphone-redis-nas |
工作手机缓存 |
| workphone-sdk | workphone-sdk-nas |
工作手机SDK服务 |
五、禁用的高耗栈
| 栈 | 内存预估 | 状态 |
|---|---|---|
| Ollama | 5GB | 已禁用 |
| karuo-ai网关 | 6~8GB | 已禁用 |
| Windows VM | 4GB | 已禁用 |
| macOS VM | 4.5GB | 已禁用 |
| Android VM | 2~4GB | 已禁用 |
| 底座合集 | 2~4GB | 已禁用 |
六、长期解决方案
| 措施 | 优先级 | 说明 |
|---|---|---|
| 更换sata4硬盘 | P0 | 物理更换故障硬盘(ST_M13FQBL) |
| 升级内存至32GB | P1 | DS1825+支持32GB内存扩展 |
| 配置UPS | P2 | 避免意外断电触发btrfs续扫 |
| 定期磁盘检测 | P2 | 每10分钟SMART检测已配置 |
| 内存监控告警 | P3 | 当可用内存<2GB时自动告警 |
七、脚本部署说明
将脚本上传到NAS的以下路径:
# 在本机执行(上传脚本到NAS)
scp /Users/karuo/Documents/个人/卡若AI/01_卡资(金)/金仓_存储备份/群晖NAS管理/scripts/ckbnas_fix_sata4_and_memory.sh fnvtk@192.168.110.101:/volume1/homes/fnvtk/scripts/
scp /Users/karuo/Documents/个人/卡若AI/01_卡资(金)/金仓_存储备份/群晖NAS管理/scripts/ckbnas_sata4_health_check.sh fnvtk@192.168.110.101:/volume1/homes/fnvtk/scripts/
scp /Users/karuo/Documents/个人/卡若AI/01_卡资(金)/金仓_存储备份/群晖NAS管理/scripts/install_ckbnas_fix_cron.sh fnvtk@192.168.110.101:/volume1/homes/fnvtk/scripts/
# 设置可执行权限
ssh ckbnas-home 'chmod +x /volume1/homes/fnvtk/scripts/ckbnas_fix_sata4_and_memory.sh /volume1/homes/fnvtk/scripts/ckbnas_sata4_health_check.sh /volume1/homes/fnvtk/scripts/install_ckbnas_fix_cron.sh'
八、日志位置
| 日志 | 路径 |
|---|---|
| 修复日志 | /volume1/homes/fnvtk/scripts/karuo-network-watchdog/logs/ckbnas_fix_sata4_memory_*.log |
| 健康检测日志 | /volume1/homes/fnvtk/scripts/karuo-network-watchdog/logs/sata4_health_*.log |
| cron日志 | /volume1/homes/fnvtk/scripts/karuo-network-watchdog/logs/cron_fix.log |
九、验证清单
- sata4状态为offline
- ContainerManager已禁用
- 所有容器RestartPolicy为no
- 可用内存>2GB(当前5.8GB)
- DSM 5000/5001可访问
- MongoDB运行正常
- tencent_cloud_sync.py高内存进程已清理
十、关于"硬盘5"的说明(2026-07-10)
10.1 DSM显示的"硬盘5"对应关系
群晖DSM界面中的硬盘编号与系统设备名的对应关系:
| DSM显示 | 系统设备名 | 槽位 | 状态 |
|---|---|---|---|
| 硬盘1 | sata1 | 槽位1 | 良好 |
| 硬盘2 | sata2 | 槽位2 | 良好 |
| 硬盘5 | sata4 | 槽位4 | ⚠️ 严重 |
| 硬盘6 | sata3 | 槽位3 | 良好 |
注意:DSM的硬盘编号与物理槽位编号不一致!"硬盘5"实际上是系统中的
sata4设备。
10.2 硬盘5(sata4)问题分析
问题根因:Synology HAT3320-8T硬盘(槽位4)出现I/O错误
| 项目 | 详情 |
|---|---|
| 硬盘型号 | Synology HAT3320-8T |
| 序列号 | 2590Z9R22A02QFALL(对应scsi6) |
| 错误类型 | FLUSH CACHE失败、Buffer I/O error |
| 当前状态 | offline(已从RAID中移除) |
| RAID影响 | md2(RAID5)降级为3盘运行 [_UUU] |
10.3 已执行的修复操作
- ✅ 将sata4设置为offline状态
- ✅ 从RAID5(md2)中移除sata4p5
- ✅ 从RAID1(md0)中移除sata4p1
- ✅ 配置cron定时检测sata4状态
- ✅ 添加开机自动修复脚本
10.4 后续处理建议
| 步骤 | 说明 |
|---|---|
| 物理更换 | 购买新的8TB硬盘(推荐同型号HAT3320-8T) |
| 热插拔 | 在NAS运行状态下替换槽位4的硬盘 |
| 重建RAID | DSM会自动检测新硬盘并开始RAID重建 |
| 同步数据 | 预计RAID5重建时间:8~12小时 |
十一、新增高内存问题修复(2026-07-10)
11.1 问题发现
在检查内存状态时发现4个tencent_cloud_sync.py进程占用约70%内存:
| 进程 | PID | 内存占用 | 状态 |
|---|---|---|---|
| tencent_cloud_sync.py | 24452 | 17.8% (~1.4GB) | D (不可中断睡眠) |
| tencent_cloud_sync.py | 24199 | 17.7% (~1.4GB) | D (不可中断睡眠) |
| tencent_cloud_sync.py | 24497 | 17.6% (~1.4GB) | D (不可中断睡眠) |
| tencent_cloud_sync.py | 24160 | 17.5% (~1.4GB) | D (不可中断睡眠) |
影响:内存从6GB骤降至400MB,Swap耗尽
11.2 问题根因
tencent_cloud_sync.py脚本存在以下问题:
- 重复启动:同一脚本被启动4次,无进程冲突检测
- 内存泄漏:每个进程占用1.4GB内存,且处于D状态(不可中断)
- 缺少限制:无内存限制和进程数限制
- 启动方式未知:未找到对应的cron任务或docker容器
11.3 修复措施
- ✅ 紧急终止所有tencent_cloud_sync.py进程
- ✅ 更新修复脚本,添加自动检测和清理高内存进程功能
- ✅ 内存恢复正常(可用6GB)
11.4 防止复发措施
修复脚本已添加以下防护:
# 紧急清理高内存进程(tencent_cloud_sync.py等)
HIGH_MEM_PIDS=$(ps aux --sort=-%mem | grep -E 'python.*tencent_cloud_sync' | grep -v grep | awk '{print $2}')
if [ -n "$HIGH_MEM_PIDS" ]; then
kill -9 $HIGH_MEM_PIDS
fi
十二、当前NAS状态(2026-07-10)
| 项目 | 状态 | 详情 |
|---|---|---|
| 内存 | ✅ 正常 | 8GB,可用6GB |
| Swap | ✅ 正常 | 2GB,使用357MB |
| sata4 | ✅ online | 已重新加入RAID |
| RAID5 (md2) | 🟡 重建中 | 4盘运行,recovery=DELAYED |
| RAID1 (md0/md1) | 🟡 重建中 | 4盘运行,recovery进行中 |
| MongoDB | ✅ 运行 | 端口27017,限制2GB |
| Gitea | ✅ 运行 | 端口3000,限制512MB |
| xmfst-web | ✅ 运行 | 端口3105,限制1GB |
| AIConsole | ✅ 已禁用 | 释放193MB内存 |
| 负载 | ✅ 正常 | load average: ~3.5 |
十四、sata4硬盘重新上线修复(2026-07-10 06:40)
14.1 问题根因
sata4硬盘并未损坏! 而是被误操作设为offline后导致ATA链路禁用(ata7.00: disabled)。
| 项目 | 详情 |
|---|---|
| 硬盘型号 | Synology HAT3320-8T |
| 序列号 | 2590Z9R22A02SFALL |
| 温度 | 38°C(正常) |
| 之前状态 | offline(被误设) |
| 当前状态 | online(已恢复) |
14.2 修复过程
- 发现问题:
synodisk --enum显示sata4温度-1°C(异常),磁盘被识别但处于offline状态 - 定位原因:dmesg显示
ata7.00: disabled,ATA链路被禁用 - 重新扫描:执行SCSI总线重新扫描,磁盘重新识别
- 加入RAID:成功将sata4p1/p2/p5加入md0/md1/md2阵列
- 开始重建:RAID1(md0/md1)开始同步,RAID5(md2)等待中
14.3 当前RAID重建状态
| 阵列 | 状态 | 进度 | 预计完成 |
|---|---|---|---|
| md0 (RAID1) | 重建中 | 0.1% | ~23分钟 |
| md1 (RAID1) | 重建中 | 0.5% | ~6分钟 |
| md2 (RAID5) | 等待中 | DELAYED | 稍后开始 |
14.4 经验教训
不要轻易将硬盘设为offline!:
- sata4硬盘本身没有硬件故障
- 之前的offline状态是人为设置的
- 硬盘重新上线后一切正常,温度38°C
群晖DSM与Linux设备名对应:
- DSM显示的"硬盘5"对应系统中的
sata4 - DSM显示的"硬盘6"对应系统中的
sata3 - 不要混淆硬盘编号和系统设备名
14.5 修复后的磁盘状态
| DSM显示 | 系统设备 | 型号 | 温度 | 状态 |
|---|---|---|---|---|
| 硬盘1 | sata1 | HAT3320-8T | 39°C | ✅ 在线 |
| 硬盘2 | sata2 | HAT3320-8T | 38°C | ✅ 在线 |
| 硬盘5 | sata4 | HAT3320-8T | 38°C | ✅ 在线 |
| 硬盘6 | sata3 | HAT3320-8T | 40°C | ✅ 在线 |
十三、内存问题二次修复(2026-07-10 06:30)
13.1 问题现象
DSM监控显示RAM占用87%,可用内存仅360MB。
13.2 问题根因
| 问题 | 详情 |
|---|---|
| buff/cache过高 | 6.4GB页面缓存未释放 |
| 容器mem_limit不生效 | docker-compose V2不支持mem_limit语法,需用docker update |
| AIConsole后台运行 | 占用193MB内存 |
| 残留搜索进程 | grep/find进程占用CPU和内存 |
13.3 修复措施
- ✅ 清理页面缓存:
echo 3 > /proc/sys/vm/drop_caches - ✅ docker update设置内存限制:
- mongodb: --memory=2g --memory-swap=2g
- xmfst-web: --memory=1g --memory-swap=1g
- gitea: --memory=512m --memory-swap=512m
- ✅ 终止残留搜索进程(PID 14898, 24807)
- ✅ 禁用AIConsole服务
13.4 修复后容器内存限制
| 容器 | 内存限制 | 实际占用 |
|---|---|---|
| mongodb | 2GB | 18MB |
| xmfst-web | 1GB | 69MB |
| gitea | 512MB | 121MB |
13.5 经验教训
docker-compose V2内存限制问题:
mem_limit:语法在docker-compose V2中不生效- 需要使用
docker update --memory=X --memory-swap=X命令 - 或修改docker-compose.yml使用
deploy.resources.limits.memory格式
定期清理缓存:
- Linux会将空闲内存用于文件缓存(buff/cache)
- 当内存紧张时系统会自动释放,但可手动清理:
echo 3 > /proc/sys/vm/drop_caches
验证清单
- MongoDB服务正常运行
- RAID md2=[_UUU](降级运行)
- 定时任务已安装
- 无新的I/O错误
- 所有容器已添加有效的mem_limit
- AIConsole已禁用
- 页面缓存已清理
- deploy.resources.limits已替换为mem_limit
十、防止OOM复发的关键措施
- mem_limit强制生效:所有docker-compose.yml使用
mem_limit而非deploy.resources.limits - 高耗栈禁用:Ollama、VM、karuo-ai网关已禁用,防止自动启动
- ContainerManager禁用自启:开机不会自动启动Docker
- RestartPolicy=no:容器崩溃后不会自动重启引发连锁反应
- 定时健康检测:每10分钟检测sata4状态和I/O错误
- 开机自动修复:@reboot自动执行修复脚本
- staged boot禁用:防止开机后分批启动容器
十五、脚本修复:防止下次重启破坏RAID(2026-07-10 06:45)
15.1 问题
之前的ckbnas_fix_sata4_and_memory.sh在启动时会将sata4设为offline,这会在下次NAS重启时破坏刚修复的RAID。
15.2 修复内容
ckbnas_fix_sata4_and_memory.sh:
- 将
fix_sata4()函数逻辑反转 - 现在检查sata4是否为offline,如果是则尝试重新上线并加入RAID
- 如果设备不存在,自动重新扫描SCSI总线
ckbnas_sata4_health_check.sh:
- 更新健康检查逻辑,running状态为正常
- offline状态为异常,建议rescan
15.3 脚本已上传到NAS
- ✅
/volume1/homes/fnvtk/scripts/ckbnas_fix_sata4_and_memory.sh - ✅
/volume1/homes/fnvtk/scripts/ckbnas_sata4_health_check.sh
15.4 定时任务确认
| 任务 | 频率 | 脚本 |
|---|---|---|
| 开机修复 | @reboot | ckbnas_fix_sata4_and_memory.sh |
| 健康检测 | */10 * * * * | ckbnas_sata4_health_check.sh |
十六、最终验证结果(2026-07-10 06:45)
16.1 磁盘状态(全部在线)
| DSM显示 | 系统设备 | 型号 | 温度 | 状态 |
|---|---|---|---|---|
| 硬盘1 | sata1 | HAT3320-8T | 39°C | ✅ 在线 |
| 硬盘2 | sata2 | HAT3320-8T | 38°C | ✅ 在线 |
| 硬盘5 | sata4 | HAT3320-8T | 38°C | ✅ 在线 |
| 硬盘6 | sata3 | HAT3320-8T | 40°C | ✅ 在线 |
16.2 RAID状态(重建中)
| 阵列 | 类型 | 状态 | 进度 | 预计完成 |
|---|---|---|---|---|
| md0 | RAID1 | ✅ 完成 | 100% | - |
| md1 | RAID1 | ✅ 完成 | 100% | - |
| md2 | RAID5 | 🟡 重建中 | 0.0% | ~30小时 |
16.3 系统状态
| 项目 | 值 | 状态 |
|---|---|---|
| 内存总量 | 7894MB | ✅ |
| 可用内存 | 6083MB | ✅ |
| Swap使用 | 356MB | ✅ |
| 负载 | ~2.9 | ✅ |
| MongoDB | 运行中 | ✅ |
| Gitea | 运行中 | ✅ |
| xmfst-web | 运行中 | ✅ |
16.4 重要提示
RAID5重建需要约30小时,在此期间:
- ✅ NAS可正常使用
- ✅ 数据安全有保障(4盘RAID5,3盘即可运行)
- ✅ 重建完成后自动恢复完整冗余
版本 v1.2 | 2026-07-10(添加sata4重新上线修复和脚本修正)