diff --git a/pipeline_service/agent_loop.py b/pipeline_service/agent_loop.py index 1076e39..aef088d 100644 --- a/pipeline_service/agent_loop.py +++ b/pipeline_service/agent_loop.py @@ -941,6 +941,8 @@ async def handle_failed_task(task_id: str, project_id: str) -> dict: "WHERE id=${tid}$ AND state='failed'", {"tid": task_id}) if not recs: + # 释放 SELECT 的元数据锁,防止连接回池后阻塞 DDL + await sor.sqlExe("COMMIT", {}) return {"status": "idle", "task_id": task_id} t = recs[0] title = getattr(t, "title", "") or "" @@ -951,6 +953,9 @@ async def handle_failed_task(task_id: str, project_id: str) -> dict: retry_count = 0 last_error = getattr(t, "last_error", "") or "" + # 释放 SELECT 的元数据锁,避免决策/建问题期间长时间持有 MDL + await sor.sqlExe("COMMIT", {}) + # 已重试 3 次仍未成功 → 报故障 if retry_count >= 3: decision = "fault" diff --git a/pipeline_service/init.py b/pipeline_service/init.py index 9f49193..bc450c3 100644 --- a/pipeline_service/init.py +++ b/pipeline_service/init.py @@ -663,6 +663,9 @@ def load_pipeline_service(): _fd_dispatched.discard(tid) asyncio.ensure_future(_fd_dispatch(tid, pid)) + # SELECT-only 事务必须显式 COMMIT,否则连接回到池后仍持有元数据锁(MDL), + # 会阻塞后续 ALTER TABLE / DDL(sqlor 只在有写入时才自动提交)。 + await sor.sqlExe("COMMIT", {}) except Exception as e: debug(f"failed_poller error: {e}") await asyncio.sleep(60)