无法重建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
相关产品推荐
相关产品推荐

