pg_query() - “无法设置与阻止模式的连接(错误号8)

时间:2017-03-26 17:30:06

标签: php database postgresql amazon-web-services amazon-redshift

我们的应用程序是使用COPY查询将CSV文件中的数据插入Redshift。它上传c。 c总共700 GB。 11000个文件。每个文件都映射到一个数据库表。我们在每个SELECT COUNT(*) FROM <table>之前和之后运行COPY进行日志记录和完整性检查。

经过一段时间(似乎有所不同),对pg_query()的调用会返回此E_NOTICE PHP错误:

pg_query() - "Cannot set connection to blocking mode (Error No. 8)

SELECT COUNT(*) FROM <table>查询返回此内容;我们的应用程序将所有PHP错误传播到异常。除了E_NOTICESELECT上的COPY之外,删除此传播会向我们提供此错误消息:

Failed to run query: server closed the connection unexpectedly
    This probably means the server terminated abnormally

COPY查询肯定不会实际插入文件。

一旦出现,每次尝试插入文件时都会发生此错误。它似乎没有自行解决。

我们最初在脚本开头打开了一个数据库连接(用pg_connect()打开),并将其重新用于所有后续SELECTCOPY s。当我们得到E_NOTICE时,我们尝试了 - 就像一个实验 - 为每个查询打开一个新的连接。这没有任何改变。

我们当前在PHP ini文件中的pgsql设置是:

pgsql.allow_persistent = Off
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0

可能导致此错误的原因以及如何解决?

更新 - 请参阅随附的屏幕。看来我们只有默认查询队列,'concurrency'设置为5,超时设置为0 MS?

enter image description here

另外:我们只在应用程序运行时连接这些数据库用户(带有'username_removed'的用户是我们的应用程序创建的唯一用户):

main=# select * from stv_sessions;
       starttime        | process |                     user_name                      |                      db_name
------------------------+---------+----------------------------------------------------+----------------------------------------------------
 2017-03-24 10:07:49.50 |   18263 | rdsdb                                              | dev
 2017-03-24 10:08:41.50 |   18692 | rdsdb                                              | dev
 2017-03-30 10:34:49.50 |   21197 | <username_removed>                              | main
 2017-03-24 10:09:39.50 |   18985 | rdsdb                                              | dev
 2017-03-30 10:36:40.50 |   21605 | root                                               | main
 2017-03-30 10:52:13.50 |   23516 | rdsdb                                              | dev
 2017-03-30 10:56:10.50 |   23886 | root                                               | main

2 个答案:

答案 0 :(得分:0)

您是否尝试将 pg_connect 更改为 pg_pconnect ?这将重用现有连接,并减少与数据库的连接,服务器将顺利运行。

我会说永远不会使用* 进行计数。您正在强制数据库为每个寄存器创建一个哈希并对其进行计数。使用一些独特的值。如果没有,请考虑创建一个序列并在“auto_increment”字段中使用它。 我看到你使用大文件,任何性能改进都将有助于你的工作

您还可以检查阻止模式配置。

我在网上搜索,可能适合你。 “从将pgsql.auto_reset_persistent = Off更改为On并重新启动Apache,这可以解决错误。”

我的最后建议是关于交易,如果您使用交易,您可以设置您的计数选择忽略锁定的行,这将使您的计数运行得更快。

https://www.postgresql.org/docs/9.5/static/explicit-locking.html#LOCKING-ROWS

答案 1 :(得分:0)

您的连接可能会超时。确保在连接选项中启用了Keepalive。

在连接字符串中设置keepalives=1应该发送keepalive数据包并防止连接超时。您也可以尝试设置keepalives_idle=60

默认情况下,来自操作系统的连接可能无法请求保持连接,因此在您更新相应的操作系统级别设置之前,这些设置似乎不起作用。

请查看类似问题TCP Keep-Alive PDO Connection Parameter以获取更多信息。