Это признак того, что pg_send_query()
не может успешно переключить соединение обратно в режим блокировки. Глядя на исходный код в PHPs pgsql.c, вы можете найти:
/* {{{ proto bool pg_send_query(resource connection, string query)
Send asynchronous query */
PHP_FUNCTION(pg_send_query)
{
<... snipped function setup stuff ...>
if (PQ_SETNONBLOCKING(pgsql, 1)) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to nonblocking mode");
RETURN_FALSE;
}
<... snipped main function execution stuff ...>
if (PQ_SETNONBLOCKING(pgsql, 0)) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot set connection to blocking mode");
}
RETURN_TRUE;
}
Таким образом, ошибка возникает в конце функции после выполнения основной работы. Это соответствует вашему наблюдению, что ваши операторы INSERT выполняются.
Цель двух вызовов PQ_SETNONBLOCKING
состоит в том, чтобы перевести соединение в неблокирующий режим, чтобы разрешить асинхронное выполнение, и впоследствии вернуть его к поведению блокировки по умолчанию. Из документации PQsetnonblocking : (PQ_SETNONBLOCKING - просто псевдоним, определенный для этой функции):
Устанавливает статус неблокирования
подключение.
int PQsetnonblocking(PGconn *conn, int arg);
Устанавливает состояние соединения как неблокирующее, если arg равно 1,
или блокировка, если аргумент равен 0. Возвращает 0, если
ОК, -1, если ошибка.
В неблокирующем состоянии звонит
PQsendQuery, PQputline, PQputnbytes,
и PQendcopy не будет блокировать, но
вместо этого верните ошибку, если им нужно
быть вызванным снова.
Обратите внимание, что PQexec не соблюдает
неблокирующий режим; если это называется, это
в любом случае будет действовать блокирующим образом.
Если посмотреть дальше на источник PQsetnonblocking (в PostgeSQLs fe-exec.c), есть две возможные причины сбоя вызова:
/* PQsetnonblocking:
* sets the PGconn's database connection non-blocking if the arg is TRUE
* or makes it non-blocking if the arg is FALSE, this will not protect
* you from PQexec(), you'll only be safe when using the non-blocking API.
* Needs to be called only on a connected database connection.
*/
int
PQsetnonblocking(PGconn *conn, int arg)
{
bool barg;
if (!conn || conn->status == CONNECTION_BAD)
return -1;
barg = (arg ? TRUE : FALSE);
/* early out if the socket is already in the state requested */
if (barg == conn->nonblocking)
return 0;
/*
* to guarantee constancy for flushing/query/result-polling behavior we
* need to flush the send queue at this point in order to guarantee proper
* behavior. this is ok because either they are making a transition _from_
* or _to_ blocking mode, either way we can block them.
*/
/* if we are going from blocking to non-blocking flush here */
if (pqFlush(conn))
return -1;
conn->nonblocking = barg;
return 0;
}
Таким образом, либо соединение каким-то образом потеряно, либо pqFlush не завершился успешно, что указывает на наличие остатка в буфере вывода соединения.
Первый случай будет безвредным, поскольку ваш скрипт наверняка заметит потерянное соединение для последующих вызовов и отреагирует на это (или потерпит неудачу более заметно).
Это оставляет второй случай, который будет означать, что у вас есть соединение в состоянии по умолчанию, не блокирующем. Я не знаю, может ли это повлиять на последующие вызовы, которые будут использовать это соединение повторно. Если вы хотите избежать опасности, в этом случае вы бы закрыли соединение и использовали новое / другое.