You need to enable JavaScript to run this app. 无法重建MariaDB ConnectionPool,二次调用时进程无报错挂死
优惠活动
大模型
产品
解决方案
定价
更多

无法重建MariaDB ConnectionPool,二次调用时进程无报错挂死

问题根因

MariaDB Python连接器的ConnectionPool是按pool_name全局注册的,同一进程内同名连接池不允许重复创建。你当前的代码只关闭了从连接池获取的单个连接,没有显式销毁连接池本身,第一次调用first()创建的pool1注册信息一直残留在进程中,第二次调用再尝试创建同名连接池时就会触发无报错的挂起异常。

解决方案

分两种使用场景选择对应方案:

场景1:需要每次方法调用独立创建、销毁连接池

每次使用完连接池后,显式调用pool.close()方法销毁连接池,清除全局注册信息。修改后的代码如下:

import mariadb

def first():
    pool = mariadb.ConnectionPool(
        pool_name = 'pool1',
        pool_size = 3,
        pool_reset_connection = False,
        host = '127.0.0.1',
        user = 'root',
        password = 'secret',
        database = 'test',
    )

    conn1 = pool.get_connection()
    conn2 = pool.get_connection()
    conn3 = pool.get_connection()

    cursor = conn1.cursor()
    cursor.execute('INSERT INTO sample VALUES (?, ?)', (1, 2))

    cursor = conn2.cursor()
    cursor.execute('INSERT INTO sample VALUES (?, ?)', (3, 4))

    cursor = conn3.cursor()
    cursor.execute('INSERT INTO sample VALUES (?, ?)', (5, 6))

    conn1.commit()
    conn2.commit()
    conn3.commit()

    conn1.close()
    conn2.close()
    conn3.close()
    # 新增:销毁连接池
    pool.close()


def main():
    first()
    first()

场景2:需要复用连接池(推荐生产环境使用)

连接池的设计初衷就是减少连接重复创建的开销,没必要每次方法调用都新建销毁。建议将连接池改为全局单例初始化,整个进程生命周期复用同一个连接池,进程退出前再销毁:

import mariadb

# 全局初始化一次连接池
pool = mariadb.ConnectionPool(
    pool_name = 'pool1',
    pool_size = 3,
    pool_reset_connection = False,
    host = '127.0.0.1',
    user = 'root',
    password = 'secret',
    database = 'test',
)

def first():
    conn1 = pool.get_connection()
    conn2 = pool.get_connection()
    conn3 = pool.get_connection()

    cursor = conn1.cursor()
    cursor.execute('INSERT INTO sample VALUES (?, ?)', (1, 2))

    cursor = conn2.cursor()
    cursor.execute('INSERT INTO sample VALUES (?, ?)', (3, 4))

    cursor = conn3.cursor()
    cursor.execute('INSERT INTO sample VALUES (?, ?)', (5, 6))

    conn1.commit()
    conn2.commit()
    conn3.commit()

    # 这里close只是把连接归还到池,不是销毁连接
    conn1.close()
    conn2.close()
    conn3.close()


def main():
    first()
    first()
    # 进程退出前再销毁连接池
    pool.close()

if __name__ == "__main__":
    main()

注意事项

  • pool.close()执行时会自动关闭池内所有空闲连接,已经被取出未归还的连接会在后续归还时自动销毁,不会造成资源泄漏。
  • 多线程场景下不要频繁创建销毁连接池,复用全局单例连接池的性能表现最优。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 16:36:04