bug: Data retention (TTL) deletes traces referenced by annotation queue items, leaving orphaned items

此 bug 发生在自托管 Langfuse 配置了数据保留 (TTL) 且项目存在标注队列(Annotation Queue)时。TTL 删除 trace 时不检查是否有 AnnotationQueueItem 引用,导致孤儿记录。核心英文报错: bug: Data retention (TTL)

快速结论:此 bug 发生在自托管 Langfuse 配置了数据保留 (TTL) 且项目存在标注队列(Annotation Queue)时。TTL 删除 trace 时不检查是否有 AnnotationQueueItem 引用,导致孤儿记录。核心英文报错:bug: Data retention (TTL) deletes traces referenced by annotation queue items, leaving orphaned items。优先排查 TTL 清理逻辑中是否加入了引用检查,或查看是否存在孤儿队列项。

适用环境:Langfuse 自托管版本 v3.150.0。

最快修复方案:暂无确认的一步修复方案。Issue 报告时社区建议了四种方向,但均未作为正式补丁合并。建议关注官方后续版本是否在 TTL 删除前检查 AnnotationQueueItem.objectId 引用,或者实现级联删除。

注意事项:如果已出现孤儿项,UI 已通过 PR #10417 做了容错(不崩溃但仍显示“Trace not found”)。该 bug 本身不会导致数据损坏,但会导致标注队列项无法使用。

问题场景

自托管用户在使用 Langfuse 时,为项目设置了 N 天的数据保留(TTL)。等待 N 天后(或设置极短的保留期用于测试),打开标注队列(Annotation Queue)UI,原本引用已过期 traces 的队列项显示“Trace not found”。此问题仅影响自托管部署,Langfuse Cloud 不在 Issue 讨论范围内。

报错原文

Trace not found — Path: `traces.byIdWithObservationsAndScores`

原因分析

可能原因是 Langfuse 的 TTL 删除逻辑(位于 handleDataRetentionProcessingJob.tsBatchDataRetentionCleaner)执行直接 DELETE 查询时,仅依据时间戳条件 (timestamp < cutoffDate),未检查 AnnotationQueueItem 中的 objectId 字段是否引用了即将被删除的 trace。由于 AnnotationQueueItem.objectId 是简单字符串,没有外键约束到 ClickHouse 中的 trace 表,删除操作静默执行,导致 PostgreSQL 中的 AnnotationQueueItem 记录变成孤儿项。

环境排查

  • 确认 Langfuse 版本是否为 v3.150.0 或相近版本(此版本已确认存在该 bug)。
  • 确认项目是否启用了标注队列(Annotation Queue),且队列项中 objectId 指向 ClickHouse 中的 trace。
  • 确认数据保留(TTL)是否已生效,可通过查询 ClickHouse 确认过期 trace 是否已被删除。
  • 检查 AnnotationQueueItem 表中是否存在 objectId 对应 trace ID 在 ClickHouse 中已不存在的记录。

解决步骤

  1. 临时缓解(UI 层面):确保部署已包含 PR #10417 的更改(该 PR 对孤儿项做了 UI 侧优雅处理,避免崩溃)。该 PR 已合并,升级至包含此提交的版本可减少错误提示。
  2. 推荐修复方向(需代码改动)
    1. 在 TTL 删除 trace 之前,通过 AnnotationQueueItem 表查询即将删除的 trace ID,跳过那些被队列引用的 trace。
    2. 或者实现级联清理:当 trace 因 TTL 被删除时,同步删除(或标记过期)对应的 AnnotationQueueItem 记录。
    3. 作为附加改进,在用户设置项目数据保留时,若项目存在活跃标注队列,给出警告提示。
  3. 手动清理孤儿项(临时):对于已存在的孤儿 AnnotationQueueItem,可通过数据库直接删除或标记,但需谨慎操作,不丢失业务数据。
  4. 遵循官方更新:关注 Langfuse PR 中是否合并了相关修复,升级至最新版。

验证方法

在修复后,重新打开标注队列,确认原本显示“Trace not found”的项不再出现,或显示正确的“该 trace 已被数据保留删除”等提示。同时检查 PostgreSQL 中不再存在 objectId 对应已不存在 trace 的 AnnotationQueueItem 记录。

参考来源

langfuse/langfuse #12852

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 15969

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注