【问题标题】:psql: FATAL: remaining connection slots are reserved for non-replication superuser connectionspsql:致命:剩余的连接槽保留用于非复制超级用户连接
【发布时间】:2021-01-11 13:56:11
【问题描述】:

我想了解此错误何时发生以及如何解决。我检查了pg_stat_activitypg_locks,但无法弄清楚哪个进程正在耗尽连接

我们正在使用 sqlalchemy 连接到数据库,如下所示

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine_url = f'{dbms}://{username}:{password}@{hostname}:{port}/{database}'

engine = create_engine(engine_url, pool_size=20, max_overflow=10)
Session = sessionmaker(bind=engine)

db_session = Session()

这是Heroku "psql: FATAL: remaining connection slots are reserved for non-replication superuser connections"的扩展

【问题讨论】:

  • 可能有些东西没有正确关闭连接,所以你的数据库连接用完了。这种情况称为连接泄漏
  • 没错!我想找到导致此连接泄漏的应用程序。有没有办法找出来?
  • 你说你检查了pg_stat_activity。这就是您获得的现有客户端的所有信息:进程 ID、客户端地址、用户、数据库。您必须调查客户端。
  • 有没有办法从这个 pg_stat_activity pid 创建大量连接的客户端进程 id?
  • 没有。这通常在不同的机器上。使用lsof 查看谁拥有与数据库的网络连接。使用pg_terminate_backend 终止数据库会话。

标签: database postgresql database-connection connection-pooling


【解决方案1】:

我在 sqlalchemy 引擎 url 的应用程序名称中添加客户端进程 ID。这将存储在pg_stat_activity 中的application_name 下,有助于调试从何处打开此连接。

import os
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

client_hostname = os.environ.get('HOSTNAME', 'UNKNOWN')
client_pid = os.getpid()


engine_url = f'{dbms}://{username}:{password}@{hostname}:{port}/{database}?application_name={client_hostname}_{client_pid}'

engine = create_engine(engine_url, pool_size=20, max_overflow=10)
Session = sessionmaker(bind=engine)

db_session = Session()

这显示了连接的来源,并且应用程序名称的限制为 64 chars,因此我们可以包含您想要传递给 db stats 的任何自定义信息

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-30
    • 2018-05-19
    • 2012-08-04
    • 2019-03-12
    • 2020-09-22
    • 1970-01-01
    • 2016-11-28
    相关资源
    最近更新 更多