【问题标题】:CALLing a mySQL Stored Procedure from a PHP script - no error but not executing?从 PHP 脚本调用 mySQL 存储过程 - 没有错误但没有执行?
【发布时间】:2019-01-08 11:27:59
【问题描述】:
  • 最后更新

我正在关注这个Automatic Partition Maintenance in MySQL 教程,其中详细介绍了基于日期范围删除和添加 mySQL 表分区的通用方法。

这个想法是您可以在一定时间后自动抛弃旧表数据,并根据需要为当前数据创建新的表分区。

但是,由于我的网站可能托管在“共享”提供程序包上,因此我似乎无法使用 mySQL 事件。

因此,我正在对第一个教程中描述的存储过程进行交叉施肥,并使用另一种方法来调用它们,使用此 Stack Overflow 答案中详述的方法,并进行一些修改:Partition maintainance script for Mysql

在我的本地测试机器上,我想将 PHP 脚本作为 CRON 作业从 Webmin 运行。

当我使用mySQL test databaseAdminer(具有与phpMyAdmin 类似的功能)运行存储过程时,它们按预期执行 - 分区被删除,整个过程需要几分钟才能完成。

但是,当我从 Webmin 将修改后的 PHP 脚本作为 CRON 作业运行时,似乎什么也没发生。没有错误,但脚本会立即返回“OK”。

同样,当我从 LAMP 机器的 shell 运行脚本时,它会立即返回“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);

如果您对我可能出错的地方提出任何建议,我将不胜感激。


更新

根据 Nick 的建议,我添加了很多调试语句。我走了一条稍微不同的路线,因为它更容易做 - 很多新的“into 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;

这一切都是从 Geoff Montee 页面上的 web 教程中获取的,未经修改,并且在其他环境中完美地工作(即,在 Adminer 中,从 sql 控制台 - 只是没有与 PHP 脚本结合使用)。 但是,当我注释掉以下内容时:

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

一切正常,但是当我把那行放回原处时,脚本卡住了。我无法理解这一点。特别是因为 - 在测试中 - 我正在将“current_partition_name”写到磁盘上的文件中,用于循环的前三个迭代,并且在这种情况下引用字符串不会导致任何问题。这很奇怪。

This other (apparently unresolved) stackoverflow question 听起来有些相似。

【问题讨论】:

  • 您确定 PHP 用户有适当的权限来执行程序中的操作吗?
  • 嘿尼克,感谢你的建议——这就是我一直在烦恼的想法。我是 Linux 新手,但我使用过“exec('whoami'),它返回“root”
  • 这不是你在 Linux 上的身份,而是在 MySQL 中my_username 被授予的权限在这里很重要。
  • 再次感谢:我在这里传入的用户名也是“root”(至少,在我的本地测试机器上)
  • 听起来您可能需要将一些调试SELECT 语句放入过程中并将其结果输出到您的脚本中。请注意,您需要使用mysqli_real_querymysqli_multi_query 来获取返回的数据(请参阅php.net/manual/en/mysqli.quickstart.stored-procedures.php

标签: php mysql stored-procedures adminer


【解决方案1】:

后来,我意识到当表具有外键时分区不可用。当我第一次探索分区作为一种选择时,我不确定我是如何错过这个基本细节的。

这很不幸,因为它使整个练习变得多余。我将不得不研究某种涉及常规表删除的解决方案,以及所有相关的麻烦。


另外,我不太理解为什么从 Geoff Montee 的存储过程中注释掉该特定行对于允许从 PHP 调用该函数时成功运行至关重要。我很想把它归结为解释器错误(我在我的测试环境中运行 mySQL 5.5.62),但如前所述,存储过程在从管理员启动时执行完美。

【讨论】:

    猜你喜欢
    • 2020-10-18
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 2013-05-08
    • 2022-01-13
    • 2018-01-24
    • 2013-08-08
    • 2014-06-14
    相关资源
    最近更新 更多