来自php脚本的mysqldump的内存要求

时间:2013-12-18 18:23:25

标签: php mysqldump

我有以下脚本,非常适合数据库备份。但是我会遇到非常大的数据库的内存问题吗?

//Set large amount of memory to prevent fatal errors and don't let it timeout
ini_set('memory_limit', '1024M');
set_time_limit(0);

$database = escapeshellarg($this->db->database);
$db_hostname = escapeshellarg($this->db->hostname);
$db_username= escapeshellarg($this->db->username);
$db_password = escapeshellarg($this->db->password);

$backup_command = "/usr/local/mysql/bin/mysqldump -h $db_hostname -u $db_username -p$db_password $database";
$dump_output = shell_exec($backup_command);

force_download('database.sql', $dump_output);

2 个答案:

答案 0 :(得分:2)

我不会使用shell_exec()。使用passthru()代替,它不需要额外的内存,因为它将mysqldump的输出不变为PHP的输出:

// set appropriate headers for download ...  
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="download.sql"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');

// then directly output using passthru()
passthru('/usr/local/mysql/bin/mysqldump -h $db_hostname -u $db_username -p$db_password $database"');

但是,此解决方案无法设置Content-Length标头,因为PHP的输出大小未知。在大多数情况下它应该没问题,你可以忍受。 (phpmyadmin做同样的事)


此处不需要使用passthru()set_time_limit()(除非您的服务器运行Windows(!))。来自documenation

  

注意:set_time_limit()函数和配置指令max_execution_time仅影响脚本本身的执行时间。在确定脚本运行的最长时间时,不会包括在执行脚本之外发生的任何活动,例如使用system()的系统调用,流操作,数据库查询等。在测量时间真实的Windows上,情况并非如此。

答案 1 :(得分:1)

基于评论/讨论的最终解决方案:

function do_mysqldump_backup()
{
    //Set large amount of memory to prevent fatal errors and don't let it timeout

    ini_set('memory_limit', '1024M');
    set_time_limit(0);

    $mysqldump_paths = array('C:\Program Files\PHP Point of Sale Stack\mysql\bin\mysqldump.exe',  //Windows
    '/Applications/phppos/mysql/bin/mysqldump', //Mac
    '/opt/phppos/mysql/bin/mysqldump',  //Linux
    '/usr/bin/mysqldump', //Linux
    '/usr/local/mysql/bin/mysqldump', //Linux
    '/usr/local/bin/mysqldump', //Linux
    '/usr/mysql/bin/mysqldump'); //Linux

    $database = escapeshellarg($this->db->database);
    $db_hostname = escapeshellarg($this->db->hostname);
    $db_username= escapeshellarg($this->db->username);
    $db_password = escapeshellarg($this->db->password);

    $success = FALSE;
    foreach($mysqldump_paths as $mysqldump)
    {

        if (is_executable($mysqldump))
        {
            $backup_command = "\"$mysqldump\" --host=$db_hostname --user=$db_username --password=$db_password $database";

            // set appropriate headers for download ...  
            header('Content-Description: File Transfer');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename="php_point_of_sale.sql"');
            header('Content-Transfer-Encoding: binary');
            header('Connection: Keep-Alive');
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
            header('Pragma: public');

            $status = false; 
            passthru($backup_command, $status);
            $success = $status == 0;
            break;
        }
    }

    if (!$success)
    {
        header('Content-Description: Error message');
        header('Content-Type: text/plain');
        header('Content-Disposition: inline');
        header('Content-Transfer-Encoding: base64');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        die(lang('config_mysqldump_failed'));   
    }
}