使用PHP进行MySQL数据备份

时间:2012-09-14 08:27:20

标签: php mysql

我在这里遇到了一个问题,真的需要你的帮助。我试图使用PHP脚本导出mysql数据。但问题是下面的错误 “致命错误:允许的内存大小为67108864字节耗尽......”。我看过他们建议更改php.ini文件的一些帖子。但由于我在专用服务器上托管,因此我没有该访问权限。我尝试导出的表有2.2GB的数据。我在这里发布我用来导出这些数据的函数。你能帮助我解决这个问题吗?

<?php
set_time_limit(0);
backup_tables('hostname','username','password','databasename');

function backup_tables($host,$user,$pass,$name,$table = 'Table Name')
{

$link = mysql_connect($host,$user,$pass);
mysql_select_db($name,$link);

$result = mysql_query('SELECT * FROM '.$table);
$num_fields = mysql_num_fields($result);

$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
$return.= "\n\n".$row2[1].";\n\n";

for ($i = 0; $i < $num_fields; $i++)
{
while($row = mysql_fetch_row($result))
{
$return.= 'INSERT INTO '.$table.' VALUES(';
for($j=0; $j<$num_fields; $j++)
{
$row[$j] = addslashes($row[$j]);
$row[$j] = ereg_replace("\n","\\n",$row[$j]);
if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
if ($j<($num_fields-1)) { $return.= ','; }
}
$return.= ");\n";
}
}
$return.="\n\n\n";
//save file
$handle = fopen('db-backup-'.time().'-'.($tables).'.sql','w+');
fwrite($handle,$return);
fclose($handle);
}
?>

5 个答案:

答案 0 :(得分:5)

我认为你正试图在这里重新制作一个轮子。 Mysql有一个很棒的mysqldump可执行文件,可以快速,安静地使用少量资源生成你正在制作的文件。最好的是你可以使用exec在PHP脚本中直接调用它,例如:

exec('mysqldump --user=... --password=... --host=... DB_NAME > /path/to/output/file.sql');

答案 1 :(得分:1)

  

我想要导出的表有更多2.2GB的数据

你正试图将它全部加载到PHP数组中。

即使你有足够的记忆力,表现也会令人震惊。

在阅读时写下从数据库中提取的行...

while ($row = mysql_fetch_row($result)) {
   fputs($outfile, 'INSERT INTO '.$table.' VALUES(');
   ....
}

但更好的解决方案是使用mysqldump。

<强>更新

我忘了说你的输出转义方法是错误的 - 使用mysql_escape_string()而不是addslashes + ereg_replace()(如果你必须使用字符串重新定位函数,str_replace比[ep] reg_replace快得多)。

答案 2 :(得分:0)

尝试使用Zip->addFromString

压缩备份sql语句

http://php.net/manual/fr/book.zip.php

http://php.net/manual/fr/zip.examples.php

<?php

$zip = new ZipArchive();
$filename = "./backup.zip";

if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
    exit("Could not open <$filename>\n");
}
$zip->addFromString("backup.txt", "sql statement");
$zip->close();
?>

尝试将您的备份划分为多个zip文件(例如:一个拉链表)

答案 3 :(得分:0)

不是将所有内容都收集到(巨大的)$return中,而是将fopen调用移到函数的开头,并使用fwrite直接写入每个结果,而不是将其添加到$return。您遇到的内存问题是因为$return占用了太多空间。

答案 4 :(得分:0)

嗯..我想最好的方法是使用sql查询"SELECT * INTO OUTFILE...",因为php.ini安全模式可以禁止php函数“exec”。