I'm currently using a script from http://davidwalsh.name/backup-mysql-database-php to do a "hotcopy" like backup of a myisam sql database but the issue im running into is that I get a fatal error with running out of memory.
I'm working with HUGE databases so it writes entire dbs into a string then output the entire string into fwrite at once and I believe thats where the problem lays. So is it possible to split the write action into chunks so I wouldn't run into the out of memory fatal error? If so, how would you achieve this?
Here is my attempt:
ini_set('memory_limit','3000M');
//create the file to be written into
$return = '';
$f = 'db-backup-'.$name.'_'.time().'.sql';
$handle = fopen($f,'w+');
fwrite($handle,$return);
fclose($handle);
//...mysql connect goes here then...
//cycle through
foreach($tables as $table)
{
$result = mysql_query('SELECT * FROM '.$table);
$num_fields = mysql_num_fields($result);
$return.= 'DROP TABLE '.$table.';';
$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";
//Write each table into file
fopen($f,'w+');
fwrite($handle,$return);
fclose($handle);
$return =''; //clear return thus clearing memory?
}
I know there are better ways to backup the databases, this is just temporary until I get LVM to work.
Thanks
TL;DR fwrite giving out of memory error, if split the writes will avoid that issue?
ps. mysqldump locks the dbs so i cant use dump, and replication is broken since we are using temporary tables and temp tables are a must.
change this
$result = mysql_query('SELECT * FROM '.$table);
to
$result = mysql_query('SELECT * FROM LIMIT 5000'.$table); //this will only get the first 5000.
after you get them and saved you can get the rest by using
$result = mysql_query('SELECT * FROM OFFSET 5000'.$table); //you can use limit over here too...