dataease / dataease/SQLBot

[BUG] Oracle 数据源偶发导致主进程阻塞,容器变为 unhealthy

未关闭
#1,360 1 条评论 0 个 reaction 已指派 2 人 在 GitHub 查看

@xuwei-fit2cloud 已经在做这个了。

开始于 2026年9月9日。

bug Done
主要语言
JavaScript
星标
6.8k
派生
882
平均合并
4 小时 37 分钟
30 天内合并 PR
32

描述

SQLBot Version
1.10.1
Run Mode
离线安装包

Describe the bug
使用 Oracle 数据源时,服务偶发进入 unhealthy。进程仍在,但主 API(8000,--workers 1)不再响应健康检查。
py-spy dump 抓主进程时,MainThread 卡在 Oracle 连接关闭 / 连接池 checkout:

  • ask_recommend_questionsLLMService.createget_version
  • SQLAlchemy pool checkout → oracledb.connection.close 阻塞

To Reproduce
Steps to reproduce the behavior:

  1. 配置 Oracle 数据源并正常问答
  2. 模拟网络抖动 / 防火墙短暂阻断,或让池内连接失效
  3. 触发推荐问题等会调用 get_version 的接口
  4. 观察容器变为 unhealthy;py-spy dump --pid <uvicorn:8000> 可见卡在 oracledb...close

Expected behavior
Oracle 连接异常应在超时后失败并返回错误,不应阻塞主进程导致整体 unhealthy。

Screenshots

root@f6b6cb8e3d19:/opt/sqlbot/app# ps aux |grep python
root 48 0.0 1.7 1559404 288132 ? Sl Aug31 5:14 /opt/sqlbot/app/.venv/bin/python /opt/sqlbot/app/.venv/bin/uvicorn main:mcp_app --host 0.0.0.0 --port 8001 --proxy-headers --forwarded-allow-ips=*
root 49 0.0 3.4 4600232 561412 ? Sl Aug31 6:33 /opt/sqlbot/app/.venv/bin/python /opt/sqlbot/app/.venv/bin/uvicorn main:app --host 0.0.0.0 --port 8000 --workers 1 --proxy-headers --forwarded-allow-ips=*
root 21299 0.0 0.0 6324 892 pts/0 S+ 09:13 0:00 grep python
root@f6b6cb8e3d19:/opt/sqlbot/app# py-spy dump --pid 49
Process 49: /opt/sqlbot/app/.venv/bin/python /opt/sqlbot/app/.venv/bin/uvicorn main:app --host 0.0.0.0 --port 8000 --workers 1 --proxy-headers --forwarded-allow-ips=*
Python v3.11.14 (/usr/local/bin/python3.11)

Thread 49 (idle): "MainThread"
_close (oracledb/connection.py:939)
close (oracledb/connection.py:1026)
do_close (sqlalchemy/engine/default.py:721)
do_terminate (sqlalchemy/engine/default.py:718)
_close_connection (sqlalchemy/pool/base.py:373)
__close (sqlalchemy/pool/base.py:883)
get_connection (sqlalchemy/pool/base.py:863)
checkout (sqlalchemy/pool/base.py:715)
_checkout (sqlalchemy/pool/base.py:1272)
connect (sqlalchemy/pool/base.py:448)
raw_connection (sqlalchemy/engine/base.py:3319)
init (sqlalchemy/engine/base.py:144)
connect (sqlalchemy/engine/base.py:3295)
_connection_for_bind (sqlalchemy/orm/session.py:1191)
_go (sqlalchemy/orm/state_changes.py:137)
_connection_for_bind (:2)
_connection_for_bind (sqlalchemy/orm/session.py:2113)
_execute_internal (sqlalchemy/orm/session.py:2261)
execute (sqlalchemy/orm/session.py:2373)
get_version (apps/db/db.py:434)
init (apps/chat/task/llm.py:182)
create (apps/chat/task/llm.py:238)
ask_recommend_questions (apps/chat/api/chat.py:209)
run_endpoint_function (fastapi/routing.py:212)
app (fastapi/routing.py:301)
app (starlette/routing.py:73)
wrapped_app (starlette/_exception_handler.py:42)
app (starlette/routing.py:76)
handle (starlette/routing.py:288)
app (starlette/routing.py:734)
call (starlette/routing.py:714)
wrapped_app (starlette/_exception_handler.py:42)
call (starlette/middleware/exceptions.py:62)
simple_response (starlette/middleware/cors.py:144)
call (starlette/middleware/cors.py:93)
coro (starlette/middleware/base.py:141)
_run_coro (anyio/_core/_tasks.py:275)
run (asyncio/runners.py:118)
asyncio_run (uvicorn/_compat.py:30)
run (uvicorn/server.py:77)
run (uvicorn/main.py:621)
main (uvicorn/main.py:490)
invoke (click/core.py:907)
invoke (click/core.py:1353)
main (click/core.py:1490)
call (click/core.py:1569)
(uvicorn:10)
Thread 107 (idle): "ThreadPoolExecutor-1_0"
_worker (concurrent/futures/thread.py:81)
run (threading.py:982)
_bootstrap_inner (threading.py:1045)
_bootstrap (threading.py:1002)
Thread 108 (idle): "ThreadPoolExecutor-1_1"
_worker (concurrent/futures/thread.py:81)
run (threading.py:982)
_bootstrap_inner (threading.py:1045)
_bootstrap (threading.py:1002)
Thread 110 (idle): "ThreadPoolExecutor-1_2"
_worker (concurrent/futures/thread.py:81)
run (threading.py:982)
_bootstrap_inner (threading.py:1045)
_bootstrap (threading.py:1002)
Thread 158 (idle): "ThreadPoolExecutor-3_0"
_worker (concurrent/futures/thread.py:81)
run (threading.py:982)
_bootstrap_inner (threading.py:1045)
_bootstrap (threading.py:1002)
Thread 164 (idle): "ThreadPoolExecutor-2_0"
_worker (concurrent/futures/thread.py:81)
run (threading.py:982)
_bootstrap_inner (threading.py:1045)
_bootstrap (threading.py:1002)
Thread 248 (idle): "ThreadPoolExecutor-3_1"
_worker (concurrent/futures/thread.py:81)
run (threading.py:982)
_bootstrap_inner (threading.py:1045)
_bootstrap (threading.py:1002)
Thread 249 (idle): "ThreadPoolExecutor-3_2"
_worker (concurrent/futures/thread.py:81)
run (threading.py:982)
_bootstrap_inner (threading.py:1045)
_bootstrap (threading.py:1002)
Thread 4387 (idle): "tqdm_monitor"
wait (threading.py:331)
wait (threading.py:629)
run (tqdm/_monitor.py:69)
_bootstrap_inner (threading.py:1045)
_bootstrap (threading.py:1002)
Thread 4388 (idle): "tqdm_monitor"
wait (threading.py:331)
wait (threading.py:629)
run (tqdm/_monitor.py:69)
_bootstrap_inner (threading.py:1045)
_bootstrap (threading.py:1002)
Thread 25124 (idle): "ThreadPoolExecutor-2_1"
_worker (concurrent/futures/thread.py:81)
run (threading.py:982)
_bootstrap_inner (threading.py:1045)
_bootstrap (threading.py:1002)
Thread 21251 (idle): "AnyIO worker thread"
wait (threading.py:327)
get (queue.py:171)
run (anyio/_backends/_asyncio.py:1022)
_bootstrap_inner (threading.py:1045)
_bootstrap (threading.py:1002)
Thread 21263 (idle): "AnyIO worker thread"
wait (threading.py:327)
get (queue.py:171)
run (anyio/_backends/_asyncio.py:1022)
_bootstrap_inner (threading.py:1045)
_bootstrap (threading.py:1002)
root@f6b6cb8e3d19:/opt/sqlbot/app#

Additional context
Add any other context about the problem here.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。