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

aiomysql在Discord bot事件中随机触发Task pending销毁报错如何排查?

你遇到的Task was destroyed but it is pending!错误核心原因是绑定到Discord事件的异步任务还没执行完成就被垃圾回收销毁了,结合你的代码,具体问题和修复方案如下:

问题根因

  1. 连接池被重复创建覆盖
    discord.py的on_ready事件并非仅触发一次,每次和Discord网关重连后都会重新触发该事件。你的getpool函数没有做防重复判断,每次调用都会生成新的连接池并覆盖全局变量,旧连接池中还在被使用的连接会变成游离状态,依赖这些连接的数据库操作会直接卡住,导致对应的事件任务一直处于pending状态,最终被销毁时报错。
  2. 连接池配置错误
    你将pool_recycle参数设为0,关闭了连接自动回收逻辑。MySQL服务端默认会主动断开空闲超过8小时的连接,aiomysql无法主动感知连接已失效,执行查询时会一直等待响应,也会导致任务卡住。
  3. 缺少连接池清理逻辑
    bot进程退出或断开重连时,没有手动关闭现有连接池,正在执行的数据库操作会被强制中断,pending状态的任务就会触发报错。
  4. 缺少边界情况处理
    如果bot启动后,on_ready还没执行完成就收到了事件,此时全局pool还是None,调用数据库操作方法会直接抛出未捕获异常,也可能导致任务异常终止。

修复方案

  • 调整连接池初始化逻辑,避免重复创建
    修改mysqlconnection.py中的getpool函数,增加初始化判断,同时调整pool_recycle配置:
async def getpool():
    global pool
    # 仅当连接池不存在时才创建,避免重复覆盖
    if pool is None:
        pool = await aiomysql.create_pool(
            host="", 
            user="", 
            password="", 
            db="", 
            pool_recycle=3600, # 配置为1小时自动回收连接,小于MySQL默认的8小时超时即可
            minsize=2, # 最小空闲连接数,按需调整
            maxsize=10 # 最大连接数,按需调整
        )
  • 增加连接池清理逻辑
    在bot.py中注册断开连接钩子,进程退出或重连时主动释放连接池:
@bot.event
async def on_disconnect():
    global pool
    if pool is not None:
        pool.close()
        await pool.wait_closed()
        pool = None
  • 给事件回调增加异常捕获
    所有涉及数据库操作的事件回调外层增加异常捕获,避免未处理异常导致任务卡住:
async def on_raw_message_delete(payload):
    try:
        # 你的原有业务逻辑,包含数据库操作代码
    except Exception as e:
        # 按需打印日志或者上报错误
        print(f"on_raw_message_delete处理失败: {str(e)}")
  • 可选:增加连接池初始化判断
    可以在execute_search和execute_alter函数开头增加判断,如果连接池还未初始化,先等待getpool执行完成,避免启动阶段调用报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:24:01