From 57dfc4f125921c17a5ad063e99d1f2fce55726e4 Mon Sep 17 00:00:00 2001 From: Vincent <1729065730@qq.com> Date: Mon, 2 Nov 2026 17:24:14 +0800 Subject: [PATCH] fix(knowledge): tolerate concurrent HNSW index creates Parallel document embedding for one knowledge base can all pass the pg_indexes existence check and then race on CREATE INDEX, raising DuplicateTable. Use CREATE INDEX IF NOT EXISTS so losers of the race do not fail the embedding task (Fixes #7596). Signed-off-by: Vincent <1729065730@qq.com> --- apps/knowledge/serializers/common.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/knowledge/serializers/common.py b/apps/knowledge/serializers/common.py index 83b1038e356..a259a4289b1 100644 --- a/apps/knowledge/serializers/common.py +++ b/apps/knowledge/serializers/common.py @@ -269,9 +269,12 @@ def create_knowledge_index(knowledge_id=None, document_id=None): dims = result[0]['dims'] # 超过2000维度不创建索引,pgvector hnsw索引不支持超过2000维度 if dims < 2000: - sql = f"""CREATE INDEX "embedding_hnsw_idx_{k_id}" ON embedding USING hnsw ((embedding::vector({dims})) vector_cosine_ops) WHERE knowledge_id = '{k_id}'""" + # IF NOT EXISTS: parallel document embedding tasks for the same + # knowledge base can all pass the pg_indexes check above, then race + # on CREATE INDEX (DuplicateTable). Treat a concurrent create as OK. + sql = f"""CREATE INDEX IF NOT EXISTS "embedding_hnsw_idx_{k_id}" ON embedding USING hnsw ((embedding::vector({dims})) vector_cosine_ops) WHERE knowledge_id = '{k_id}'""" update_execute(sql, []) - maxkb_logger.info(f'Created index for knowledge ID: {k_id}') + maxkb_logger.info(f'Ensured index for knowledge ID: {k_id}') def drop_knowledge_index(knowledge_id=None, document_id=None):