快速结论:在 Open WebUI 中永久删除带附件的聊天后,数据库里的 chat_file 关联行、孤立的 file 记录、磁盘上的上传文件以及对应的向量集合不会被清理,长期运行会导致 uploads/ 目录和向量库持续膨胀。优先排查 SQLite 部署下外键是否未生效,以及删除流程是否遗漏了对 file 与磁盘数据的回收逻辑。
适用环境:Open WebUI v0.11.3(在 dev 分支 commit 420b4a2797fa283cd15b5ee267380743115eca5f 上同样复现);Docker 安装;操作系统 Debian 13(Docker 容器)/ Linux x86_64;与浏览器无关。
最快修复方案:暂无确认的一步修复方案。Issue 中记录了根因位置与验证方法,但未给出经验证的补丁或升级版本,需等待官方修复或按下文手动清理。
注意事项:手动清理数据库与磁盘文件存在删错数据的风险,操作前务必先备份数据库和 uploads/ 目录;同时不要假设 PostgreSQL 部署就完全正常,Issue 指出即便外键生效,也缺少判断 file 是否还有其他所有者(chat_file、knowledge_file、channel_file)后再回收的逻辑。
问题场景
使用 Open WebUI(v0.11.3 或任意 v0.11.x 版本,Docker + SQLite 默认部署)创建聊天并上传附件(图片或文档),然后通过 UI 或 API(DELETE /api/v1/chats/{id})永久删除该聊天。删除后再次检查数据库与磁盘时会发现:chat 行已消失,但 chat_file 行仍然存在并指向不存在的 chat_id,file 行依然孤立存在,/app/backend/data/uploads/ 下的物理文件也未被删除。该问题出现在 delete_chat_by_id、delete_chat_by_id_and_user_id、delete_chats_by_user_id、delete_chats_by_user_id_and_folder_id 等删除路径上。
报错原文
issue: deleting chats leaves dangling chat_file links, orphaned file rows, and leaked uploads on disk
-- The chat row is gone:
SELECT * FROM chat WHERE id = '<chat_id>'; -- 0 rows
-- But the chat_file row is still present:
SELECT * FROM chat_file WHERE chat_id = '<chat_id>'; -- 1 row (dangling link!)
-- The file row is still present:
SELECT * FROM file WHERE id = '<file_id>'; -- 1 row (orphaned!)
原因分析
最可能的原因有三层,均来自 Issue 正文的代码定位:
- 数据库关联未级联删除:在 SQLite 部署下,数据库连接未启用
PRAGMA foreign_keys(见internal/db.py),因此models/chats.py:223中定义在ChatFile.chat_id上的ON DELETE CASCADE不会在删除Chat行时触发,chat_file行会一直残留并指向不存在的 chat ID。 - 孤立 file 记录无回收逻辑:即便外键生效,或在 PostgreSQL 上,删除聊天也只移除
chat_file链接,没有逻辑去检查被引用的file行是否还被其他所有者(chat_file、knowledge_file、channel_file)使用,导致file表出现孤立行。 - 物理与向量存储泄漏:由于
file行从未被删除,Storage.delete_file(file.path)与ASYNC_VECTOR_DB_CLIENT.delete(collection_name=f"file-{file_id}")从未被调用,上传文件永久留在磁盘上。
Issue 提到生产服务器审计结果为:残留 78 条 chat_file 悬挂链接、27 条孤立 file 行、14 个物理上传文件共 9.88 MB。
环境排查
- 确认 Open WebUI 版本:Issue 在 v0.11.3 与
dev分支 commit420b4a2797fa283cd15b5ee267380743115eca5f上复现。 - 确认安装方式:Docker。
- 确认操作系统:Debian 13(Docker 容器)/ Linux x86_64。
- 确认数据库类型:SQLite(默认 Docker 部署)为报告中的主要复现环境;PostgreSQL 情况见原因分析第 2 条。
- 确认文件存储路径是否存在残留上传文件,例如
/app/backend/data/uploads/。 - 确认数据库中是否存在悬挂关联,可执行 Issue 提供的审计查询:
SELECT cf.id, cf.chat_id, cf.file_id
FROM chat_file cf
LEFT JOIN chat c ON c.id = cf.chat_id
WHERE c.id IS NULL;
解决步骤
- 先确认当前是否存在泄漏数据。执行上面的审计查询,统计悬挂的
chat_file行;再对file表检查是否存在未被chat_file、knowledge_file、channel_file任一引用的孤立记录。 - 备份数据库文件与
uploads/目录,避免清理过程中误删仍被引用的数据。 - 对照
backend/open_webui/models/chats.py中delete_chat_by_id(约第 2477 行)、delete_chat_by_id_and_user_id(约第 2489 行)、delete_chats_by_user_id(约第 2501 行)、delete_chats_by_user_id_and_folder_id(约第 2522 行)的删除逻辑,确认这些路径是否只删除了 chat 行而未处理chat_file与file。 - 如需缓解,可优先尝试:对确认无其他所有者的孤立
file行执行删除,并同步删除其磁盘文件与向量集合file-{id},使数据库、磁盘与向量库三者一致。此项为基于 Issue 描述的推断处理,Issue 中未给出经验证的一键脚本。 - 关注官方对该 Issue 的修复进展,在修复版本中按正常流程删除聊天,观察是否还会残留
chat_file行与上传文件。
验证方法
重新创建一个带附件的聊天并永久删除后,执行以下检查应全部满足:SELECT * FROM chat_file WHERE chat_id = '<chat_id>' 返回 0 行;SELECT * FROM file WHERE id = '<file_id>' 返回 0 行(前提是该 file 不再被任何 chat_file、knowledge_file、channel_file 引用);/app/backend/data/uploads/ 中对应的物理文件已被移除;向量库中 file-{id} 集合不再存在。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。

![Misc. bug: Vulkan ARGSORT ne=[2048,1,1,1] only sorts half of the array on some devices](https://www.chat-gpts.plus/wp-content/uploads/2026/09/29431-0e9cbdaa-768x403.jpg)
![[Bug] Qwen4Exp QSA indexer: per-chunk logits buffer grows with max_seq_len, caching allocator keeps every size, device OOM/hang on unified-m](https://www.chat-gpts.plus/wp-content/uploads/2026/09/56457-d01dde83-768x403.jpg)