Files
dsh_ai1net_server/交付物/DB修复-workbuddy.db损坏诊断与方案-20260923.md

113 lines
6.9 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.
# workbuddy.db 损坏 — 诊断结论与修复方案
> 诊断时间:**2026-09-23 18:2x–18:4x** | 诊断人:会话 `IM线-第11棒`(纯只读诊断,⛔ 未改动任何原文件)
> 库路径:`E:\ProgramData\.workbuddy\workbuddy.db`(活动库,由 `CODEBUDDY_CONFIG_DIR=E:\ProgramData\.workbuddy` 确认)
---
## 一、结论(一句话)
**主库数据不可恢复** —— `sqlite_master` 的 schema 根页(page 1)已被清零破坏,且 96.7% 的页是零页。**推荐路径 = 让 app 重建库**(automation 配置会丢,需重建)。
---
## 二、实测证据(全部为只读取证)
| # | 判据 | 实测值 | 含义 |
|---|---|---|---|
| 1 | 头部 magic(off 0-15) | `0d000000070081070ea30d5908fd0a530639035f00810000` 等乱码 | **非 `SQLite format 3`** |
| 2 | `page_size`(off 16-17) | `0x0639` = 1593 | **非法值**(合法须 2^n,且 ≥512) |
| 3 | 头部 off 24-99 | **全零** | 头部被覆写(前 24B 垃圾 + 后 76B 零) |
| 4 | 🔴 **page 1 的 b-tree 页头(off 100-107)** | **全零** | ⛔ **`sqlite_master` 根页被毁 ⇒ schema 字典丢失** |
| 5 | 全库页健康度(8637 页) | **8355 页(96.7%)首字节 0x00**;仅 282 页(3.3%)是合法 b-tree 页 | 绝大部分页被清零 |
| 6 | WAL 头 | magic `0x377F0682` ✅、`page_size=0x1000`(4096) ✅、完整 1055 帧 | **WAL 本身完好** |
| 7 | WAL 覆盖范围 | 仅 **62 个不同页**(页号 15..8125),最后 commit 声明 DB = **7504 页** | WAL 只含 0.8% 的页 |
| 8 | WAL 是否有 page 1 | ⛔ **无** | 无法从 WAL 还原头部 |
| 9 | 头部重建实测 | 在**副本**上重建 100 字节合法头(page_size=4096 / db_pages=7504 / ver=2-2 / UTF-8)后打开 ⇒ **仍 `database disk image is malformed`** | ⛔ **方案「只重建头部」已证伪**(因判据 4) |
| 10 | 现成备份 | 顶层**仅三件套,无 `.bak`**;`.backup-20260916\` 里只有 `MEMORY.md`(非 db);`automation-backups\` 仅 2 个 **08-30** 的 JSON | ⛔ **无 db 级可用备份** |
| 11 | `sqlite3` CLI | **未安装** | `.recover` 不可直接用 |
| 12 | 独立数据面(不依赖 db) | `sessions\` **314 个 JSON**(至 09-20)|`tasks\` **38 个目录**(至 09-23 06:08) | ✅ 这部分数据在文件里,可保留 |
**损坏形态判读**:`96.7% 零页 + page 1 全零 + 头部前 24B 垃圾` ⇒ 与项目记忆里那条血教训的现场一致 —— **文件被"部分覆写"**(只有一个大部分为空/零的文件替换了它的一部分)。
---
## 三、🔴 当前影响(比库本身更要紧)
1. **所有 automation 停摆** —— 建报 `database disk image is malformed`、查报 `file is not a database`。⇒ **各线的自动化接力全部断层**(不止 IM 线)。
2. **IM 线第 11 棒的接续棒无法登记** ⇒ 已改为**手工接力**(入口 §2 已自包含)。
3. `workbuddy.db` 内的会话历史 / 任务记录不可读(但 `sessions\`、`tasks\` 的文件形态部分仍在)。
---
## 四、修复方案(三案,各带优缺点)
### 案 A · 让 app 重建库(**推荐**)
**做法**:停 app → 把坏的三件套**改名**(不删)→ 重启 app。app 依据 `.workbuddy-sqlite-migrations\0000_workbuddy_sqlite_baseline.sql` 自动建全新 schema。
建议**先只重启 app 试一次**(不删任何文件)—— 成本最低,若 app 能自愈则无需后续动作。
- **优点**:功能立即恢复(app 有 migrations baseline ⇒ schema 自动重建);坏库改名保留 ⇒ **可回退**;不依赖任何外部工具(本机无 `sqlite3` CLI)。
- **缺点**:**automation 配置全丢,需逐条重建**(各线的接续棒都要重排);db 内的会话/任务记录丢失(`sessions\`、`tasks\` 的文件形态部分可保留)。
### 案 B · 数据挖掘(从 WAL + 282 个完好页里捞)
- **优点**:理论上能救回最近的部分写入(WAL 62 页)。
- **缺点**:🔴 **page 1 已毁 ⇒ 没有 schema,无法知道这些页属于哪张表**;WAL 仅覆盖 62 页(0.8%);需逐页人工分析、成功率低、耗时长。
### 案 C · 找更早的 db 备份
- **优点**:若有,可恢复较完整数据。
- **缺点**:⛔ **实测已排除** —— 顶层无 `.bak`,`.backup-20260916\` 只含 `MEMORY.md`,`automation-backups\` 只有 2 个 08-30 的 JSON;VSS 卷影未查到可用快照。
**⇒ 推荐案 A**(案 C 已实测排除;案 B 性价比过低)。
---
## 五、案 A 的执行步骤(⚠️ 必须由用户执行 —— 我会被停掉)
> 🔴 **红线门禁**:以下动作需**停 app**,会中断当前会话及所有在跑的会话 ⇒ 由用户决定时机并执行。
```powershell
# 0. 先确认无 WorkBuddy 进程在写(任务管理器,或)
Get-Process WorkBuddy -ErrorAction SilentlyContinue
# 1. 停掉 WorkBuddy(关闭应用)
# 2. 应急副本(已在 2026-09-23 18:36 生成一份,可再确认)
# E:\ProgramData\AIProject\aliyun-dsh-server\tmp\dbrescue-20260923\
# (workbuddy.db / -wal / -shm 三件套,35,377,152 + 4,346,632 + 32,768 字节)
# 3. 把坏的三件套改名(⛔ 不删,留回退路)
cd E:\ProgramData\.workbuddy
Rename-Item workbuddy.db workbuddy.db.broken-20260923
Rename-Item workbuddy.db-wal workbuddy.db-wal.broken-20260923
Rename-Item workbuddy.db-shm workbuddy.db-shm.broken-20260923
# 4. 顺手保一份独立数据面(文件形态,防 app 重建时一并重置)
Copy-Item -Recurse E:\ProgramData\.workbuddy\sessions E:\ProgramData\AIProject\aliyun-dsh-server\tmp\dbrescue-20260923\sessions
Copy-Item -Recurse E:\ProgramData\.workbuddy\tasks E:\ProgramData\AIProject\aliyun-dsh-server\tmp\dbrescue-20260923\tasks
# 5. 重启 WorkBuddy ⇒ app 依据 .workbuddy-sqlite-migrations 自动建新库
```
**成功判据**:app 内 automation 功能恢复(能列出、能新建)⇒ 库已重建成功。
**回退**:把 `*.broken-20260923` 三个文件改回原名即可。
---
## 六、重建后必做
1. **补登各线接续棒** —— automation 配置已丢,`覆盖网络线` / `插件投放与分库线` / `技能重组线` / `IM 线` 等需按各自入口的 §2 重新登记。
2. **IM 线**:第 11 棒(动工连接层 B 案)的完整动工范围在 `接续入口_IM线_20260922.md` **§2「第 11 棒」** 段(自包含),可直接据此重登 automation。
3. 核对 `sessions\` / `tasks\` 文件形态数据是否被 app 重建时重置(若重置 ⇒ 从本次副本回灌)。
---
## 七、本次已执行的只读动作(⛔ 未改动任何原文件)
- 诊断脚本:`tmp\db_diag.py`、`tmp\db_deep.py`、`tmp\db_pagescan.py`、`tmp\db_wal.py`、`tmp\db_rescue.py`
- dry-run 修复脚本(只在副本上跑):`tmp\db_repair.py`
- **应急副本**:`tmp\dbrescue-20260923\`(三件套 + `trial\` 试验副本)
- 项目记忆回写:`MEMORY.md` 血教训条已补两条判据(① 判活动库看 `CODEBUDDY_CONFIG_DIR` ② `immutable=1` 读不出 ≠ 仅 WAL 错位)