插件窝 干货文章 Python程序长时间运行后断开数据库连接,如何排查及解决?

Python程序长时间运行后断开数据库连接,如何排查及解决?

连接 数据库 password pymysql 918    来源:    2025-03-15

当Python程序长时间运行后断开数据库连接时,通常是由于数据库连接超时、网络问题或数据库服务器配置导致的。以下是排查和解决问题的步骤:

1. 检查数据库连接超时设置

数据库连接通常有一个超时时间,如果在这个时间内没有活动,连接会被自动关闭。你可以检查并调整数据库的超时设置。

  • MySQL: 检查 wait_timeoutinteractive_timeout 参数。

    SHOW VARIABLES LIKE 'wait_timeout';
    SHOW VARIABLES LIKE 'interactive_timeout';
    

    你可以通过修改 my.cnfmy.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'
    

2. 使用连接池

使用连接池可以有效地管理数据库连接,避免频繁地创建和关闭连接。常见的Python数据库连接池库有 SQLAlchemyDBUtils

  • 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()
    

3. 定期检查连接状态

在长时间运行的程序中,定期检查数据库连接的状态,并在必要时重新连接。

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)

4. 处理网络问题

如果网络不稳定,可能会导致数据库连接断开。你可以通过以下方式处理网络问题:

  • 增加重试机制:在连接断开时,尝试重新连接。
  • 使用更稳定的网络环境。

5. 检查数据库服务器日志

查看数据库服务器的日志,了解是否有异常或错误信息导致连接断开。

  • MySQL: 查看 error.log 文件。
  • PostgreSQL: 查看 postgresql.log 文件。

6. 使用心跳机制

在长时间空闲的连接中,定期发送心跳包以保持连接活跃。

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程序长时间运行后断开数据库连接的问题。