我有以下脚本,非常适合数据库备份。但是我会遇到非常大的数据库的内存问题吗?
//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);
答案 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'));
}
}