Files
gate_scout_order/备份恢复说明.md
2026-05-17 10:20:20 +08:00

269 lines
9.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# gate_scout_order · 手动备份与恢复
面向 **Ubuntu 服务器**,项目固定在 `/opt/gate_scout_order`,备份目录在 `/root`
`config.yaml``runtime/` **不入 Git**。升级、`git pull`、误删目录前,请先执行下方 **一键备份**
---
## 路径约定
| 用途 | 路径 |
|------|------|
| 项目根目录 | `/opt/gate_scout_order` |
| 扫描端 | `/opt/gate_scout_order/onchain_scout_gate` |
| 执行器 | `/opt/gate_scout_order/gate_order_executor` |
| 备份根目录 | `/root/backup_gate_<日期>_<时间>/` |
PM2 默认进程名:`onchain-scout``gate-order-executor`(若你改过名,恢复命令里请自行替换)。
---
## 备份内容说明
### 必须备份(丢失难恢复)
| 组件 | 文件 | 说明 |
|------|------|------|
| 扫描端 | `config.yaml` | 企微、auth、proxy、monitor 等 |
| 扫描端 | `runtime/alerts.db` | 历史告警、面板策略参数(SQLite KV) |
| 扫描端 | `runtime/order_executors.json` | 执行器转发列表、总开关、Webhook 密钥 |
| 执行器 | `config.yaml` | Gate API、`webhook_secret``dry_run` 等 |
| 执行器 | `runtime/signals.sqlite` | 信号流与每笔下单结果 |
| 执行器 | `runtime/risk_prefs.json` | 面板「最低盈亏比」 |
| 执行器 | `runtime/breakeven_prefs.json` | 移动保本开关 |
| 执行器 | `runtime/breakeven_active.json` | 移动保本运行态 |
### 可选(排障用,体积较大)
扫描端 / 执行器 `runtime/*.log``runtime/pm2-*.log` — 下方一键脚本 **默认不备份日志**;需要时见 [§5 可选:含日志备份](#5-可选含日志备份)。
### 多执行器
若除 `gate_order_executor` 外还有 **第二套执行器**(另一目录或 `:8091` 实例),请对该目录 **再执行一次** 备份块,或把路径改后单独打包(见 [§6 多执行器](#6-多执行器))。
---
## 1. 一键备份(推荐)
在服务器上 **整段复制执行**(需已安装 `sqlite3``sudo apt install -y sqlite3`)。
```bash
PROJECT_ROOT=/opt/gate_scout_order
BACKUP_DIR=/root/backup_gate_$(date +%Y%m%d_%H%M%S)
SCOUT="$PROJECT_ROOT/onchain_scout_gate"
EXEC="$PROJECT_ROOT/gate_order_executor"
mkdir -p "$BACKUP_DIR"/{onchain_scout_gate/runtime,gate_order_executor/runtime}
chmod 700 "$BACKUP_DIR"
# --- 扫描端 config ---
if [ -f "$SCOUT/config.yaml" ]; then
cp -a "$SCOUT/config.yaml" "$BACKUP_DIR/onchain_scout_gate/"
else
echo "WARN: 缺少 $SCOUT/config.yaml"
fi
# --- 扫描端 runtimeSQLite 用 .backup,其余 cp---
if [ -f "$SCOUT/runtime/alerts.db" ]; then
sqlite3 "$SCOUT/runtime/alerts.db" ".backup '$BACKUP_DIR/onchain_scout_gate/runtime/alerts.db'"
else
echo "WARN: 缺少 alerts.db"
fi
[ -f "$SCOUT/runtime/order_executors.json" ] && \
cp -a "$SCOUT/runtime/order_executors.json" "$BACKUP_DIR/onchain_scout_gate/runtime/"
# --- 执行器 config ---
if [ -f "$EXEC/config.yaml" ]; then
cp -a "$EXEC/config.yaml" "$BACKUP_DIR/gate_order_executor/"
else
echo "WARN: 缺少 $EXEC/config.yaml"
fi
# --- 执行器 runtime ---
if [ -f "$EXEC/runtime/signals.sqlite" ]; then
sqlite3 "$EXEC/runtime/signals.sqlite" ".backup '$BACKUP_DIR/gate_order_executor/runtime/signals.sqlite'"
else
echo "WARN: 缺少 signals.sqlite"
fi
for f in risk_prefs.json breakeven_prefs.json breakeven_active.json; do
[ -f "$EXEC/runtime/$f" ] && cp -a "$EXEC/runtime/$f" "$BACKUP_DIR/gate_order_executor/runtime/"
done
echo "备份完成: $BACKUP_DIR"
find "$BACKUP_DIR" -type f | sort
ls -la "$BACKUP_DIR"/onchain_scout_gate "$BACKUP_DIR"/gate_order_executor 2>/dev/null || true
```
执行成功后记下输出的目录名,例如:`/root/backup_gate_20260517_033012`
---
## 2. 查看已有备份
```bash
ls -lt /root/backup_gate_* 2>/dev/null | head -20
```
查看最新一份目录路径:
```bash
ls -dt /root/backup_gate_* 2>/dev/null | head -1
```
---
## 3. 一键恢复
**恢复会覆盖当前 `config.yaml` 与列出的 runtime 文件。** 建议先做一次 [§1 一键备份](#1-一键备份推荐),再执行恢复。
`BACKUP_DIR` 改成你要恢复的那次备份路径(整段复制后只改第一行):
```bash
BACKUP_DIR=/root/backup_gate_20260517_033012
PROJECT_ROOT=/opt/gate_scout_order
SCOUT="$PROJECT_ROOT/onchain_scout_gate"
EXEC="$PROJECT_ROOT/gate_order_executor"
if [ ! -d "$BACKUP_DIR" ]; then
echo "ERROR: 备份目录不存在: $BACKUP_DIR"
exit 1
fi
pm2 stop onchain-scout gate-order-executor 2>/dev/null || true
mkdir -p "$SCOUT/runtime" "$EXEC/runtime"
# 扫描端
[ -f "$BACKUP_DIR/onchain_scout_gate/config.yaml" ] && \
cp -a "$BACKUP_DIR/onchain_scout_gate/config.yaml" "$SCOUT/"
[ -f "$BACKUP_DIR/onchain_scout_gate/runtime/alerts.db" ] && \
cp -a "$BACKUP_DIR/onchain_scout_gate/runtime/alerts.db" "$SCOUT/runtime/"
[ -f "$BACKUP_DIR/onchain_scout_gate/runtime/order_executors.json" ] && \
cp -a "$BACKUP_DIR/onchain_scout_gate/runtime/order_executors.json" "$SCOUT/runtime/"
# 执行器
[ -f "$BACKUP_DIR/gate_order_executor/config.yaml" ] && \
cp -a "$BACKUP_DIR/gate_order_executor/config.yaml" "$EXEC/"
[ -f "$BACKUP_DIR/gate_order_executor/runtime/signals.sqlite" ] && \
cp -a "$BACKUP_DIR/gate_order_executor/runtime/signals.sqlite" "$EXEC/runtime/"
for f in risk_prefs.json breakeven_prefs.json breakeven_active.json; do
[ -f "$BACKUP_DIR/gate_order_executor/runtime/$f" ] && \
cp -a "$BACKUP_DIR/gate_order_executor/runtime/$f" "$EXEC/runtime/"
done
pm2 restart onchain-scout gate-order-executor 2>/dev/null || \
(cd "$SCOUT" && pm2 start deploy/ecosystem.config.cjs; cd "$EXEC" && bash deploy/pm2-start.sh)
pm2 save 2>/dev/null || true
echo "恢复完成,自 $BACKUP_DIR"
pm2 status
```
恢复后检查:
- 扫描端面板 `http://<服务器>:8088` — 策略参数、执行器列表是否正常
- 执行器面板 `http://<服务器>:8090/dashboard` — 信号流历史是否仍在
**注意:** `git pull` 后不要用 `git checkout -- runtime/``git clean` 清掉业务数据。
---
## 4. 从「最新一份备份」恢复(可选)
若你确认 `/root` 下最新目录就是要用的那份,可先取路径再恢复:
```bash
BACKUP_DIR=$(ls -dt /root/backup_gate_* 2>/dev/null | head -1)
echo "将恢复: $BACKUP_DIR"
read -r -p "确认请输入 yes: " ans
[ "$ans" = "yes" ] || { echo "已取消"; exit 1; }
PROJECT_ROOT=/opt/gate_scout_order
SCOUT="$PROJECT_ROOT/onchain_scout_gate"
EXEC="$PROJECT_ROOT/gate_order_executor"
pm2 stop onchain-scout gate-order-executor 2>/dev/null || true
mkdir -p "$SCOUT/runtime" "$EXEC/runtime"
cp -a "$BACKUP_DIR/onchain_scout_gate/config.yaml" "$SCOUT/" 2>/dev/null || true
cp -a "$BACKUP_DIR/onchain_scout_gate/runtime/"* "$SCOUT/runtime/" 2>/dev/null || true
cp -a "$BACKUP_DIR/gate_order_executor/config.yaml" "$EXEC/" 2>/dev/null || true
cp -a "$BACKUP_DIR/gate_order_executor/runtime/"* "$EXEC/runtime/" 2>/dev/null || true
pm2 restart onchain-scout gate-order-executor 2>/dev/null || true
pm2 save 2>/dev/null || true
echo "已从 $BACKUP_DIR 恢复"
```
---
## 5. 可选:含日志备份
需要连同日志一起打包时,在 **§1 备份脚本末尾** 追加执行:
```bash
PROJECT_ROOT=/opt/gate_scout_order
BACKUP_DIR=/root/backup_gate_$(date +%Y%m%d_%H%M%S)_with_logs
SCOUT="$PROJECT_ROOT/onchain_scout_gate"
EXEC="$PROJECT_ROOT/gate_order_executor"
mkdir -p "$BACKUP_DIR"
chmod 700 "$BACKUP_DIR"
cp -a "$SCOUT/config.yaml" "$BACKUP_DIR/scout_config.yaml" 2>/dev/null || true
cp -a "$EXEC/config.yaml" "$BACKUP_DIR/executor_config.yaml" 2>/dev/null || true
cp -a "$SCOUT/runtime" "$BACKUP_DIR/onchain_scout_gate_runtime"
cp -a "$EXEC/runtime" "$BACKUP_DIR/gate_order_executor_runtime"
echo "含日志备份完成: $BACKUP_DIR"
du -sh "$BACKUP_DIR"
```
含日志的目录结构与 §1 不同,恢复时请手动 `cp` 对应子目录,或优先使用 §1 标准结构备份。
---
## 6. 多执行器
第二套执行器若在例如 `/opt/gate_scout_order/gate_order_executor_b`
```bash
EXTRA_EXEC=/opt/gate_scout_order/gate_order_executor_b
BACKUP_DIR=/root/backup_gate_$(date +%Y%m%d_%H%M%S)_exec_b
mkdir -p "$BACKUP_DIR/runtime"
chmod 700 "$BACKUP_DIR"
cp -a "$EXTRA_EXEC/config.yaml" "$BACKUP_DIR/"
[ -f "$EXTRA_EXEC/runtime/signals.sqlite" ] && \
sqlite3 "$EXTRA_EXEC/runtime/signals.sqlite" ".backup '$BACKUP_DIR/runtime/signals.sqlite'"
for f in risk_prefs.json breakeven_prefs.json breakeven_active.json; do
[ -f "$EXTRA_EXEC/runtime/$f" ] && cp -a "$EXTRA_EXEC/runtime/$f" "$BACKUP_DIR/runtime/"
done
echo "第二执行器备份: $BACKUP_DIR"
```
---
## 7. 建议操作时机
| 场景 | 建议 |
|------|------|
| 首次部署稳定运行后 | 立刻备份一份 |
| `git pull` / 改目录 / 重装系统前 | 先备份 |
| 改 `config.yaml` 或面板大批量改策略前 | 先备份 |
| 定期(手动) | 每周或每月一次,保留多份不同日期的目录 |
可将备份目录同步到另一台机器或对象存储(scp、rsync 等),**不要**把含 API 密钥的备份放到公开网盘。
---
## 8. 故障速查
| 现象 | 可能原因 |
|------|----------|
| 升级后面板策略丢了 | 未恢复 `runtime/alerts.db` |
| 执行器列表空了 | 未恢复 `order_executors.json` |
| 信号流历史没了 | 未恢复 `signals.sqlite` |
| `sqlite3: command not found` | 执行 `sudo apt install -y sqlite3` 后重跑备份 |
| 恢复后 PM2 起不来 | `pm2 logs` 看配置校验;检查端口占用 |
更多部署与升级说明见 [部署说明.md](部署说明.md)。