为什么 PostgreSQL 会说 FATAL: sorry, too many clients already while I 远未达到最大连接数?
Why does PostgreSQL say FATAL: sorry, too many clients already when I am nowhere close to the maximum connections?
我正在安装 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%。我如何找出导致此错误的原因?
三种可能:
连接非常短暂,您查看时它们已经消失了。
您对该数据库的连接限制较低。
您对数据库用户的连接限制较低。
但是选项 2 和 3 会导致不同的错误消息,因此它一定是短期连接。
无论是什么,您的问题的答案将是一个配置良好的连接池。
这是由 Spark reads/writes 数据使用 JDBC 造成的。 Spark 尝试打开多个与数据库的并发连接,以便 read/write 多个并行数据分区。
我在文档中找不到它,但我认为默认情况下连接数等于要写入 db 的数据名中的分区数 table。这解释了您注意到的间歇性。
但是,您可以通过设置 numPartitions
选项来控制这个数字:
The maximum number of partitions that can be used for parallelism in
table reading and writing. This also determines the maximum number of
concurrent JDBC connections. If the number of partitions to write
exceeds this limit, we decrease it to this limit by calling
coalesce(numPartitions)
before writing.
示例:
spark.read.format("jdbc") \
.option("numPartitions", "20") \
# ...
我正在安装 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%。我如何找出导致此错误的原因?
三种可能:
连接非常短暂,您查看时它们已经消失了。
您对该数据库的连接限制较低。
您对数据库用户的连接限制较低。
但是选项 2 和 3 会导致不同的错误消息,因此它一定是短期连接。
无论是什么,您的问题的答案将是一个配置良好的连接池。
这是由 Spark reads/writes 数据使用 JDBC 造成的。 Spark 尝试打开多个与数据库的并发连接,以便 read/write 多个并行数据分区。
我在文档中找不到它,但我认为默认情况下连接数等于要写入 db 的数据名中的分区数 table。这解释了您注意到的间歇性。
但是,您可以通过设置 numPartitions
选项来控制这个数字:
The maximum number of partitions that can be used for parallelism in table reading and writing. This also determines the maximum number of concurrent JDBC connections. If the number of partitions to write exceeds this limit, we decrease it to this limit by calling
coalesce(numPartitions)
before writing.
示例:
spark.read.format("jdbc") \
.option("numPartitions", "20") \
# ...