为什么 PostgreSQL 说 FATAL:抱歉,当我远未达到最大连接数时,客户端已经太多了?

问题描述

我正在安装 Postgresql 11.2,它会定期在系统日志中抱怨

FATAL:  sorry,too many clients already

尽管远未达到其配置的连接限制。此查询

SELECT current_setting('max_connections') AS max,COUNT(*) AS total
FROM pg_stat_activity

告诉我数据库配置为最多 100 个连接。我从未见过使用此查询连接到数据库的大约 45 个以上,甚至在运行的程序收到数据库错误之前也没有看到过,说 Postgres 日志中的上述消息支持的客户端太多。

我能在 Internet 上找到的关于问题的所有内容都表明错误意味着您已超出 max_connections 设置,但数据库本身告诉我我没有。

就其价值而言,pyspark 是唯一触发此错误数据库客户端,并且仅当它从数据帧写入表时。使用 psycopg2(即主客户端)的常规 python 代码永远不会触发它(即使从 Pandas 数据帧以相同的方式写入表时也不会),并且像 pgAdmin 这样的管理工具也永远不会触发它。如果我没有直接在数据库日志中看到错误,我会认为 Spark 在错误方面对我撒谎。大多数时候,如果我使用这样的查询

SELECT pg_terminate_backend(pid) FROM pg_stat_activity 
WHERE pid <> pg_backend_pid() AND application_name LIKE 'pgAdmin%';

然后问题消失了几天。但是就像我说的那样,根据数据库本身,我从未见过假设的最大 100 个连接中的 50% 正在使用中。我如何找出导致此错误的原因?

解决方法

三种可能:

  1. 这些联系非常短暂,在您查看时它们已经消失了。

  2. 您对该数据库的连接限制较低。

  3. 您对数据库用户的连接限制较低。

但选项 2 和选项 3 会导致不同的错误消息,因此它必须是短连接。

无论是什么,问题的答案都是配置良好的连接池。

,

这是由 Spark 使用 JDBC 读取/写入数据的方式引起的。 Spark 尝试打开多个与数据库的并发连接,以便并行读取/写入多个数据分区。

我在文档中找不到它,但我认为默认情况下,连接数等于要写入 db 表的 datafame 中的分区数。这解释了您注意到的间歇性。

但是,您可以通过设置 numPartitions 选项来控制此数字:

可用于并行的最大分区数 表读取和写入。这也决定了最大数量 并发 JDBC 连接。如果要写入的分区数 超过此限制,我们通过调用将其降低到此限制 coalesce(numPartitions) 写之前。

示例:

spark.read.format("jdbc") \
          .option("numPartitions","20") \
# ...

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...