为什么postgresql会说fatal:对不起,当我还没有达到最大连接数的时候,已经有太多的客户端了?

5tmbdcev  于 2021-07-13  发布在  Spark
关注(0)|答案(2)|浏览(591)

我正在使用postgresql11.2的一个安装,它会定期在系统日志中抱怨

FATAL:  sorry, too many clients already

尽管没有接近其配置的连接限制。此查询:

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

告诉我数据库配置为最多100个连接。我从未见过有超过45个连接通过这个查询进入数据库,甚至在一个正在运行的程序收到一个数据库错误之前的一刻,即postgres日志中有太多的客户机受到上述消息的支持。
绝对所有我能找到的问题在互联网上这表明,错误意味着你已经超过了预期 max_connections 但是数据库本身告诉我我不是。
值得一提的是,pyspark是唯一触发此错误的数据库客户机,并且只有在它从dataframes写入表时才会触发此错误。使用 psycopg2 (即主客户机)从不触发它(即使是以相同的方式从Dataframe写入表时也不触发),像pgadmin这样的管理工具也从不触发它。如果我没有直接看到数据库日志中的错误,我会认为spark在错误方面对我撒谎。大多数情况下,如果我使用这样的查询:

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

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

oprakyz7

oprakyz71#

这是由spark如何使用jdbc读/写数据造成的。spark试图打开多个到数据库的并发连接,以便并行地读/写多个数据分区。
我在文档中找不到它,但我认为默认情况下,连接数等于要写入db表的datafame中的分区数。这就解释了你所注意到的间歇性。
但是,您可以通过设置 numPartitions 选项:
表读写中可用于并行的最大分区数。这也决定了并发jdbc连接的最大数量。如果要写入的分区数超过此限制,则通过调用 coalesce(numPartitions) 在写作之前。
例子:

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

# ...
k5hmc34c

k5hmc34c2#

三种可能性:
这些联系是非常短暂的,你看的时候它们已经消失了。
你对那个数据库有一个较低的连接限制。
您对数据库用户的连接限制较低。
但是选项2和3会导致不同的错误消息,所以它一定是短期连接。
不管是什么,解决问题的答案都是配置良好的连接池。

相关问题