Вызов хранимой процедуры MySQL из сценария PHP - нет ошибки, но не выполняется?

  • ОБНОВЛЕНИЕ В КОНЦЕ

Я следую этому руководству по автоматическому обслуживанию разделов в MySQL, в котором подробно описывается общий метод удаления и добавления разделов таблиц mySQL на основе диапазонов дат.

Идея состоит в том, что вы можете автоматически отбрасывать старые данные таблицы через определенный промежуток времени и создавать новые разделы таблицы для текущих данных по мере необходимости.

Однако, поскольку мой сайт, скорее всего, будет размещен в "общем" пакете провайдера, кажется, что события mySQL будут для меня недоступны.

Итак, я перекрестно использую хранимые процедуры, описанные в первом уроке, с альтернативным методом их вызова с использованием метода, подробно описанного в этом ответе о переполнении стека, с некоторыми изменениями: Сценарий поддержки разделов для Mysql

На моем локальном тестовом компьютере я хочу запустить скрипт PHP как задание CRON от Webmin.

Когда я запускаю хранимые процедуры из Adminer (который имеет схожую функциональность с phpMyAdmin), используя тестовую базу данных mySQL, они выполняются как положено - разделы удаляются, и весь процесс занимает пару минут.

Однако, когда я запускаю свой модифицированный PHP-скрипт из Webmin в качестве задания CRON, кажется, ничего не происходит. Ошибок нет, но скрипт сразу возвращается с "ОК".

Точно так же, когда я запускаю скрипт из оболочки моего компьютера LAMP, он сразу же возвращается с "OK".

Это скрипт PHP:

#!/usr/bin/env php
<?php
$connection = mysqli_connect('localhost', 'my_username', 'my_password', 'employees');
$result = mysqli_query($connection, "CALL perform_partition_maintenance('employees', 'titles', 3, 216, 5)") or die('Query fail: ' . mysqli_error($connection));
if ($result)
  echo "OK";
else
  echo "FAIL";
mysqli_close($connection);

Буду очень признателен за любые предложения о том, где я могу пойти не так.


ОБНОВИТЬ

В соответствии с предложением Ника, я добавил много отладочных операторов. Я пошел немного другим путем, потому что это было немного легче сделать - много новых заявлений "в файл".

Но то, что я наблюдал, сбило меня с толку. Небольшой сегмент хранимой процедуры ниже:

OPEN cur1;
    read_loop: LOOP
      FETCH cur1 INTO current_partition_name;
      IF done THEN
         LEAVE read_loop;
      END IF;

      IF ! @first AND p_seconds_to_sleep > 0 THEN
        SELECT CONCAT('Sleeping for ', p_seconds_to_sleep, ' seconds');
        SELECT SLEEP(p_seconds_to_sleep);
      END IF;

      SELECT CONCAT('Dropping partition: ', current_partition_name);

      ...

      SET @first = FALSE;
    END LOOP;
  CLOSE cur1;

Все это взято, не изменено, из веб-учебника на странице Джеффа Монти, и работает безупречно в других контекстах (т. Е. В Adminer, из консоли sql - только не в сочетании с PHP-скриптом). Тем не менее, когда я закомментирую строку, которая говорит:

SELECT CONCAT('Dropping partition: ', current_partition_name);

Все работает просто отлично, но сценарий задыхается, когда я вставляю эту строку обратно. Я не могу понять этого. Особенно потому, что - при тестировании - я записываю "current_partition_name" в файл на диске для первых трех итераций цикла, и ссылка на строку в этой ситуации не вызывает никаких проблем. Это очень странно.

Этот другой (по-видимому, неразрешенный) вопрос переполнения стека звучит несколько похоже.

1 ответ

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

Это очень неудачно, потому что делает все упражнение излишним. Мне придется исследовать какое-то решение, включающее обычное удаление таблиц, со всеми связанными головными болями.


Отдельно я не приблизился к пониманию того, почему комментирование этой конкретной строки из хранимой процедуры Джеффа Монти было ключевым в том, чтобы позволить функции успешно работать при вызове из PHP. Я был бы соблазн объяснить это ошибкой интерпретатора (я использую mySQL 5.5.62 в моей тестовой среде), но, как упоминалось ранее, хранимая процедура выполняется без нареканий при запуске из Adminer.

Другие вопросы по тегам