Ошибка Apache Apache при выполнении ЗАП. ПРОЦЕДУРЫ
Проблема
Когда я выполняю следующий код (я вызываю хранимую процедуру с параметрами 5 IN и 1 OUT)
$conn->query("SET @res = ''");
$mysqli=$conn;
if (!($stmt = $mysqli->prepare("CALL retrieve_matches(5,3, 16, 2, false, @res)"))) {
echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
if (!$stmt->execute()) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}
do {
if ($res = $stmt->get_result()) { //Apache crash on this call
printf("---\n");
var_dump(mysqli_fetch_all($res));
mysqli_free_result($res);
} else {
if ($stmt->errno) {
echo "Store failed: (" . $stmt->errno . ") " . $stmt->error;
}
}
} while ($stmt->more_results() && $stmt->next_result());
Apache сбой с ошибкой:
AH00428: Родитель: дочерний процесс 9628 вышел со статусом 255 - Перезапуск.
Что я пробовал
- Этот код работает нормально и корректно возвращает результаты:
$conn->query("SET @res = ''");
$res=$conn->query("CALL retrieve_matches(5,3, 16, 2, false, @res)");
var_dump($res->fetch_assoc());
ПРИМЕЧАНИЕ. Тот же код выше, что делает сбой Apache, работает корректно, если я просто изменяю номер во входе хранимой процедуры, например:
if (!($stmt = $mysqli->prepare("CALL retrieve_matches(5,6, 16, 2, false, @res)"))) {
- Исправлено из Workbench MySQl, и оба вызова работают нормально.
- Я использую WAMP 64b на WIN7 Enterprise 64b, я пробовал с WAMP 32b, но получил такую же проблему.
- Я проверил событие Windows и обнаружил, что сбой httpd.exe вызван php5ts.dll
- Если вы ищете "httpd.exe php5ts.dll" в google, вы можете найти много людей, занимающихся этой проблемой. Но я не нашел решение для WAMP...
- Пробовал с AMPPS, точно такую же проблему
Журнал ошибок PHP
[10-Jul-2015 15:30:03 UTC] PHP Warning: PHP Startup: Unable to load dynamic library 'C:/Program Files/wamp/bin/php/php5.5.12/ext/php_ldap.dll' - Impossibile trovare il modulo specificato.
in Unknown on line 0
[10-Jul-2015 15:30:04 UTC] PHP Warning: PHP Startup: Unable to load dynamic library 'C:/Program Files/wamp/bin/php/php5.5.12/ext/php_intl.dll' - Impossibile trovare il modulo specificato.
Журнал ошибок APACHE:
[Tue Jul 14 15:02:13.038276 2015] [mpm_winnt:notice] [pid 7044:tid 404] AH00428: Parent: child process 9448 exited with status 255 -- Restarting.
[Tue Jul 14 15:02:13.324305 2015] [mpm_winnt:notice] [pid 7044:tid 404] AH00455: Apache/2.4.9 (Win32) PHP/5.5.12 configured -- resuming normal operations
[Tue Jul 14 15:02:13.329306 2015] [mpm_winnt:notice] [pid 7044:tid 404] AH00456: Apache Lounge VC11 Server built: Mar 16 2014 12:13:13
[Tue Jul 14 15:02:13.329306 2015] [core:notice] [pid 7044:tid 404] AH00094: Command line: 'C:\\Program Files\\wamp\\bin\\apache\\apache2.4.9\\bin\\httpd.exe -d C:/Program Files/wamp/bin/apache/apache2.4.9'
[Tue Jul 14 15:02:13.352308 2015] [mpm_winnt:notice] [pid 7044:tid 404] AH00418: Parent: Created child process 3140
[Tue Jul 14 15:02:14.528388 2015] [mpm_winnt:notice] [pid 3140:tid 332] AH00354: Child: Starting 64 worker threads.
Я действительно потерялся здесь, где я должен искать проблему?
Большое спасибо за вашу помощь.
ИЗМЕНИТЬ
Я понял, что хранимая процедура "retrieve_matches" вызывает другую хранимую процедуру в функции измененного значения. Я отлаживал хранимую процедуру "retrieve_standalone", которая является причиной сбоя Apache. Эта процедура выполняет select/insert, я проверил, и вставка выполнена правильно.
НО внутри "retrieve_standalone" я использую курсор странным образом:
declare bNoMoreRows bool default false;
declare tmp_cursor cursor for
select comp_id from to_match; -- to_match is a temporary table
declare continue handler for not found set bNoMoreRows := true;
если я не открываю курсор
open tmp_cursor;
все работает нормально!! Поэтому, я думаю, я нашел проблему сейчас: как я могу ее решить?
Ответы
Ответ 1
По-видимому, есть немного байка, проходящего - то есть scaricabarile - между ребятами PHP и ребятами из MySQLi.
Что-то происходит, так это то, что MySQLi реагирует "ненадлежащим образом" и возвращает неожиданное значение (я бы поставил небольшую сумму на него как NULL) на PHP, который был должным образом выпущен. Это поведение задокументировано, а вердикт от PHPland: "Не ошибка [PHP]". На их стороне, ребята MySQLi утверждают, что это PHP, который неправильно проверяет возвращенный результат. И эти "неправильные" результаты в любом случае зависели от вашего запроса.
Итак, я выхожу на конечность и полагаю, что ваша проблема связана с "трудностями общения", поэтому проблема возникает: "Ваш запрос заставляет MySQLi сбросить/снова подключиться". Почему это так? По-видимому (некоторые) хранимые процедуры требуют mysqli_multi_query
, чтобы правильно вести себя.
И mysqli_multi_query
не совместим с mysqli_prepare
.
Поэтому я предлагаю попробовать без подготовки запроса и запустить его с помощью mysqli_multi_query
.
$conn->query("SET @res = ''");
$conn->multi_query("CALL retrieve_matches(5,3, 16, 2, false, @res)");
do {
if ($result = $conn->store_result()) {
while ($row = $result->fetch_row()) {
var_dump($row);
}
$result->free();
}
} while ($conn->more_results() && $conn->next_result());
С помощью этого кода ваш тестовый пример получит меня, как и ожидалось,
array(1) {
[0] =>
string(4) "test"
}
Ответ 2
Если php5ts.dll или любая другая часть Apache падает с повторяющимся воспроизведением каждый раз, когда вы запускаете короткий script, скорее всего, вы попали в ошибку в php. Особенно, если вы запускаете обновленный apache с недавней php-версией, загруженной с php.net, у вас есть очень хорошие шансы получить поддержку от команды PHP. Итак, прочитайте https://bugs.php.net/how-to-report.php, посмотрите, можете ли вы воспроизвести сбой при запуске script без apache (в отдельном script на cli, используя php.exe) и создать обратную трассировку, которую вы затем можете отправить как ошибку.
Ошибки, подобные этим, иногда могут обрабатываться, но редко фиксируются из контекста вашего script. PHP никогда не должен разбивать веб-сервер, и если он делает это воспроизводимо, ошибка должна быть подана, поэтому ее можно исправить.
Ответ 3
Я узнаю, как воспроизвести его, я считаю, что ошибка php/apache
PHP-код:
if (!($stmt = $mysqli->prepare("CALL test()"))) {
echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
if (!$stmt->execute()) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}
do {
if ($res = $stmt->get_result()) {
printf("---\n");
//var_dump(mysqli_fetch_all($res));
var_dump($res->fetch_assoc());
mysqli_free_result($res);
} else {
if ($stmt->errno) {
echo "Store failed: (" . $stmt->errno . ") " . $stmt->error;
}
}
} while ($stmt->more_results() && $stmt->next_result());
Код процедуры хранения:
CREATE DEFINER=`root`@`localhost` PROCEDURE `test`()
BEGIN
declare test_var varchar(100) default "ciao";
declare bNoMoreRows bool default false;
declare test_cursor cursor for
select id from tmp_folder;
declare continue handler for not found set bNoMoreRows := true;
create temporary table tmp_folder select "test" as id;
open test_cursor;
fetch test_cursor into test_var;
close test_cursor;
select test_var;
drop temporary table if exists tmp_folder;
END
Ошибка открыта:
Apache: https://bz.apache.org/bugzilla/show_bug.cgi?id=58136
Php: https://bugs.php.net/bug.php?id=70073
Ответ 4
Я думаю, вы путаете $conn
и $stmt
. Вот что у меня есть. (Он собирает результат в $out.)
if ($conn->multi_query($call)) {
$raa = array();
do {
/* store first result set */
if ($result = $conn->use_result()) {
while ($row = $result->fetch_row()) {
$raa[] = $row;
printf("+\n");
}
$result->close();
}
$out[] = $raa;
/* print divider */
if ($conn->more_results()) {
printf("-----------------\n");
}
} while ($conn->next_result());
}
else
echo "err";
Ответ 5
Попробуйте изменить стек сервера. Либо обновите WAMP, либо выполните свой код в другой среде. Этот вопрос предполагает наличие ошибки в WAMP, которая заставит Apache выбросить ошибку 255
php → mysql_connect → дочерний процесс завершен со статусом 255 - Перезапуск