You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行Telegram机器人约24小时后出现'MySQL server has gone away'错误如何解决?

wait_timeout = 28800

调整后故障依旧,运行约24小时仍会抛出相同异常。
- 将`CONN_MAX_AGE`设置为`None`,无任何改善。
- 按照网友建议安装了`mysql-server-has-gone-away` Python包,运行近24小时后还是会出现相同报错。
- 尝试手动关闭旧连接的方案,代码如下:
```python
from django.db import close_old_connections

try:
    # 执行数据库操作
except django.db.utils.OperationalError:
    close_old_connections()
    # 重试执行数据库操作

调整后仍未解决问题。

解决方案

核心原因

Django的数据库连接自动回收逻辑(基于CONN_MAX_AGE)默认仅在HTTP请求生命周期结束时触发,你运行的是长期在线的自定义Django命令,不属于HTTP请求场景,没有自动触发连接回收的时机,导致连接被MySQL服务端超时关闭后,Django仍在复用失效连接。
另外你之前在my.cnf的[client]段设置wait_timeout完全不生效,该参数是MySQL服务端配置,需要写在[mysqld]段才会生效,这也是之前调整参数没用的核心原因之一。

修复步骤

  1. 主动触发连接回收:给python-telegram-bot加全局前置处理器,所有更新处理前先调用close_old_connections(),Django会自动判断连接是否过期,过期则关闭重建,不会额外消耗性能,不用修改每个业务回调函数:
from telegram.ext import BaseHandler
from django.db import close_old_connections

class DBConnectionPreprocessor(BaseHandler):
    def check_update(self, update):
        close_old_connections()
        # 返回False让后续业务handler继续处理更新
        return False

# 注册handler时放在最前面保证优先执行
dispatcher.add_handler(DBConnectionPreprocessor())
  1. 调整CONN_MAX_AGE参数:将settings.py中的CONN_MAX_AGE设置为300(5分钟),远小于MySQL默认的8小时超时阈值,确保Django主动回收连接的时机早于MySQL关闭连接的时机。
  2. 兜底重试逻辑:如果仍偶现报错,可以给数据库操作加简单的重试逻辑:
from django.db import close_old_connections, OperationalError

def run_db_safe(func, retries=2):
    for _ in range(retries):
        try:
            return func()
        except OperationalError:
            close_old_connections()
    # 重试耗尽后抛出原始异常
    return func()

# 调用示例
u = run_db_safe(lambda: Telegram.objects.get(idtelegram=userid))

内容的提问来源于stack exchange,提问作者nKn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 08:36:03