如何处理Django线程中MySQL连接超时(4031)错误?
解决Django线程中MySQL连接闲置超时(4031错误)的问题
核心原因
问题出在连接池配置与MySQL服务器超时参数不匹配:
- MySQL服务器的
wait_timeout(或interactive_timeout)设置为4-5小时,而连接池的RECYCLE参数设为-1(不自动回收闲置连接),同时CONN_MAX_AGE设为24小时,远大于服务器的超时时间。 - 线程闲置期间,连接池中的连接已被MySQL服务器主动断开,但连接池仍判定连接有效,线程再次使用时就会触发4031错误。
具体修复方案
1. 调整连接池的连接回收时间
修改POOL_OPTIONS中的RECYCLE参数,设置为小于MySQL服务器wait_timeout的值(建议比服务器超时少5分钟,避免时间差导致的问题):
db_config = { 'default': { 'ENGINE': DB_ENGINE, 'NAME': DB_NAME, 'USER': DB_USER, 'PASSWORD': DB_PASSWORD, 'HOST': DB_HOST, 'PORT': DB_PORT, 'CONN_MAX_AGE': 24*60*60, 'POOL_OPTIONS': { 'POOL_SIZE': 10, 'MAX_OVERFLOW': 10, # 假设服务器wait_timeout是4小时(14400秒),这里设为14100秒(3小时55分) 'RECYCLE': 14100 } } }
先通过MySQL命令确认服务器的超时设置:
SHOW VARIABLES LIKE 'wait_timeout'; SHOW VARIABLES LIKE 'interactive_timeout';
2. 在线程执行数据库操作前强制检查连接有效性
由于线程是长时间闲置后才执行操作,可在每次线程执行ORM操作前,主动检查并重建失效连接:
from django.db import connection from django.db.utils import OperationalError def thread_task(): # 执行数据库操作前,检查连接是否有效 with connection.cursor() as cursor: try: cursor.execute("SELECT 1") except OperationalError: # 连接失效,关闭旧连接,Django会自动重建新连接 connection.close() # 后续正常执行ORM操作 YourModel.objects.all()
3. 调整MySQL服务器超时参数(可选)
如果业务允许,可适当调大MySQL的wait_timeout和interactive_timeout,但不建议设得过大(会占用更多服务器资源):
在MySQL配置文件(如my.cnf或my.ini)中添加:
wait_timeout = 28800 # 8小时 interactive_timeout = 28800
修改后重启MySQL服务生效。
4. 确认连接池引擎的兼容性
确保dj_db_conn_pool与当前Django版本、mysqlclient/mysql-connector-python版本兼容,可尝试更新连接池包到最新版本:
pip install --upgrade dj-db-conn-pool
验证方案
修改配置后,让线程闲置超过之前的超时时间(4-5小时),再触发操作,检查是否还会出现4031错误。
内容的提问来源于stack exchange,提问作者BikashSaud
相关产品推荐
相关产品推荐

