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

Django大文件夹压缩后MySQL连接超时问题求助

问题原因分析

你的压缩任务最长耗时48小时,远超过Django配置的CONN_MAX_AGE(25分钟)和MySQL的wait_timeout(8小时),任务执行期间数据库连接早已被MySQL主动关闭。之前的方法无效主要有几个核心原因:

  • close_old_connections()仅处理当前线程的连接,若压缩任务在独立线程/进程中执行,主线程调用该方法无法清理任务线程的旧连接;且该方法仅回收超过CONN_MAX_AGE的连接,无法识别已被MySQL主动关闭的失效连接。
  • 遍历connections.all()若未主动触发重新连接,Django执行ORM操作时可能仍从连接池中复用残留的失效连接。
彻底解决方法

1. 数据库操作前强制重建连接

在执行ExportStatus更新的代码块中,彻底关闭当前线程所有连接并主动重建:

from django.db import connections

def update_export_status(export_id, package_size, zip_time):
    # 遍历所有数据库连接,强制关闭并重建
    for conn in connections.all():
        conn.close()
        conn.connect()
    
    # 执行更新操作
    ExportStatus.objects.filter(id=export_id).update(
        package_size=package_size,
        zip_time=zip_time
    )

2. 异步任务场景的连接管理优化

如果压缩任务通过Celery等异步框架执行,需在任务启动和数据库操作前两次重置连接:

from celery import shared_task
from django.db import connections

@shared_task
def compress_folder_task(export_id, folder_path):
    # 任务启动时先清理旧连接,避免后续复用失效连接
    for conn in connections.all():
        conn.close()
    
    # 执行压缩逻辑(耗时48小时的操作)
    package_size, zip_time = perform_large_compression(folder_path)
    
    # 更新前再次重置并重建连接
    for conn in connections.all():
        conn.close()
        conn.connect()
    
    ExportStatus.objects.filter(id=export_id).update(
        package_size=package_size,
        zip_time=zip_time
    )

3. 辅助配置优化

  • 调整CONN_MAX_AGE至小于MySQLwait_timeout的值(比如设为3600秒),让Django主动回收旧连接:
# settings.py
DATABASES = {
    'default': {
        # 其他数据库配置
        'CONN_MAX_AGE': 3600,
        'OPTIONS': {
            # 启用MySQL自动重连作为辅助机制
            'init_command': 'SET AUTO_RECONNECT=1',
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:35:23