LangGraph 迁移后读慢
普通聚合列表迁到 DeltaChannel 后,PostgresSaver 每次重放整条历史。检查 blob 中的 plain seed 与正式 saver 3.1.2 修复,保留已有状态。
把 LangGraph 的普通聚合列表迁到 DeltaChannel 后,PostgresSaver 读出的内容仍然正确,却每次都重放越来越长的历史。这个组合可以检查旧的完整列表有没有被识别为 seed,不能只看最终列表相等就判断迁移读取已经正常。
旧 Postgres 读取路径曾漏掉这类迁移前的普通值。正式 langgraph-checkpoint-postgres 3.1.2 已包含修复,已核对的 3.1.3 仍沿 channel 版本查找实际存储值。这里处理的是迁移后的历史重建,不是 PostgreSQL 的所有慢查询。
完整列表在 blob 表里,标记却没留下
Postgres saver 会把部分值拆到 checkpoint_blobs。DeltaChannel 的快照对象移到 blob 表后,会在 checkpoint 的 channel_values 留下一个标记;普通列表移走时,旧保存路径不留下同样的标记。
迁移前的聚合列表正是普通值。旧祖先扫描只检查 channel_values 的标记,看不到已经存到 blob 表里的完整列表,于是一直向根检查点查找,再从空值开始重放全部更新。
对简单追加列表,全部写入碰巧还能重建正确结果,所以内容检查可能通过。失去的是在最近完整值处停止的能力:历史越来越长,每次读取需要处理的写入也随之增长。
先确认实际 saver 版本、迁移前后的 channel 类型,以及同一 thread、namespace、目标 checkpoint 的读取工作。比较返回历史里是否包含应有的 seed 和它之后的写入,不以某次总延迟单独归因;连接等待、查询计划和应用重复调用也能使请求变慢。
查存储位置,比补一个标记更完整
只让以后保存的普通值多写一个标记,无法帮助已经在数据库里的旧检查点。已有列表仍没有标记,迁移后的读取继续找不到它。
正式修复同时检查 channel 版本对应的 blob 与 checkpoint 内联值。blob 存在时,以它的实际值作为 seed;某些整数、字符串或布尔值留在 checkpoint 内,也不能因为只查 blob 而被漏掉。
快照用的 true 标记与一个真正的布尔值 True 还需要区分。读取不能把标记当作业务状态,也不能把所有内联真值都当成快照存在的证据。修复处理的是存储位置与值的判断,不是给列表内容做去重。
用原迁移历史检查修复
按项目允许的依赖范围选择包含修复的正式 Postgres saver,并核对实际同步或异步入口。保留数据库与应用配置;不要为了缩短读取直接删除 checkpoint、清空 blob 表,或把列表强制改成私有快照对象。
在获准的测试环境里用保留的迁移历史读取同一个目标。应能找到已有完整列表作为 seed,只重放它之后需要的合法更新;最终状态仍与原业务记录一致。另保留新建 DeltaChannel thread 和未迁移字段的对照,避免修复旧列表时破坏其他值的读取。
恢复停止条件不等于所有历史都能恢复。如果旧写入已经被 prune、TTL 或其他清理流程删除,而可用 seed 也不存在,版本升级不能补回这些数据。也不应把某个小测试的延迟写成所有部署都能达到的性能指标。
若包含修复的 saver 仍然遍历整条历史,继续检查那个完整值是否实际存在、版本与 namespace 是否匹配,以及自定义序列化或迁移是否改变了存储契约。需要重建时依靠可信备份和原业务记录,不能以“最终列表目前看着正确”代替这些核对。


