I’m using a modified php mysql backup script I found on the net to backup my sql databases but I kept running into an issue with mysql_fetch_row and I was wondering if there was a way to fix it.
I commented the line with the memory error.
<?php
ini_set('memory_limit','4000M');
$ho = "host";
$us = "username";
$pa = "password";
$da='dbname';
backup_tables($ho,$us,$pa,$da);
/* backup the db OR just a table */
function backup_tables($host,$user,$pass,$name,$tables = '*')
{
$link = mysql_connect($host,$user,$pass);
mysql_select_db($name,$link);
//get all of the tables
if($tables == '*')
{
$tables = array();
$result = mysql_query('SHOW TABLES');
while($row = mysql_fetch_row($result))
{
$tables[] = $row[0];
}
}
else
{
$tables = is_array($tables) ? $tables : explode(',',$tables);
}
$filename = 'db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql';
$handle = fopen($filename,'w');
//cycle through
foreach($tables as $table)
{
$result = mysql_query('SELECT * FROM '.$table);
$num_fields = mysql_num_fields($result);
fwrite( $handle, 'DROP TABLE '.$table.';' );
$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
fwrite( $handle, "\n\n".$row2[1].";\n\n" );
for ($i = 0; $i < $num_fields; $i++)
{
//this is the line with the error******
while($row = mysql_fetch_row($result))
{
fwrite( $handle, '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])) { fwrite( $handle, '"'.$row[$j].'"' ) ; }
else { fwrite( $handle, '""' ); }
if ($j<($num_fields-1)) { fwrite( $handle, ',' ); }
}
fwrite( $handle, ");\n" );
}
}
fwrite( $handle, "\n\n\n" );
}
//save file
fclose($handle);
}
?>
and this is the error:
Fatal error: Out of memory (allocated 1338507264) (tried to allocate 35 bytes) in /home/user/backupSQL/backupmodified.php on line 47
I know there are better ways to do a backup but this meets all my requirements for my system and I only run into the memory problem with my ridiculously huge databases.
Thanks for the help.
-PHP/MySQL newbie
ps. heres the link i used http://www.htmlcenter.com/blog/back-up-your-mysql-database-with-php/
edit: mysqldump works fine when backing up these large databases, but the large dbs are the most modified ones and I cant have my dbs lock while dumping when someone needs to work on them. That’s why I resorted to this script.
As the other posters have mentioned, you would be better off using a ready-made tool, but let’s talk about your script for now.
If you have a ridiculously large table, then there’s just no way to allocate that much memory. You’ll have to split your data set into multiple chunks. Use a query like:
Then just iterate with
$startor do awhileloop to check if you’re still getting results. Like this, you’ll get the data in chunks of 10000 records so it’ll surely fit in your memory.There’s still a problem, though – consistency. What if some rows change while you’re still fetching chunks? Well, you could wrap your
SELECTloop in a transaction and lock the table while you’re getting the data. I know you’re trying to avoid locks, but locking a table is better than an entire database. This still won’t ensure inter-table consistency, but it’s the best that can be done under the conditions you set.EDIT: Here is the code for the loop. I implemented the
whilesolution. There is an equivalentforloop, but the comparison between the two is outside the scope of this post.