Вызов хранимой процедуры MySQL из сценария PHP - нет ошибки, но не выполняется? - PullRequest
0 голосов
/ 08 января 2019
  • ОБНОВЛЕНИЕ В КОНЦЕ

Я следую этому Автоматическому обслуживанию разделов в 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);

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


UPDATE

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

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

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 Ответ

0 голосов
/ 30 января 2019

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

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


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

...