1

使用 PHP/Joomla,我正在尝试将数据库备份导出到 CSV/sql 文件中进行下载。有些表有大量的记录。当我开始导出时,它给出以下错误: 致命错误:超过 30 秒的最大执行时间

注意:我不想使用 'max_execution_time' 或 'set_time_limit()' 或任何 php.ini 设置。因为我将在不同的客户端服务器上使用此脚本,并且我不会告诉每个客户端更改设置。我需要 PHP/Joomla 脚本,而不是任何扩展。

请帮我。

4

4 回答 4

2

鉴于您对我之前的回答的评论,我建议您考虑创建一个 Joomla!CLI(查看/cli您的 Joomla 2.5+ 安装目录)。

对于我们为内部使用而开发的 Easystaging 扩展的 Pro 版本,我们已经做了类似的事情,以管理具有特定内容批准流程的客户网站。内部版本必须处理我们更大的客户需求。

实际上,我们创建了继承自JApplicationCliCRON 或由我们的组件用户界面启动的类。例如

class EasyStaging_PlanRunner extends JApplicationCli
{
    /**
     * Entry point for the plan funner (yes it's more fun)
     *
     * @return  void
     *
     * @since   2.5
     */
    public function doExecute()
    {
    }
}

如果它是由用户从 Joomla 中启动的,我们使用实用程序方法来确保系统正确地分叉它:

/**
 * Runs the script in the background by scheduling it with the `at` daemon and returns the result
 *
 * @param   string  $pathToScript  A path to the script to run e.g. "/path/to/my/cli/app.php"
 *
 * @return  int
 */
private function _runScriptInBackground($pathToScript)
{
    $cmdPath = "/usr/bin/php -q $pathToScript";

    // We need '2>&1' so we have something to pass back
    $cmd     = 'echo "' . $cmdPath . '" | at now 2>&1';
    $result = shell_exec($cmd);

    return $result;
}

由于这是作为命令行脚本有效运行的,因此许多限制要宽松得多,但它们仍然不会让您绕过非常大的桌子。(我们的一些客户拥有数千篇文章或更差的 K2 内容项)。

为了解决这个问题,我们编写了一个从我们doExecute()的主调度循环调用的导出方法,以合理的批次检索和导出表行。对我们来说,合理是由远程数据库max_allowed_packet值决定的,我们创建了一个 SQL 文件,其中包含符合此限制的语句,并为各种开销留出了少量余量。您可能没有这些问题,但即便如此,您也应该将 SQL 分解为合理大小的insert语句。

一旦计划完成运行,我们就会压缩所有文件并将它们发送到存档。

于 2013-06-28T02:32:41.377 回答
1

由于某些表的数据量很大,因此需要相当长的时间。结果,连接将超时并且导出将失败。

更好的方法是使用命令行将数据转储为 SQL。您可能想查看 mysqldump 命令。

您还可以从这样的 PHP 脚本调用 mysqldump 命令 -

<?php
# Database Settings
$tmpDir = "/home/<username>/tmp/"; // Temp location the user has access to
$user = "<username>_******"; // MySQL Username for the database
$password = "*******"; // MySQL Password
$dbName = "<username>_******"; // Database name, usually in the pattern: <username>_<dbname>
$dbHost = "localhost"; // Mysql server hostname, usually localhost

$sqlFile = $tmpDir . $dbName . date('Y_m_d') . ".sql"; // The dumped SQL File
$attachment = $tmpDir . $dbName . "_" . date('Y_m_d') . ".tgz"; // TGZed file

$creatBackup = "mysqldump -h '" . $dbHost .  "' -u '" . $user . "' --password='" . $password . "' '" . $dbName . "' > '" . $sqlFile . "'"; // Full command
$createZip = "tar cvzf $attachment $sqlFile"; // Full Command

// Execute 'em
system($creatBackup);
system($createZip);

这应该创建一个 SQL 转储并从中创建一个存档。

上面的代码是我构建的一个工具的一部分,用于通过电子邮件向我发送数据库的每日备份。您可以在 Github 上查看并修改它以适合您的目的 - https://github.com/masnun/mysql-backup-to-email

于 2013-06-26T18:00:26.207 回答
0

也许您甚至必须将每个表的记录拆分到不同的文件中。

于 2013-06-26T17:57:24.227 回答
0

我建议您不要重新发明轮子,而是使用Akeeba Backup,因为它可以让您创建整个站点的自动备份,或者只是文件或特定目录,或者只是数据库或特定表或任何您能想到的组合的。

它也是免费的。

它年复一年地获奖,在Joomla 扩展目录中获得高度评价,我们在所有网站和客户网站上都使用它。

如果您获得Pro 版本,您甚至可以备份到 Amazon 的 S3 或其他有用的系统。

除了我喜欢使用他们的产品外,我与 Akeeba 没有任何关系——他们让我晚上睡觉。

于 2013-06-27T10:31:31.340 回答