[BUG] Oracle 数据源偶发导致主进程阻塞,容器变为 unhealthy
@xuwei-fit2cloud ya está trabajando en esto.
Desde el 9/9/2026.
- Lenguaje dominante
- JavaScript
- Estrellas
- 6.8k
- Forks
- 882
- Merge medio
- 4 h 37 min
- PR fusionados (30 d)
- 32
Descripción
SQLBot Version
1.10.1
Run Mode
离线安装包
Describe the bug
使用 Oracle 数据源时,服务偶发进入 unhealthy。进程仍在,但主 API(8000,--workers 1)不再响应健康检查。
用 py-spy dump 抓主进程时,MainThread 卡在 Oracle 连接关闭 / 连接池 checkout:
ask_recommend_questions→LLMService.create→get_version- SQLAlchemy pool checkout →
oracledb.connection.close阻塞
To Reproduce
Steps to reproduce the behavior:
- 配置 Oracle 数据源并正常问答
- 模拟网络抖动 / 防火墙短暂阻断,或让池内连接失效
- 触发推荐问题等会调用
get_version的接口 - 观察容器变为 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.
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Evaluación
Este issue todavía no se ha evaluado.