标题: [Bug][数据一致性] index_file 的 Milvus+PostgreSQL 双写用并发 gather + best-effort 回滚,回滚失败残留单边数据
正文:
问题
backend/package/yuxi/knowledge/implementations/milvus.py(约 534 行)_insert_chunks_to_stores 同时写 PostgreSQL(chunk_repo.batch_upsert)与 Milvus(collection.insert):
pg_task = chunk_repo.batch_upsert(self._build_chunk_pg_records(kb_id, chunks))
milvus_task = asyncio.to_thread(_insert_milvus_records)
results = await asyncio.gather(pg_task, milvus_task, return_exceptions=True)
...
await chunk_repo.delete_by_file_id(file_id) # rollback,失败仅 log
try:
await self._delete_file_chunks_from_milvus(collection, file_id)
except Exception as cleanup_error:
logger.error(...)
- 任一失败后回滚是 best-effort:回滚的异常只记日志,若回滚时对端网络异常,留下"PG 有 chunk 但 Milvus 没有"或反之的单边数据;
- 嵌入中途某批失败时已写批次先落库,文件状态置
ERROR_INDEXING,需人工重索引才能收敛;状态机无自动重试。
建议
- 双写改为以 PG 为准 + 幂等重试:PG 写入成功后,Milvus 插入可重试(插入按 file_id/chunk_id 幂等),不依赖并发 gather 的强一致;
- 失败进入补偿/重试队列,而不是置 ERROR_INDEXING 就放弃;
- 增加对账:比对 PG chunks 与 Milvus 集合中按 file_id 的向量,定期清理单边残留。
标题: [Bug][数据一致性] index_file 的 Milvus+PostgreSQL 双写用并发 gather + best-effort 回滚,回滚失败残留单边数据
正文:
问题
backend/package/yuxi/knowledge/implementations/milvus.py(约 534 行)_insert_chunks_to_stores同时写 PostgreSQL(chunk_repo.batch_upsert)与 Milvus(collection.insert):ERROR_INDEXING,需人工重索引才能收敛;状态机无自动重试。建议