---
title: 故障排查与灾备
description: PAC 的数据备份、代码回滚、游标倒退与并发锁清理。
icon: LifeBuoy
---

> 下文 `$PAC_HOME` 指安装目录(部署时 `export PAC_HOME=...`)。

---

## 一、数据备份

```bash
# 每日定时全量备份(与 08:15 增量错峰,如 03:00)
pg_dump -U pac -d pac -F c -f /backup/pac-$(date +%F).dump
# 保留 7 天
find /backup -name 'pac-*.dump' -mtime +7 -delete
```

---

## 二、回滚代码版本

```bash
cd $PAC_HOME && git fetch && git checkout <last-known-good-tag>
pnpm install && pnpm --filter @pac/types build && pnpm --filter @pac/service build
systemctl restart pac-service
```

---

## 三、游标倒退(重跑某时间窗)

```sql
-- 把最近一次 sync_log 的 cursor_after 改到目标时间(键为数据源表名)
UPDATE sync_logs SET cursor_after = '{"<source_table>":"2026-04-01T00:00:00", ...}'
WHERE id = (SELECT id FROM sync_logs
  WHERE resource='incremental_bundle' AND status='success'
  ORDER BY started_at DESC LIMIT 1);
```

下次 cron 自动从该游标拉。或直接 `pnpm sync -- --full` 忽略游标全量重拉(幂等,已有数据 skip)。

---

## 四、清理残留的 'running' 锁

并发锁是 `sync_logs` 里 `status='running'` 的行;进程崩溃未 finalize 会留下 stale 锁挡住后续 sync。

```sql
-- running 超 12h 视为 stale,人工 abort 释放锁
UPDATE sync_logs SET status='aborted', ended_at=NOW()
WHERE status='running' AND started_at < NOW() - INTERVAL '12 hours';
```

(CLI 撞锁会以退出码 `4` 退出,日志含对应 sync_log id 便于定位。)
