【问题标题】:Strange behaviour of PHP script performing SELECT query执行 SELECT 查询的 PHP 脚本的奇怪行为
【发布时间】:2011-10-18 22:39:07
【问题描述】:

我有一个运行良好的 PHP 脚本很长时间了。它基本上对远程数据库执行查询;使用 postgreSQL API:

SELECT id,command FROM tablet_sync WHERE id>$certainNumber

Id 字段为 int4 类型;并且 command 是 text 类型。

正如我所说,它已经运行了很长时间。但最近,我发现有时 command 字段可能有点大(但不是特别大);大约 10000 个字符或更多。

好吧,当该查询找到其字段 command 大于一定数量的字符(大约 9000)的行时;它不起作用。

  • Apache 调用永无止境。
  • 未发现错误消息(PHP/Apache 日志文件、客户端和服务器)。

我应该说,如果这个查询是在 PostgreSQL 客户端执行的,比如说 pgAdmin,它可以完美地工作(当然,10000 字节的数据并不是大量的数据!)。 但是如果我从我的 PHP 脚本中创建它就行不通了。

我给你所有其他可能有助于解决问题的信息:

  • 服务器和客户端具有相同的 Apache amd PHP 版本:2.2 和 5.3.0;分别。
  • 客户端和服务器不在同一台机器上
  • 如果我在 PHP 脚本文件中执行查询时限制要恢复的数据量; 有效!。 (例如:SELECT id,(CAST command AS varchar(9000) FROM tablet_sync WHERE id>$certainNumber)

*更新* 我可以推测 PostgreSQL 远程数据库服务器正在抛出这些错误:

  • LOG:无法从客户端接收数据:连接超时
  • 日志:客户端连接出现意外 EOF

尽管有这些错误,PHP 调用仍然没有结束...

*04/08 更新*

感谢您的回答@regilero。我做了一些测试:

  1. 更改超时值没有任何效果。

  2. 感谢 SHOW AL 命令,我发现一些配置字段是 客户端和服务器端不同:所有语言环境(lc_collat​​e, lc_message 等;); 在服务器端设置为 UTF-8,同时在 客户端设置为 English_United States.1252。 ma​​x_fsm_pages 设置为 153600;小于客户端。我发现客户端和服务器端的 postgreSQL 版本也不同:分别为 8.3.1 和 8.3.9。 shared_buffer 值也设置不同:32MB 和 24MB;客户端和服务器,分别。未发现更多相关差异。

  3. 我使用PHP API connector to PostgreSQL,从现在开始一直运行良好。 PHP 错误日志文件没有显示任何内容。

【问题讨论】:

  • 如何执行查询? “PostgreSQL API”是指 pg_* 函数吗?
  • 你也检查过 MySQL 错误日志吗?远射……
  • 我的意思是 Postgres,freudian slip,只是在回答一个 MySQL 问题。
  • @bertzzie;是的,我正在使用 pg_* 函数,从现在开始它们一直运行良好。我还检查了 PostgreSQL lof 文件;并且没有发现错误。它仅在我手动停止呼叫时显示连接错误(我单击 Firefox 上的停止按钮)。我还应该告诉被调用的 PHP 脚本位于客户端计算机(localhost)中;但数据库位于远程服务器中。
  • 您可以尝试使用更新的 PHP 版本(可能是 5.3.8)吗?

标签: php apache postgresql select


【解决方案1】:

好像是超时问题。

在 postgresql 会话方面,您可以尝试在查询之前添加这些命令:

set statement_timeout to 10000;

这是一个以毫秒为单位的值,您也可以尝试将其设置为 0(无限)。

如果它来自会话中的 tcp 问题,您可以调整这 3 个设置:

set tcp_keepalives_count to 10;
set tcp_keepalives_idle to 2;
set tcp_keepalives_interval to 1;

或其他值(这里只是随机尝试)。这里的意思是,每2s尝试一次'tcp keepalive ping',如果失败则每1s重试一次,并允许在死前重试10次(0表示系统默认)。

现在问题也可能出在客户端,您使用的是哪个 postgresql 连接器?此连接使用的可选设置是什么(连接字符串,默认配置值,...)。 “SHOW ALL;”将列出所有设置,您应该尝试从 PHP 客户端执行此查询并将结果存储在某处,然后检查此列表中的每个设置,并使用来自 pgadmin 的相同查询检查差异。

【讨论】:

  • 我编辑了我的问题并附上了一些测试。谢谢你的回答!
  • 我不明白你编辑中的#2,show all 不能显示客户端和服务器的差异,只是你从不同的客户端执行 show all,不是吗(pgadmin 是一个客户端,作为php API)?但是您是否请求 2 个不同的服务器? shared_buffer 是服务器设置,您不能从不同的客户端获取该配置的 2 个值。
  • Ups,对不起,我没有告诉系统有两台服务器(一台是客户端和服务器在同一台机器上,还有另一台远程服务器)。原因是有时客户端必须在没有 Internet 连接的情况下工作;因此它将信息存储在本地数据库中;然后尝试同步到远程服务器。所以..是的......我从同一个客户端(pgAdmin)到不同的服务器:/。所以你告诉我从 pgAdmin 客户端和 PHP API 客户端到同一个远程服务器执行“SHOW ALL”命令;并检查差异?谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-06
  • 2015-06-02
相关资源
最近更新 更多