Странное поведение PHP-скрипта, выполняющего запрос SELECT - PullRequest
2 голосов
/ 03 августа 2011

У меня есть PHP-скрипт, который работал хорошо в течение долгого времени.Он в основном выполняет запрос к удаленной базе данных;используя postgreSQL API:

SELECT id,command FROM tablet_sync WHERE id>$certainNumber

Поле Id имеет тип int4 ;и команда имеет тип text .

Как я уже говорил, она хорошо работает в течение долгого времени.Но недавно я обнаружил, что иногда поле command может быть немного (но не очень) большим;около 10000 символов или более.

Хорошо, когда этот запрос находит строку с ее полем команда больше определенного количества символов (около 9000);он не работает.

  • Вызов Apache никогда не заканчивается.
  • Не обнаружено сообщений об ошибках (файлы журнала PHP / Apache, клиент и сервер).

Я должен сказать, что если этот запрос выполняется в клиенте PostgreSQL, скажем, pgAdmin, он работает отлично (конечно, 10000 байт данных - это не большой объем данных!).Но это не сработает, если я сделаю это из своего PHP-скрипта.

Я дам вам всю другую информацию, которая может быть полезна для решения проблемы:

  • Сервер и клиент имеют одинаковый Apacheверсии PHP amd: 2.2 и 5.3.0;соответственно.
  • Клиент и сервер НЕ расположены на одном компьютере
  • Если я ограничу объем данных, которые необходимо восстановить при выполнении запроса в файле сценария PHP; это работает! .(например: SELECT id, ( команда CAST AS varchar (9000) FROM tablet_sync WHERE id> $ sureNumber)

* Обновлено * Можно предположить, что удаленный сервер баз данных PostgreSQL выдает следующие ошибки:

  • LOG: не удалось получить данные от клиента: истекло время ожидания соединения
  • LOG: неожиданное EOF при клиентском соединении

Несмотря на эти ошибки, вызов PHP по-прежнему не заканчивается ...

* 04/08 Обновлено *

Спасибо за ваш ответ @regilero. Я провел несколько тестов:

  1. Изменение значения времени ожидания не сработало.

  2. Я обнаружил, благодаря команде SHOW AL, что некоторые поля конфигурации различаются на стороне клиента и сервера: все локали (lc_collate, lc_message и т. Д .;); установлены в UTF-8 на стороне сервера,в то же время на стороне клиента установлено значение English_United States.1252. max_fsm_pages установлено на 153600; меньше, чем на стороне клиента.и что версия postgreSQL также отличается на стороне клиента и сервера: 8.3.1 и 8.3.9, соответственно. shared_buffer значение также установлено разным: 32 МБ и 24 МБ;клиент и сервер соответственно.Никаких более значимых различий обнаружено не было.

  3. Я использую PHP API-коннектор для PostgreSQL и с тех пор работает хорошо.Файл журнала ошибок PHP ничего не показывает.

1 Ответ

1 голос
/ 03 августа 2011

Кажется, это проблема тайм-аута.

На стороне сеанса 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;

или другие значения (здесь простослучайная попытка).В данном случае это означает, что вы должны пытаться выполнить tcp keepalive ping каждые 2 с, повторять каждые 1 с в случае неудачи и разрешать 10 повторных попыток перед смертью (0 означает системное значение по умолчанию).

Теперь проблема также может быть на клиентесторона, какой разъем postgresql вы используете?Какие опциональные настройки используются с этим соединением (строка соединения, значения по умолчанию conf, ...).«SHOW ALL;» перечислит все настройки, вы должны попытаться выполнить этот запрос из вашего PHP-клиента и сохранить результат где-нибудь, затем проверить все настройки в этом списке и проверить разницу с тем же запросом от pgadmin.

...