我在这里遇到了一个问题,真的需要你的帮助。我试图使用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);
}
?>
答案 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
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”。