Skip to content

mongo db 写冲突 #5992

@lck0129

Description

@lck0129

例行检查

  • 我已确认目前没有类似 issue
  • 我已完整查看过项目 README,以及项目文档
  • 我使用了自己的 key,并确认我的 key 是可正常使用的
  • 我理解并愿意跟进此 issue,协助测试和提供反馈
  • 我理解并认可上述内容,并理解项目维护者精力有限,不遵循规则的 issue 可能会被无视或直接关闭

你的版本

  • 公有云版本
  • 私有部署版本, 具体版本号: V4.9.4
    • 部署方式:docker-compose 单实例部署(FastGPT 仅 1 个实例)
    • MongoDB 版本:5.0.18
    • Mongo 连接方式:本地 docker-compose 中的 Mongo 服务(无分片、无复制集)
    • Mongo 连接串参数:无特殊参数(无显式设置 maxPoolSize 等,如果需要我可以补充)

问题描述, 日志截图,配置文件等

问题现象:
同一个对话会话(同一个 chatId)较短时间内收到两条消息 时,FastGPT 更新会话历史(chats 集合)时会触发 MongoDB 的 WriteConflict,导致接口报错,前端 / 调用方拿到错误响应。

FastGPT 日志示例(docker-compose 部署环境):

[Warn] 2025-11-25 16:21:07 Request finish /api/v1/chat/completions, time: 72454ms
[Error] 2025-11-25 16:21:07 update chat history error
{
  message: 'WriteConflict error: this operation conflicted with another operation. Please retry your operation or multi-document transaction.',
  stack: 'MongoServerError: WriteConflict error: this operation conflicted with another operation. Please retry your operation or multi-document transaction.\n' +
    '    at O.sendCommand (/app/projects/app/.next/server/chunks/50290.js:4:65866)\n' +
    '    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n' +
    '    at async O.command (/app/projects/app/.next/server/chunks/50290.js:4:66485)\n' +
    '    at async y.command (/app/projects/app/.next/server/chunks/50290.js:5:85007)\n' +
    '    at async a.executeCommand (/app/projects/app/.next/server/chunks/50290.js:5:26534)\n' +
    '    at async a.execute (/app/projects/app/.next/server/chunks/50290.js:5:61566)\n' +
    '    at async a.execute (/app/projects/app/.next/server/chunks/50290.js:5:61852)\n' +
    '    at async d (/app/projects/app/.next/server/chunks/50290.js:5:37622)\n' +
    '    at async h (/app/projects/app/.next/server/chunks/50290.js:5:35598)\n' +
    '    at async $.updateOne (/app/projects/app/.next/server/chunks/50290.js:4:105165)'
}

MongoDB 日志中在对应时间点附近,可以看到连接数短时间内增加,以及比较长耗时的事务写入(示例为脱敏后的片段):

{"t":{"$date":"2025-11-25T16:21:02.648+00:00"},"s":"I","c":"NETWORK","id":22943,"ctx":"listener",
 "msg":"Connection accepted",
 "attr":{
   "remote":"192.168.0.2:55390",
   "connectionId":57679,
   "connectionCount":47
 }}

{"t":{"$date":"2025-11-25T16:21:02.670+00:00"},"s":"I","c":"TXN","id":51802,"ctx":"conn57655",
 "msg":"transaction",
 "attr":{
   "parameters":{
     "lsid":{"id":{"$uuid":"4710d7b0-a6d3-4795-bbdd-fc40360494f2"}},
     "txnNumber":2,
     "autocommit":false,
     "readConcern":{"level":"local"}
   },
   "ninserted":2,
   "keysInserted":11,
   "terminationCause":"committed",
   "durationMillis":8734
 }}
  • 触发冲突的对象是 chats 集合中某个会话文档(含 variables.historyList 等字段)。当同一个会话在短时间内有多条消息 / 多次重试时,会同时对这条文档进行更新;
  • MongoDB 侧并没有抛出其他错误,只是正常的文档级 WriteConflict。目前 FastGPT 对 WriteConflict 没有自动重试机制,错误直接抛到了上层。

我的理解是:同一会话在短时间内存在“并发写同一条 chats 文档”的情况(例如 historyList 的追加),导致 Mongo 返回 WriteConflict。在单实例 FastGPT 环境下,这种冲突应该可以通过应用层串行化 / 重试来避免对用户的直接影响。

如果需要,我可以提供更完整的 Mongo 日志片段和 chats 文档结构(脱敏后)供分析。

复现步骤

目前我这边的复现方式大致如下(在 V4.9.4、docker-compose、Mongo 5.0.18 环境):

  1. 启动单实例 FastGPT(docker-compose),连接本地 Mongo 5.0.18;

  2. 创建一个应用 / 对话机器人,使用默认的会话存储方式(chats + chatitems),历史上下文配置使用默认值或较大的轮数;

  3. 打开同一个对话(同一个 chatId),在短时间内对这个会话发送多条消息:

    • 比如第一条提问还在处理中(还没完全返回 / history 写入还没结束)的时候,再快速点击发送第二条消息;
    • 或在回答过程中多次点击“重试 / 重新生成”;
  4. 在某些情况下,请求会在几十秒后报错(例如 Request finish /api/v1/chat/completions, time: 72454ms 这样较长处理时间),同时后端日志出现:

    [Error] update chat history error
    MongoServerError: WriteConflict error: this operation conflicted with another operation...
    
  5. 对应时间点在 MongoDB 日志中也可看到相关的写事务和连接活动。

(注:目前复现并不是 100% 稳定,但在“同一会话快速连续发送 / 重试”的情况下,偶尔会出现上述报错。)

预期结果

  • 在同一个会话(同一个 chatId)存在并发写入时,希望 FastGPT 能够通过合理的并发控制或重试机制,避免 WriteConflict 直接暴露给最终用户;
  • 建议:
    1. 服务端对单个 chatId 的会话更新做串行化处理,避免同时对同一条 chats 文档进行写操作;
    2. 在写 chats(或相关会话文档)时,对 MongoDB 的 WriteConflict 进行有限次数的自动重试(带简单退避),而不是直接抛出;
    3. 或基于 version 字段 / updatedAt 做乐观锁与幂等更新,确保会话更新在并发情况下可恢复、可重试。

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions