Hermes Decision Trace

Hindsight 0.7.1 Postgres 升级风险与方案 C 规划

Hindsight 0.7.x 解决了 entity links O(N²) 膨胀方向问题,但 v0.7.1 官方包在本机 Postgres 升级路径上存在 migration 硬阻塞;当前不建议直接升级 live。

0.6.2live 保持健康
0.7.1isolated runtime 可用
阻塞migration 需修复
🎯
核心结论

0.7.x 值得跟进,但 v0.7.1 官方 migration 原样不能作为本机 production cutover 依据。

🧭
推荐路径

先向 vectorize-io/hindsight 提 issue;若走方案 C,则采用 patched 0.7.1 + cloned DB rehearsal + clone-and-swap。

🛡️
关键边界

rehearsal-only 的普通 DDL 补丁只证明 runtime 可用,不能直接用于生产升级。

关键判断

判断项摘要
推荐方案保持 live 0.6.2;向上游提交 issue;等官方修复或先做可审计 production patch,再 fresh rehearsal。
关键依据isolated 0.7.1 在补丁后 health/retain/recall/consolidation 通过,但官方 migration 原样失败。
落地方式方案 C 采用 patched package、cloned DB、batch cleanup、clone-and-swap cutover,不做 in-place 硬升。
风险边界官方包目前缺 psycopg,且多处 DROP/CREATE INDEX CONCURRENTLY 运行在 Alembic transaction block 内。

证据摘要

  • 上游 #1887:0.7.x redesign 解决 entity links O(N²) 膨胀。
  • 本机 rehearsal:entity links 从 39372 清零,0.7.1 runtime 功能验证通过。
  • 阻塞日志:ModuleNotFoundError: No module named 'psycopg'DROP INDEX CONCURRENTLY cannot run inside a transaction block
  • 上游对比:main 与 v0.7.1 相关 migration 文件相同,尚未修复。
  • 已提交 issue:vectorize-io/hindsight#1902

行动清单

已发布本 Decision Trace 到 wiki/HTML,并 retain pointer。
已向 vectorize-io/hindsight 提交 GitHub issue:#1902
暂不动 live;如推进方案 C,先做 patched branch 与两轮 fresh rehearsal。

边界 / 风险

直接升级风险

官方 migration 可能让 API 启动失败,并把 alembic_version / 索引状态停在中间态。

本地补丁风险

普通 DDL 会锁表;生产应优先使用 autocommit + CONCURRENTLY,或拆出手工 batch cleanup。

回滚边界

不要依赖 downgrade migration;使用旧 venv + 旧 DB + final dump 做快速回滚。

完整记录

Hindsight 0.7.1 Postgres 升级风险与处理规划

1. 背景

本机当前 live Hindsight:

API: 127.0.0.1:8889 Version: 0.6.2 Status: healthy Database: pg0/PostgreSQL 18.1 on 127.0.0.1:5432

本次任务是评估上游 0.7.1 是否值得升级,以及是否能安全从本机 live 0.6.2 迁移过去。

隔离演练路径:

isolated venv: /home/ht/hindsight-071-venv isolated API: 127.0.0.1:18889 rehearsal DB: hindsight_071_rehearsal_20260601_151948 审计目录: /home/ht/hindsight-upgrade-audit-0.7.1-20260601-150919

live 8889 和 live DB 未直接修改。

---

2. 0.7.x 解决的问题

上游 issue #1887 指出,0.6.xmemory_linkslink_type = 'entity' 行会按高频实体近似 O(N²) 增长,导致表膨胀、dead tuples、stats 慢查询、CPU 飙高和连接池耗尽。

官方在该 issue 中说明,0.7.0 已重新设计:

  • entity edges 不再物化为 memory_links 行;
  • entity relationships 改为从 unit_entities 按需派生;
  • migration e9b2c7d1f3a4_drop_entity_memory_links 会删除既有 entity links。

本机 rehearsal DB 迁移前后验证:

迁移前 memory_links: semantic | 53180 entity | 39372 temporal | 38768 caused_by| 981 迁移后 memory_links: semantic | 53200 temporal | 38788 caused_by| 981

说明 0.7.x 的方向和目标是有效的。

---

3. 本机实测阻塞点

3.1 缺少 psycopg

hindsight-api-slim 0.7.1 安装后包含:

psycopg2-binary==2.9.12

但启动 migration 时 SQLAlchemy 使用 postgresql+psycopg 路径,报:

ModuleNotFoundError: No module named 'psycopg'

补救方式:

uv pip install --python /home/ht/hindsight-071-venv/bin/python 'psycopg[binary]'

3.2 CONCURRENTLY 在 transaction block 中执行

psycopg 后,migration 继续失败:

DROP INDEX CONCURRENTLY cannot run inside a transaction block

已撞到的 revision:

e1b2c3d4f5a6_drop_unused_indexes.py e9b2c7d1f3a4_drop_entity_memory_links.py

继续扫描上游 v0.7.1/main 发现同类写法还存在于多个 migration:

a2b3c4d5e6f8_add_gin_index_source_memory_ids.py b3c4d5e6f7g8_add_temporal_date_indexes.py c1a2b3d4e5f6_enable_pg_trgm_and_entities_trgm_index.py d2e3f4a5b6c7_add_memory_links_expansion_indexes.py d4e5f6g7h8i9_gin_source_memory_ids_fastupdate_off.py e1b2c3d4f5a6_drop_unused_indexes.py e9b2c7d1f3a4_drop_entity_memory_links.py

上游 mainv0.7.1 的相关 migration 文件对比结果为 SAME,说明截至本次检查时,上游 main 尚未修复该问题。

---

4. 隔离验证结果

为了验证 0.7.1 runtime 本身是否可用,本次只在 isolated venv + copied rehearsal DB 中做 rehearsal-only patch:

将 CONCURRENTLY 改成普通 DDL 移除 migration 中手写 COMMIT

这不是 production 方案,只用于确认 runtime 能力。

补丁后 isolated 0.7.1 启动成功:

{"status":"healthy","database":"connected"} {"api_version":"0.7.1"}

验证通过:

banks ✅ stats ✅ manual retain ✅ manual recall ✅ consolidation ✅ operations clean ✅

关键结果:

alembic_version: b5a4c3e2f1d8 pending_operations: 0 failed_operations: 0 pending_consolidation: 0 failed_consolidation: 0

---

5. 对 live 的影响

短期:本机 live 仍健康,当前 rehearsal DB 规模较小,不是马上要抢修。

DB size: 104 MB memory_links: 39 MB entity links: 39372

中长期:继续停留在 0.6.2 会保留 entity links 膨胀风险。如果后续 retain、历史回放、consolidation 增加,memory_links 表可能持续膨胀。

直接升级的风险更高:如果直接在 live DB 上跑官方 0.7.1 migration,可能出现 API 启动失败、alembic_version 半路状态、索引部分删除、DB schema 中间态等问题,回滚不能只退 Python 包,可能需要恢复 dump。

---

6. 方案 C:patched 0.7.1 的规划

6.1 原则

不做 in-place 硬升。采用:

patched 0.7.1 + cloned DB rehearsal + clone-and-swap cutover

6.2 Patch 范围

只修 migration/依赖,不改业务逻辑。

  1. 补依赖:
psycopg[binary]>=3.3.0
  1. CONCURRENTLY migration:

将:

op.execute("COMMIT") op.execute("DROP INDEX CONCURRENTLY IF EXISTS ...")

改为:

with op.get_context().autocommit_block(): op.execute("DROP INDEX CONCURRENTLY IF EXISTS ...")
  1. 单独处理 e9b2c7d1f3a4 的 entity cleanup。

生产更稳的方式是将大规模 entity links 删除拆成可观测 batch cleanup:

DELETE FROM memory_links WHERE ctid IN ( SELECT ctid FROM memory_links WHERE link_type = 'entity' LIMIT 50000 );

循环直到 0 行,并在结束后:

VACUUM ANALYZE memory_links;

6.3 Rehearsal 要求

fresh dump 新建 rehearsal DB,必须验证:

health/version/banks/stats manual retain/manual recall consolidation operation completed alembic_version == head entity links cleared pending_operations = 0 failed_operations = 0

还要记录:

migration 耗时 entity cleanup 耗时 DB size 前后变化 memory_links dead tuples / vacuum 后状态 索引列表

6.4 Cutover 策略

生产采用 clone-and-swap:

  1. 维护窗口开始,停止 Hindsight API 写入;
  2. final dump live DB;
  3. 恢复到新 DB,如 hindsight_071_prod_candidate_<timestamp>
  4. patched 0.7.1 指向 candidate DB 跑 migration;
  5. isolated API 验证通过;
  6. systemd/env 切换到 patched venv + candidate DB;
  7. live 8889 验证通过;
  8. 保留旧 0.6.2 venv、旧 DB、旧 env 和 final dump 作为回滚点。

6.5 回滚

不依赖 downgrade migration,直接切回旧 venv + 旧 DB:

stop hindsight-api restore env/systemd to 0.6.2 + old DB start hindsight-api verify health/version/stats/recall

---

7. 建议

当前建议:

不直接升级 live。 先向上游提交 issue。 等待官方修复,或准备可审计 production patch 后 fresh rehearsal。

如果后续继续推进方案 C,应先把 patch 做成可重复脚本/本地分支,并至少完成两次 fresh rehearsal,再安排生产维护窗口。

---

8. 证据与路径

本机审计目录:

/home/ht/hindsight-upgrade-audit-0.7.1-20260601-150919

关键文件:

verify-banks.json verify-retain.json verify-recall-after.json verify-consolidate-operation.json verify-stats-final.json *.noconcurrent.diff hindsight-071-api-18889-*.log venv-freeze-hindsight-ish.txt uv-install-psycopg.txt

上游相关:

Repo: https://github.com/vectorize-io/hindsight Issue #1887: Entity links grow O(N²) per shared entity... Release: v0.7.1, 2026-05-28

---

9. 当前执行状态

本记录生成时间:2026-06-01 18:31:18 CST。

本记录用于 wiki / HTML / Hindsight retain pointer 归档,并作为向上游提 issue 的依据。