Memory requirements for mysqldump from php script

别来无恙 提交于 2020-01-25 03:07:25

问题


I have the following script which works great for database backup. But will I ever run into memory issues for very large databases?

//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);

回答1:


I would not use shell_exec(). Use passthru() instead, it will not require extra memory as it passes mysqldump's output untouched to PHP's output:

// 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"');

However, this solution will not being able to set the Content-Length header as the size of output is unknown for PHP. In most cases it should be OK and you can live with that. (phpmyadmin does the same)


Using passthru() even set_time_limit() isn't required here (unless your server runs Windows(!)). From the documenation:

Note: The set_time_limit() function and the configuration directive max_execution_time only affect the execution time of the script itself. Any time spent on activity that happens outside the execution of the script such as system calls using system(), stream operations, database queries, etc. is not included when determining the maximum time that the script has been running. This is not true on Windows where the measured time is real.




回答2:


Final solution based on comments/discussion:

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'));   
    }
}


来源:https://stackoverflow.com/questions/20665609/memory-requirements-for-mysqldump-from-php-script

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!