sqlalchemy 报错 Lost connection to MySQL server during query 解决

这篇具有很好参考价值的文章主要介绍了sqlalchemy 报错 Lost connection to MySQL server during query 解决。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

sqlalchemy 报错 Lost connection to MySQL server during query 解决

最近在开发过程中遇到一个sqlalchemy lost connection的报错,记录解决方法。

报错信息

python后端开发,使用的框架是Fastapi + sqlalchemy。在一个接口请求中报错如下:

[2023-03-24 06:36:35 +0000] [217] [ERROR] Exception in ASGI application
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/uvicorn/protocols/http/h11_impl.py", line 407, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "/usr/local/lib/python3.8/dist-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
    return await self.app(scope, receive, send)
  File "/usr/local/lib/python3.8/dist-packages/fastapi/applications.py", line 199, in __call__
    await super().__call__(scope, receive, send)
  File "/usr/local/lib/python3.8/dist-packages/starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.8/dist-packages/starlette/middleware/errors.py", line 181, in __call__
    raise exc from None
  File "/usr/local/lib/python3.8/dist-packages/starlette/middleware/errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "/usr/local/lib/python3.8/dist-packages/starlette/middleware/base.py", line 26, in __call__
    await response(scope, receive, send)
  File "/usr/local/lib/python3.8/dist-packages/starlette/responses.py", line 224, in __call__
    await run_until_first_complete(
  File "/usr/local/lib/python3.8/dist-packages/starlette/concurrency.py", line 24, in run_until_first_complete
    [task.result() for task in done]
  File "/usr/local/lib/python3.8/dist-packages/starlette/concurrency.py", line 24, in <listcomp>
    [task.result() for task in done]
  File "/usr/local/lib/python3.8/dist-packages/starlette/responses.py", line 216, in stream_response
    async for chunk in self.body_iterator:
  File "/usr/local/lib/python3.8/dist-packages/starlette/middleware/base.py", line 56, in body_stream
    task.result()
  File "/usr/local/lib/python3.8/dist-packages/starlette/middleware/base.py", line 38, in coro
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.8/dist-packages/starlette_exporter/middleware.py", line 289, in __call__
    await self.app(scope, receive, wrapped_send)
  File "/usr/local/lib/python3.8/dist-packages/starlette/exceptions.py", line 82, in __call__
    raise exc from None
  File "/usr/local/lib/python3.8/dist-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "/usr/local/lib/python3.8/dist-packages/starlette/routing.py", line 580, in __call__
    await route.handle(scope, receive, send)
  File "/usr/local/lib/python3.8/dist-packages/starlette/routing.py", line 241, in handle
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.8/dist-packages/starlette/routing.py", line 55, in app
    await response(scope, receive, send)
  File "/usr/local/lib/python3.8/dist-packages/starlette/responses.py", line 146, in __call__
    await self.background()
  File "/usr/local/lib/python3.8/dist-packages/starlette/background.py", line 35, in __call__
    await task()
  File "/usr/local/lib/python3.8/dist-packages/starlette/background.py", line 20, in __call__
    await run_in_threadpool(self.func, *self.args, **self.kwargs)
  File "/usr/local/lib/python3.8/dist-packages/starlette/concurrency.py", line 40, in run_in_threadpool
    return await loop.run_in_executor(None, func, *args)
  File "/usr/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/app/ymir_app/app/libs/datasets.py", line 330, in ats_import_dataset_in_backgroud
    task = crud.task.create_placeholder(
  File "/app/ymir_app/app/crud/crud_task.py", line 81, in create_placeholder
    db.commit()
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/session.py", line 1428, in commit
    self._transaction.commit(_to_root=self.future)
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/session.py", line 829, in commit
    self._prepare_impl()
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/session.py", line 808, in _prepare_impl
    self.session.flush()
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/session.py", line 3298, in flush
    self._flush(objects)
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/session.py", line 3438, in _flush
    transaction.rollback(_capture_exception=True)
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__
    compat.raise_(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/util/compat.py", line 207, in raise_
    raise exception
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/session.py", line 3398, in _flush
    flush_context.execute()
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/unitofwork.py", line 456, in execute
    rec.execute(self)
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/unitofwork.py", line 630, in execute
    util.preloaded.orm_persistence.save_obj(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/persistence.py", line 242, in save_obj
    _emit_insert_statements(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/persistence.py", line 1219, in _emit_insert_statements
    result = connection._execute_20(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/base.py", line 1582, in _execute_20
    return meth(self, args_10style, kwargs_10style, execution_options)
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/sql/elements.py", line 323, in _execute_on_connection
    return connection._execute_clauseelement(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/base.py", line 1451, in _execute_clauseelement
    ret = self._execute_context(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/base.py", line 1813, in _execute_context
    self._handle_dbapi_exception(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/base.py", line 1994, in _handle_dbapi_exception
    util.raise_(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/util/compat.py", line 207, in raise_
    raise exception
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/base.py", line 1770, in _execute_context
    self.dialect.do_execute(
  File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/engine/default.py", line 717, in do_execute
    cursor.execute(statement, parameters)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/cursors.py", line 148, in execute
    result = self._query(query)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/cursors.py", line 310, in _query
    conn.query(q)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 548, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 775, in _read_query_result
    result.read()
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 1156, in read
    first_packet = self.connection._read_packet()
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 692, in _read_packet
    packet_header = self._read_bytes(4)
  File "/usr/local/lib/python3.8/dist-packages/pymysql/connections.py", line 748, in _read_bytes
    raise err.OperationalError(
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2013, 'Lost connection to MySQL server during query')
[SQL: INSERT INTO task (name, hash, type, state, parameters, config, percent, duration, error_code, user_id, project_id, dataset_id, model_stage_id, is_terminated, is_deleted, last_message_datetime, create_datetime, update_datetime) VALUES (%(name)s, %(hash)s, %(type)s, %(state)s, %(parameters)s, %(config)s, %(percent)s, %(duration)s, %(error_code)s, %(user_id)s, %(project_id)s, %(dataset_id)s, %(model_stage_id)s, %(is_terminated)s, %(is_deleted)s, %(last_message_datetime)s, %(create_datetime)s, %(update_datetime)s)]
[parameters: {'name': 't0000001000012b2ae341679639795', 'hash': 't0000001000012b2ae341679639795', 'type': 5, 'state': 1, 'parameters': '{"group_name": "from_ats_6579a9116a", "description": null, "project_id": 12, "input_url": null, "input_dataset_id": null, "input_dataset_name": null, "input_path": "/data/ymir-workplace/ymir-sharing/3c87e23bb8904b638a9479d6e68aea23", "strategy": 4, "source": 5, "import_type": 5}', 'config': None, 'percent': 0, 'duration': None, 'error_code': None, 'user_id': 1, 'project_id': 12, 'dataset_id': None, 'model_stage_id': None, 'is_terminated': 0, 'is_deleted': 0, 'last_message_datetime': datetime.datetime(2023, 3, 24, 6, 36, 35, 351864), 'create_datetime': datetime.datetime(2023, 3, 24, 6, 36, 35, 351870), 'update_datetime': datetime.datetime(2023, 3, 24, 6, 36, 35, 351873)}]
(Background on this error at: http://sqlalche.me/e/14/e3q8)

主要报错信息是:
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2013, 'Lost connection to MySQL server during query')

在网上搜了很多答案包括:

  1. 设置sqlalchemy 回收链接的时间为10分钟 pool_recycle
    engine = create_engine(url, pool_recycle=600)

  2. 设置每次session操作之前检查 pool_pre_ping
    engine = create_engine("mysql+pymysql://user:pw@host/db", pool_pre_ping=True,pool_recycle=1800)

  3. 不使用连接池
    engine = create_engine("mysql+pymysql://user:pw@host/db", pool_pre_ping=True,pool_recycle=-1)

  4. 检查数据库设置的连接超时时间

经过以上一些列操作还是不能解决问题。于是仔细分析这个问题出现的原因。

分析问题原因

从字面意思来看就是数据库在查询时丢失了连接,这里的连接也就是session。这个接口是一个操作很多的任务,要下载大量数据集,通常在20G以上,所以设计成异步接口。请求接口之后获取一个数据库session,然后处理简单任务直接返回一个成功的状态,最后将耗时任务放在后台任务完成。这里的后台任务是Fastapi自身的功能,专门用于处理一些小型的耗时任务,如发送邮件等。lost connect 就是发生在后台任务中。
抽象任务流程:

  1. 用户调用接口时获取session
  2. 异步接口直接返回
  3. 后台任务下载数据库30分钟左右
  4. 下载完成更新数据库状态,错误发生。

所以通过分析这个任务的流程可以发现是持有session过长导致的。从接口请求的开始就获取了该session,然后将session传递到后台任务中,经过30分钟之后才再次使用该session,就发生了lost connection的问题。

解决办法

知道问题症状所在就知道如何对症下药的了,就是在后台下载任务30分钟之后更新数据库时重新获取一个session,不复用之前的session,这样就就解决了这个问题。

这个问题之所以没有发现是因为按照官网的介绍pool_recycle字段就是负责回收session,配合pool_pre_ping每次使用session之前检查一次就能解决这个session断联的问题。但是似乎在配置的pool_recycle醒没有生效。

可能这个问题是我自身没配置好导致的,但是也可以作为解决此类问题的一个思路。遇到类似问题排查时思考一下,是不是持有session时间过长。

附录猜测过程

sqlalchemy 报错 Lost connection to MySQL server during query 解决文章来源地址https://www.toymoban.com/news/detail-409889.html

到了这里,关于sqlalchemy 报错 Lost connection to MySQL server during query 解决的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 解决Navicat本地连接mysql数据库时报错误:2013-Lost connection to MYSQL server at ‘reading for initial

    在window系统下,用Navicat Premium本地连接MySQL数据库时,报了 错误,就觉得很奇怪,昨天连接的好好的,也没有动配置文件,只是连接本地local host的数据库,为什么会出现这问题呢? 注意到了开了网易UU加速器,是不是因为加速器而连不上呢? 将加速器关掉,没有解决问题。

    2024年02月11日
    浏览(40)
  • 连接MySQL报错,is not allowed to connect to this MySQL server

            本机装的MySQL数据库,本机可以正常连接,其他机器访问报错,is not allowed to connect to this MySQL server,防火墙等其他策略均配置没问题 。   解决方案:         出现该问题的原因是,MySQL数据库只允许自身所在的本机器连接,不允许远程连接。 1、在MySQL所在服务器

    2024年02月16日
    浏览(31)
  • MySQL登录报错1130:1130 Host ***.***.***.*** is not allowed to connect to this MySQL server

    一、问题发现 ​ 从Navicat登录MySQL时报错:1130 Host . . . is not allowed to connect to this MySQL server ​ 原因分析:报错信息表示需要连接的数据库不允许其他主机进行访问,这是因为MySQL的系统数据库mysql中的user表没有配置远程访问主机的登录信息,只有localhost本地登录的信息(如下

    2024年02月13日
    浏览(35)
  • Mysql报错:1130-host ... is not allowed to connect to this MySql server如何处理

    PS:如果出现报错,忽略即可:ERROR 1130: Host ‘192.168.10.173’ is not allowed to connect to this MySQL ERROR 1062 (23000): Duplicate entry ‘%-root’ for key ‘PRIMARY’ 忽略即可

    2024年02月15日
    浏览(33)
  • Mysql登录报错:Can‘t connect to MySQL server on ‘localhost:3306‘ (10061)

    可能每个人遇到问题的情况不一样,首先打开服务我的是当时登录mysql输完密码就会报错:Can\\\'t connect to MySQL server on \\\'localhost:3306\\\' (10061); 网上有的说可以先启动mysql在登陆,但我的输入\\\'net start mysql\\\'也没用,并且我打开服务,发现里面也没有MySql。于是我在想,是不是我的MyS

    2024年02月15日
    浏览(35)
  • 登录mysql报错 Can‘t connect to MySQL server on ‘localhost:3306‘ (10061)解决方法

    1、以管理员身份运行cmd窗口,执行命令mysql -uroot -p,出现错误 Can\\\'t connect to MySQL server on \\\'localhost:3306\\\' (10061),这时执行命令mysqld --console  2、不要关闭第一步的cmd窗口,再以管理员身份运行一个cmd窗口,执行命令mysql -uroot -p,输入正确密码,此时就可登录成功  

    2024年02月13日
    浏览(39)
  • Mysql远程登录报错:Host ‘192.168.137.1‘ is not allowed to connect to this MySQL server

          连接失败是因为数据库没有对指定的ip的服务器地址的连接进行授权,许哦一需要先进行授权。  1. 改表  先登录登录数据库:mysql -u root -p  2.授权 第一步:root用户登录;mysqlmysql -u root -p rootpassword; 第二步:赋予权限; 第三步:刷新数据库; 一定要执行 (1)授权myuse

    2024年02月10日
    浏览(45)
  • Mysql连接本地报错:1130-host ... is not allowed to connect to this MySQL server如何处理

    net stop MySQL57         // 我的MySQL是57版本的 mysqld --skip-grant-tables //执行到这里就只会有光标在一闪一闪无法继续写命令或输入任何命令,故重新再打开一个cmd窗口   mysql flush privileges;  use mysql   //可以看到user表 select Host,User,authentication_string from user; update user set host = \\\'%\\\' whe

    2024年02月07日
    浏览(32)
  • Navicat连接数据库出现 is not allowed to connect to this MySQL server 报错

    我们发现防火墙已经关闭了,还会出现这样的情况,那是因为mysql数据只允许自身所在的本机器连接,不允许进行远程连接 (1)在mysql服务安装的机器上进入mysql:  (2)然后使用 use mysql命令,出现如下报错。  (3)如出现上图报错,那是因为没有修改mysql的初始密码,使用

    2023年04月13日
    浏览(31)
  • 解决Mysql报错2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)

    1.找到mysql文件夹,将my,ini文件放入bin文件夹 2.管理员模式打开cmd 3.输入 netstat -ano 查看端口占用情况,这里我已经开启mysql应用,所以会有3306,如果没有开启是不会有的 4.输入 sc delete mysql ,删除mysql服务 5.将data文件夹下数据进行删除 6.输入 mysqld --initialize --user=mysql --console

    2024年02月14日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包