如何使用自定义连接器正确终止 Django 中的 MySQL/MariaDB 连接

Posted

技术标签:

【中文标题】如何使用自定义连接器正确终止 Django 中的 MySQL/MariaDB 连接【英文标题】:How to properly kill MySQL/ MariaDB connections in Django using custom connectors 【发布时间】:2021-09-12 09:44:19 【问题描述】:

我目前正在处理一个项目,我使用 MariaDB 连接器来运行查询。

我不能使用 ORM,所以我必须使用原始查询。

一般来说,系统工作正常,正如预期的那样,但是当我进行一些“大”查询时,我会收到 Too many connections 错误消息。

我在 mysql 和 MariaDB 连接器上都遇到过这种情况,但我主要使用 MariaDB。

我的代码示例(截断/简化):

import mariadb

def get_cursor():
    conn = mariadb.connect(
    user="user",
    password="pass",
    host="localhost",
    database="db")
    return conn, conn.cursor(named_tuple=True)

def get_duplicated_variants():
    results = []
    conn_cursor  = get_cursor()
    cursor = conn_cursor[1]
    conn = conn_cursor[0]
    try:
        cursor.execute("SELECT * FROM `db`.s_data;")
        columns = [column[0] for column in cursor.description]
        results = []
        for row in cursor.fetchall():
            results.append(dict(zip(columns, row)))
        cursor.close()
        conn.close()
        return results
    except mariadb.Error as e:
        print(f"Error: e")

我尝试过的:

show status like '%onn%';

还有:show variables like 'max_connections';

所以max_used_connections = 152 和我有2503 Connections

我还尝试执行以下查询:

SELECT 
CONCAT('KILL ', id, ';') 
FROM INFORMATION_SCHEMA.PROCESSLIST 
WHERE `User` = 'user' 
AND `Host` = 'localhost'
AND `db` = 'db';

如在this question 中看到的那样。

但是运行查询后连接数是一样的,就不行了。

如何正确关闭连接?

我不明白为什么连接仍然处于活动状态,因为我同时使用 cursor.close() 关闭光标和 conn.close() 关闭连接,但连接显然仍然处于活动状态。

我知道我可以增加 max_connections 类似:set global max_connections = 500; 但我想在查询完成后关闭来自后端的连接。

有什么想法吗?

【问题讨论】:

@nbk del 不会触发垃圾回收。见docs.python.org/3/reference/datamodel.html#object.__del__。调用 del 会将对象的引用计数减少 1,并可能使调用的变量名称 del 无法访问对象。这在很大程度上与 Python 的垃圾收集器分开,后者在 CPython(我假设 Cheknov 正在使用)下主要用于清理引用循环。 您不想在finally: 子句中添加.close() 吗? 只要它终止连接,当然可以。你能提供一个使用例子吗? 【参考方案1】:

位于here 的用于连接close() 的API 肯定清楚连接已关闭。

我知道您说您截断了代码,但是看到您对单个程序中 2,503 个连接的评论肯定会让您看起来好像没有共享该连接,而是为每个查询创建新连接。我建议您检查未包含的代码,以确保您正确存储和重用该连接,这将是昂贵的继续重新创建。

最后,我会改为使用netstat 之类的内容查看状态表,以查看哪些连接真正在进行以及它们来自/来自何处。我并不完全清楚您是否排除了可能来自其他实体到/来自数据库的连接,或者连接实际上并没有被破坏。简而言之,我有点不确定你是否在这里追逐红鲱鱼。我仍然认为 > 2000 个连接似乎出乎意料,您应该首先根据您提供的代码,追查为什么会首先创建这么多连接。

【讨论】:

以上是关于如何使用自定义连接器正确终止 Django 中的 MySQL/MariaDB 连接的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中正确使用自定义标签时遇到问题

如何在 django 中自定义数据库连接设置的时区?

Sonarqube PLSQL 自定义规则,用于在 SQL 脚本文件中检测正确的 SQL 终止符分号

如何正确连接并显示从 Firebase 到自定义列表视图 Android Studio 的数据

如何在 Django 中自定义 slug 字段?

django中的自定义登录URL