当Python程序长时间运行后断开数据库连接时,通常是由于数据库连接超时、网络问题或数据库服务器配置导致的。以下是排查和解决问题的步骤:
数据库连接通常有一个超时时间,如果在这个时间内没有活动,连接会被自动关闭。你可以检查并调整数据库的超时设置。
MySQL: 检查 wait_timeout
和 interactive_timeout
参数。
SHOW VARIABLES LIKE 'wait_timeout';
SHOW VARIABLES LIKE 'interactive_timeout';
你可以通过修改 my.cnf
或 my.ini
文件来调整这些参数:
[mysqld]
wait_timeout = 28800
interactive_timeout = 28800
PostgreSQL: 检查 idle_in_transaction_session_timeout
参数。
SHOW idle_in_transaction_session_timeout;
你可以通过修改 postgresql.conf
文件来调整这个参数:
idle_in_transaction_session_timeout = '1h'
使用连接池可以有效地管理数据库连接,避免频繁地创建和关闭连接。常见的Python数据库连接池库有 SQLAlchemy
和 DBUtils
。
SQLAlchemy:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
engine = create_engine('mysql+pymysql://user:password@host/dbname', pool_size=10, pool_recycle=3600)
Session = sessionmaker(bind=engine)
session = Session()
DBUtils:
from dbutils.pooled_db import PooledDB
import pymysql
pool = PooledDB(
creator=pymysql,
host='host',
user='user',
password='password',
database='dbname',
maxconnections=10,
mincached=2,
maxcached=5,
maxusage=100,
blocking=True
)
conn = pool.connection()
在长时间运行的程序中,定期检查数据库连接的状态,并在必要时重新连接。
import time
import pymysql
def check_connection(conn):
try:
conn.ping(reconnect=True)
except pymysql.Error as e:
print(f"Connection error: {e}")
conn = pymysql.connect(host='host', user='user', password='password', database='dbname')
return conn
conn = pymysql.connect(host='host', user='user', password='password', database='dbname')
while True:
# 你的业务逻辑
time.sleep(60) # 每隔60秒检查一次连接
conn = check_connection(conn)
如果网络不稳定,可能会导致数据库连接断开。你可以通过以下方式处理网络问题:
查看数据库服务器的日志,了解是否有异常或错误信息导致连接断开。
error.log
文件。postgresql.log
文件。在长时间空闲的连接中,定期发送心跳包以保持连接活跃。
import time
import pymysql
def send_heartbeat(conn):
try:
with conn.cursor() as cursor:
cursor.execute("SELECT 1")
except pymysql.Error as e:
print(f"Heartbeat failed: {e}")
conn = pymysql.connect(host='host', user='user', password='password', database='dbname')
return conn
conn = pymysql.connect(host='host', user='user', password='password', database='dbname')
while True:
# 你的业务逻辑
time.sleep(60) # 每隔60秒发送一次心跳
conn = send_heartbeat(conn)
通过调整数据库超时设置、使用连接池、定期检查连接状态、处理网络问题、查看数据库服务器日志以及使用心跳机制,可以有效地解决Python程序长时间运行后断开数据库连接的问题。