[英]How to speed up php backup script?
我一直在php中使用mysql db備份腳本,備份需要21個小時。 我想將其用作cli和cron的日常備份腳本,想知道你們是否可以看一下它,看看是否還有我可以對其進行優化。
<?
//Timer start
$time = microtime();
$time = explode(' ', $time);
$time = $time[1] + $time[0];
$start = $time;
ini_set('memory_limit','4000M');
//ini_set('max_execution_time', 300);
$host = "host";
$user = "user";
$pass = "pass";
$db = "tagdb";
$link = mysql_connect($host,$user,$pass);
$result = mysql_query("show databases like 'tag%'"); // we only want tagdb
while($row = mysql_fetch_row($result))
{
$dbs[] = $row[0];
}
foreach($dbs as $db)
{
if(strlen($db) == 10 || $db == "tagdb" || $db == "tagui")
{
echo $db."\n";
backup_tables($host,$user,$pass,$db);
}
}
//backup_tables($host,$username,$password,$db);
/* backup the db OR just a table */
function backup_tables($host,$user,$pass,$name,$tables = '*')
{
$fname = 'db-backup-'.$name.'_'.time().'.sql';
echo $fname."\n";
$handle = fopen($fname,'w+');
$return = '';
fwrite($handle,$return);
fclose($handle);
$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);
}
foreach($tables as $table)
{
$handle = fopen($fname,'a');
fwrite( $handle, 'DROP TABLE IF EXISTS '.$table.';' );
$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
fwrite( $handle, "\n\n".$row2[1].";\n\n" );
$offset = 10000;
$start = 0;
do {
$result = mysql_query( "SELECT * FROM ".$table." LIMIT ".$start.", ".$offset."" );
$start += $offset;
$num_rows = mysql_num_rows( $result );
if (false === $result) {
//close original file
fclose($handle);
//open error file
$errfn = $fname.'.ERROR';
$errf = fopen($errfn,'a');
$err = mysql_error();
fwrite( $errf, $err );
fclose($errf);
//reopen original file
$handle = fopen($fname,'a');
//break loop
$num_rows = 0;
}
while( $row = mysql_fetch_row( $result ) ) {
$line = 'INSERT INTO '.$table.' VALUES(';
foreach( $row as $value ) {
$value = addslashes( $value );
@$value = ereg_replace( "\n","\\n", $value );
$line .= '"'.$value.'",';
}
$line = substr( $line, 0, -1 ); // cut the final ','
$line .= ");\n";
fwrite( $handle, $line );
}
} while( $num_rows !== 0 );
}
$return="\n\n\n";
fwrite($handle,$return);
fclose($handle);
}
//End timer and output time
$time = microtime();
$time = explode(' ', $time);
$time = $time[1] + $time[0];
$finish = $time;
$total_time = round(($finish - $start), 4);
echo "\n Page generated in ".$total_time." seconds. \n";
?>
我當時正在考慮將備份拆分為並行進程,但是我的數據庫很大,我不確定php是否會用完內存,因為以前有過。 歡迎提出建議。
謝謝!
ps。 我知道有更好的備份方法,但是這個特殊的腳本對我來說效果很好,因為其他選項(例如mysqldump)對我不可用。
是的,您可以直接在MySQL中復制表
CREATE TABLE new_table LIKE old_table;
INSERT new_table SELECT * FROM old_table;
這樣會更快,並且您還可以將表放在2個分離的數據庫(NEW_DB和OLD_DB)上
CREATE TABLE NEW_DB.new_table LIKE OLD_DB.old_table;
INSERT NEW_DB.new_table SELECT * FROM OLD_DB.old_table;
因此,您可以從PHP做到這一點,而無需將數據傳輸到PHP,而獲得了巨大的性能提升。
如果您要備份數據庫,請使用Dagon所述的mysqldump
。 按計划從cron任務調用它。 然后,如果需要回滾,只需找到適當的轉儲(存儲在.sql文件中)並執行該文件即可。
mysqldump -u [username] -p[password] db_name > [timestamped_filename].sql
我正在使用mysqldump,但意識到由於myisam dbs上的鎖而導致生產力下降,如果我只是刪除鎖並在使用中繼續備份dbs,則備份將無法使用。 那就是為什么我需要為myisam dbs提供類似熱拷貝備份的功能
如果我錯了,請糾正我,但是您的腳本根本沒有鎖定。 如果需要21小時執行,那么你就必須有同步問題。
如果您不能使用mysqldump
,那么我看到的唯一實際的解決方案是使用MySQL從站(請參閱: http : //www.redips.net/mysql/add-new-slave/-第 1點和第2點是您的興趣所在)和mysqlhotcopy
: http : //dev.mysql.com/doc/refman/5.1/en/mysqlhotcopy.html 。
第一個解決方案的設置較為復雜,但運行起來可能更簡潔,更簡單(我認為也是更快)。 有了更多的設置,它就可以兩倍於SQL Server上的負載平衡。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.