简体   繁体   English

如何加快php备份脚本的速度?

[英]How to speed up php backup script?

I have been using a mysql db backup script in php and the backups take 21 hours my dbs. 我一直在php中使用mysql db备份脚本,备份需要21个小时。 I want to use it as a daily backup script through cli and cron and was wondering if you guys could take a look at it and see if there is anyway I can optimize it. 我想将其用作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";
?>

I was thinking about splitting the backups into parallel processes but my databases are huge and I'm not sure if php will run out of memory because it has before. 我当时正在考虑将备份拆分为并行进程,但是我的数据库很大,我不确定php是否会用完内存,因为以前有过。 Suggestions are welcome. 欢迎提出建议。

Thanks! 谢谢!

ps. ps。 I know there are better ways to do a backup but this particular script works well for me as the other options, such as mysqldump is not available to me. 我知道有更好的备份方法,但是这个特殊的脚本对我来说效果很好,因为其他选项(例如mysqldump)对我不可用。

Yes you could directly copy a table in MySQL 是的,您可以直接在MySQL中复制表

CREATE TABLE new_table LIKE old_table;
INSERT new_table SELECT * FROM old_table;

It will be way faster, and you could also have your table on 2 separated database (NEW_DB & OLD_DB) 这样会更快,并且您还可以将表放在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;

So you could do it from PHP, WITHOUT transferring data to PHP, with a huge gain in performance. 因此,您可以从PHP做到这一点,而无需将数据传输到PHP,而获得了巨大的性能提升。

If you're looking to back up your database, just use mysqldump as Dagon mentioned. 如果您要备份数据库,请使用Dagon所述的mysqldump Call it from a cron task on a schedule. 按计划从cron任务调用它。 Then if you need to roll back, you can simply find proper dump (stored in a .sql file) and execute the file. 然后,如果需要回滚,只需找到适当的转储(存储在.sql文件中)并执行该文件即可。

mysqldump -u [username] -p[password] db_name > [timestamped_filename].sql

Read this article for more information . 阅读本文以获得更多信息

was utilizing mysqldump but realized that it was driving productivity down because of locks on myisam dbs and the backups were unsuable if i just removed the locks and continued backing up the dbs while they were in use. 我正在使用mysqldump,但意识到由于myisam dbs上的锁而导致生产力下降,如果我只是删除锁并在使用中继续备份dbs,则备份将无法使用。 thats why i need something like a hotcopy backup for the myisam dbs 那就是为什么我需要为myisam dbs提供类似热拷贝备份的功能

Correct me if I'm wrong, but your script does no locking at all. 如果我错了,请纠正我,但是您的脚本根本没有锁定。 If it takes 21 hours to execute, then you've got to have synchronization issues. 如果需要21小时执行,那么你必须有同步问题。

If you can't use mysqldump , the only practical solutions I see are to use a MySQL slave (see: http://www.redips.net/mysql/add-new-slave/ - points 1 and 2 are what interests you) and mysqlhotcopy : http://dev.mysql.com/doc/refman/5.1/en/mysqlhotcopy.html . 如果您不能使用mysqldump ,那么我看到的唯一实际的解决方案是使用MySQL从站(请参阅: http : //www.redips.net/mysql/add-new-slave/-第 1点和第2点是您的兴趣所在)和mysqlhotcopyhttp : //dev.mysql.com/doc/refman/5.1/en/mysqlhotcopy.html

The first solution is more complicated to set up, but it's probably cleaner and simpler (also, I think, faster) to run. 第一个解决方案的设置较为复杂,但运行起来可能更简洁,更简单(我认为也是更快)。 And with a little more set-up, it can double as load-balancing on the SQL server. 有了更多的设置,它就可以两倍于SQL Server上的负载平衡。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM