pg_query () — «Невозможно установить соединение в режим блокировки (ошибка № 8)

Наше приложение вставляет данные из файлов CSV в Redshift с помощью COPY запрос. Это загружает c. 700 ГБ всего по c. 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_NOTICE выше на обоих SELECT и COPY:

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

COPY запрос определенно не вставляет файлы.

После появления эта ошибка возникает при каждой попытке вставить файл. Кажется, это не решает себя.

Первоначально у нас было открыто одно соединение с базой данных pg_connect()) в начале сценария и повторно использовать его для всех последующих SELECTс и COPYs. Когда мы получили E_NOTICE Выше мы попытались — просто в качестве эксперимента — открыть новое соединение для каждого запроса. Это ничего не изменило.

наши текущие настройки pgsql в PHP-файле ini:

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

Что может быть причиной этой ошибки и как ее можно устранить?

Обновить — Смотрите прикрепленный экран. Кажется, у нас есть только очередь запросов по умолчанию с «параллелизмом», установленным на 5, и таймаутом, установленным на 0 мс?

введите описание изображения здесь

Кроме того: у нас есть только эти пользователи БД, подключенные во время работы приложения (тот, у кого 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

5

Решение

Вы пытались изменить 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

0

Другие решения

Возможно, ваше соединение истекло. Убедитесь, что вы включили keepalive в настройках подключения.

настройка keepalives=1 в вашей строке соединения следует отправлять пакеты keepalive и предотвращать тайм-аут соединения. Вы также можете попробовать установить keepalives_idle=60,

По умолчанию соединения из вашей ОС могут не иметь возможности запрашивать сообщения поддержки активности, поэтому эти настройки будут работать не до тех пор, пока вы не обновите соответствующие настройки уровня ОС.

Взгляните на похожий вопрос Параметр соединения TCP Keep-Alive PDO для дополнительной информации.

0

По вопросам рекламы [email protected]