Django 从何处着手调查导致数据库崩溃的问题:剩余的连接插槽保留给非复制超级用户连接

Django 从何处着手调查导致数据库崩溃的问题:剩余的连接插槽保留给非复制超级用户连接,django,database,postgresql,Django,Database,Postgresql,我们的Postgres数据库偶尔会崩溃,只有重新启动服务器才能解决。我们已尝试增加最大连接数和Django的CONN_max_AGE。此外,我正在努力学习如何设置PgBouncer。然而,我相信根本的问题必须是其他可以解决的问题 我正试图找出问题所在。问题是,我不知道从哪里开始,从什么开始。以下是一些信息: 错误总是操作错误:致命:剩余的连接插槽保留给非复制超级用户连接和操作错误:无法写入哈希连接临时文件:设备上没有剩余空间。我认为这是由于打开了太多的数据库连接造成的,但我从未设法捕捉到这种情况

我们的Postgres数据库偶尔会崩溃,只有重新启动服务器才能解决。我们已尝试增加最大连接数和Django的
CONN_max_AGE
。此外,我正在努力学习如何设置PgBouncer。然而,我相信根本的问题必须是其他可以解决的问题

我正试图找出问题所在。问题是,我不知道从哪里开始,从什么开始。以下是一些信息:

错误总是
操作错误:致命:剩余的连接插槽保留给非复制超级用户连接
操作错误:无法写入哈希连接临时文件:设备上没有剩余空间
。我认为这是由于打开了太多的数据库连接造成的,但我从未设法捕捉到这种情况,以便我可以检查
pg_stat_activity
并查看哪些实际连接处于活动状态

查看错误日志,大多数情况下都会显示相同的URL。我检查了nginx日志,它在许多不同的行中列出,这意味着请求一次被多次发出,而不是Django多次记录相同的错误。所有这些请求都得到了答复。除了这个URL,当然还有其他用户试图访问我们网站的零星请求

我应该提到,服务器在请求相关URL时处理的逻辑非常简单,我看不到任何可能导致数据库崩溃的可疑情况。但是,由于某些原因,页面在生产中加载缓慢


我知道这是一个非常模糊的问题,也没有什么好处理的,但我不习惯在系统管理员工作,我只是在大学里学习过这类东西,到目前为止我只是作为一名开发人员工作。

这两个问题基本上是独立的

连接插槽不足不会使数据库崩溃。这只是一个迹象,表明您要么不使用连接池,要么存在连接泄漏,即忘记关闭代码中的事务

如果这种情况持续存在,空间不足将导致数据库崩溃

我假设在您的系统中发生以下情况:

  • 由于有人忘记了几个连接条件或其他原因,您的一些查询需要很长时间

    它们还产生许多(可能是中间的)结果,这些结果缓存在临时文件中,最终填满磁盘。一旦查询失败,这种空间不足的情况就会被清除,但它会使数据库崩溃

  • 因为这些查询需要很长时间并阻塞数据库会话,所以应用程序会一直启动新会话,直到达到限制为止

解决方案:

  • 查找并修复此失控查询。作为权宜之计,您可以设置
    statement\u timeout
    来终止所有耗时过长的语句

  • 使用具有上限的连接池,以免连接耗尽


您始终可以设置额外的日志记录来捕获连接和查询。正如您所怀疑的,您的连接正在被耗尽。每次我看到这一点,都是因为代码中的一个bug在使用后没有关闭连接。当然,如果你使用游泳池,那么会有其他地方可以看。有趣。关于缓存的中间结果达到极限,您可能是对的,因为我们肯定会在所有地方使用Django的
select_related
prefetch_related
语句,包括我提到的路线。可能是因为缓存太多,空间过载了吗?但是,正如您所说,如果查询失败并释放了空间,那么崩溃将如何发生?这些缓存结果准确地存储在哪里,以便我可以监控其使用情况?我的回答包含很多猜测,因为这个问题只描述症状。如果PostgreSQL在尝试创建新事务日志文件时空间不足,它将崩溃。临时文件在数据目录的
base/pgsql\u tmp
子目录中创建。您可以在
postgresql.conf
中打开
log_temp_文件
log_min_duration_语句
,以监视临时文件和长时间运行的语句。