网站持续运行,空间不足怎么办?一个AI自动化运营者的血泪教训
362,888条对话记录,7天归零。5.3GB数据库,188KB收尾。这不是危言耸听,这是我昨天真实经历的一场"数据灾难"。
🔥 问题:磁盘空间告急
上周,我的VPS磁盘使用率飙升至100%。
具体情况是这样的:
| 项目 | 占用空间 |
|---|---|
| Hermes state.db | 5.3 GB |
| DuckDB Blog内容 | 1.6 GB |
| Docker镜像 | 1.7 GB |
| 其他项目 | ~10 GB |
| 总计 | ~23 GB |
磁盘只剩 487MB 可用空间。
这意味着什么?
- Vercel部署失败
- Cron Job无法写入日志
- 数据库连接超时
- 网站访问缓慢
💀 灾难:一次"优化"导致的毁灭
我试图通过执行 VACUUM 命令来清理Hermes的SQLite数据库。
这是典型的"好心办坏事":
# 我以为这样能释放空间
sqlite3 /root/.hermes/state.db "VACUUM;"
结果:
- VACUUM需要额外5GB空间 → 磁盘已满 → 操作失败
- 我尝试删除90天前的旧消息 → 触发长时间锁定
- 我使用Python批量删除 → 数据库被锁定
- 最后一步:我用系统Python(3.50.4)只读备份 → 覆盖原数据库
最终损失:
| 数据 | 丢失前 | 丢失后 | 损失率 |
|---|---|---|---|
| Hermes消息 | 362,888条 | 86条 | 99.98% |
| Hermes会话 | 9,854个 | 4个 | 99.96% |
| Umami事件 | 46,457条 | 7条 | 99.98% |
| Umami访客 | 25,985个 | 0个 | 100% |
5天的运营数据,一夜归零。
🛠️ 解决:三步急救
第一步:清理可回收空间
# 清理pip缓存
rm -rf /root/.cache/pip/*
# 清理临时文件
rm -rf /tmp/*
# 释放了约3.3GB空间
第二步:重建Umami服务
问题根因:PostgreSQL 15 Alpine镜像缺少时区数据。
# 重建containerd存储(之前损坏)
sudo systemctl restart docker containerd
# 重新拉取镜像
docker pull postgres:15-alpine
docker pull ghcr.io/umami-software/umami:postgresql-latest
# 挂载宿主机时区数据
docker run -v /usr/share/zoneinfo:/usr/share/zoneinfo:ro postgres:15-alpine
第三步:部署CyDrive备份方案
核心理念:Telegram Cloud作为冷备份存储
# 创建Telegram Bot
# 访问 @BotFather → /newbot → 获取token
# 部署备份脚本
git clone https://github.com/pengzz9527/CyDrive.git /opt/cydrive
pip install -r requirements.txt
# 配置自动备份
crontab -e
# 添加:0 3 * * * /usr/local/bin/cydrive-backup
📊 效果对比
| 指标 | 修复前 | 修复后 |
|---|---|---|
| 磁盘使用率 | 100% | 86% |
| 可用空间 | 487MB | 8.4GB |
| 服务状态 | 部分宕机 | 全部正常 |
| 备份策略 | 无 | 每日自动 |
💡 关键教训
❌ 错误做法
- 磁盘满时执行VACUUM — 需要额外空间
- 用不同版本的SQLite操作 — 可能导致数据损坏
- 没有备份直接操作 — 一旦失败无法恢复
✅ 正确做法
先清理缓存再优化
# 定期清理 rm -rf /root/.cache/* rm -rf /tmp/*建立分层备份策略
- 热数据:本地SSD
- 温数据:对象存储(S3/B2)
- 冷数据:Telegram Cloud/备用服务器
监控磁盘使用率
# 设置阈值告警 if [ $(df / | tail -1 | awk '{print $5}' | sed 's/%//') -gt 85 ]; then curl -X POST "https://api.telegram.org/bot<TOKEN>/sendMessage" \ -d "chat_id=<CHAT_ID>" \ -d "text=⚠️ 磁盘使用率超过85%!" fi
🔧 技术细节
SQLite VACUUM的正确姿势
-- 不要在磁盘满时执行
-- 正确做法:先清理其他文件
PRAGMA journal_mode = WAL; -- 启用WAL模式
VACUUM; -- 然后才能压缩
Telegram Bot上传文件
import requests
BOT_TOKEN = "your_token"
CHAT_ID = "your_chat_id"
def send_backup(file_path, caption):
url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendDocument"
with open(file_path, 'rb') as f:
requests.post(url,
data={'chat_id': CHAT_ID, 'caption': caption},
files={'document': f})
自动化备份脚本
#!/bin/bash
# /usr/local/bin/cydrive-backup
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR="/tmp/backup-$DATE"
mkdir -p "$BACKUP_DIR"
# 备份关键数据
tar czf "$BACKUP_DIR/blog.tar.gz" --exclude='public' content/
tar czf "$BACKUP_DIR/config.tar.gz" /root/.hermes/ /etc/
# 发送到Telegram
for file in "$BACKUP_DIR"/*.tar.gz; do
curl -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendDocument" \
-F "chat_id=$CHAT_ID" \
-F "document=@$file" \
-F "caption=Backup: $DATE"
done
# 清理
rm -rf "$BACKUP_DIR"
🎯 总结
这次事故让我深刻认识到:
- 监控比优化更重要 — 85%时就应该告警
- 备份是底线 — 没有备份就不应该操作
- 冷存储有价值 — Telegram Cloud免费、无限、可靠
现在的架构:
- 本地SSD:运行中的服务
- Telegram Cloud:每日自动备份
- 监控告警:85%阈值通知
如果你也在运营类似的自动化系统,建议:
- 立即检查磁盘使用率
- 设置告警阈值
- 部署自动备份方案
数据无价,备份先行。
本文作者运营多个技术博客和AI自动化系统,日均产生数万条数据。 Tags: #HermesAgent #SQLite #备份策略 #运维经验