Skip to content

[BUG] 账户标识依赖文件名导致删除/重新导入后历史记录断裂 #35

Description

@fangzhengjin

问题概述

在当前实现中,运行时统计与部分持久化表对“账户标识(auth_id / quota_cache id / routing cursor)”的持久化依赖于凭证文件名或由它派生的值。结果是:当用户删除凭证并以不同文件名重新导入同一账号时,历史数据(运行时统计、配额缓存、路由游标、使用日志等)无法与新导入的账号重新关联,从而造成历史记录“断裂”。

复现步骤

问题主要出现在账户订阅升级或降级,重新oauth2认证会生成不同的文件名(-plus、-pro)

  1. 在管理界面或文件系统中添加一个凭证文件(例如 my-account.json)并让系统加载。
  2. 生成一些请求、配额/监控写入(会产生 auth_runtime_stats、quota_cache、routing_cursor_state、usage_events 等记录)。
  3. 删除该凭证文件并以不同的文件名(例如 my-account-2.json)重新导入相同账号的凭证内容。
  4. 发现历史记录没有关联到新导入的账号(UI 与查询结果表现为历史数据丢失或重置)。

受影响范围(关键表/字段)

  • auth_runtime_stats.auth_id — 当前使用 auth.ID(由文件名派生)作为写入值,导入/重命名后无法匹配旧记录。
  • auth_runtime_stats.file_name — 存放文件名 basename(用于追溯,但不能当做稳定标识)。
  • quota_cache.id / quota_cache.file_name — quota_cache 的 id 与 file_name 也含文件名/索引信息,导入后断裂。
  • routing_cursor_state.last_auth_id — 轮询游标记录 last_auth_id,若为文件名派生则会丢失游标位置。
  • usage_events.auth_index — 使用 auth.Index(位置索引),账户顺序变化会影响关联。

根本原因

  • auth_runtime_stats 等模块在写入/恢复时以 auth.ID(当前由文件名或与文件名紧密耦合的值)作为主查找键或恢复回退键。
  • authRuntimeIdentityFingerprint 的实现(见 cliproxyapi-pro-core/patches/auth_runtime_state.go)对指纹的计算依赖 provider、文件名 basename 以及少量 metadata 字段(email、account_id、subject、user_id 等);当 metadata 缺失时指纹退化为依赖文件名(甚至回退到按位置索引 auth.Index),因此文件名变化导致指纹不匹配并在恢复时直接丢弃旧条目。
  • 不同表之间的匹配策略与指纹算法不一致(例如 quota_cache 的指纹/ID 生成与 auth_runtime_stats 不统一),导致跨表重关联困难。

关键代码位置(参考)

  • authRuntimeIdentityFingerprint: cliproxyapi-pro-core/patches/auth_runtime_state.go (指纹计算)
  • authRuntimeStatsSnapshot: cliproxyapi-pro-core/patches/auth_runtime_state.go (构造写入 snapshot 时使用 auth.ID 作为 AuthID)
  • applyStoredAuthRuntimeStats: cliproxyapi-pro-core/patches/auth_runtime_state.go (恢复时使用指纹校验并在不匹配时拒绝应用)
  • store schema 与表定义: cliproxyapi-pro-core/patches/sources/internal/pro/observability/store.go(usage_events、auth_runtime_stats、quota_cache、routing_cursor_state)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions