如何加速php备份脚本?

如何加速php备份脚本?,php,mysql,optimization,backup,database-backups,Php,Mysql,Optimization,Backup,Database Backups,我一直在使用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

我一直在使用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是否会耗尽内存,因为它以前有过。 欢迎提出建议

谢谢


另外,我知道有更好的备份方法,但是这个特定的脚本对我来说很好,因为其他选项,例如mysqldump,我不可用。

是的,您可以直接在MySQL中复制一个表

CREATE TABLE new_table LIKE old_table;
INSERT new_table SELECT * FROM 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从机(请参阅:-您感兴趣的是第1点和第2点)和
mysqlhotcopy


第一个解决方案的设置更复杂,但它可能更干净、更简单(我认为,运行起来也更快)。再加一点设置,它就可以在SQL server上兼作负载平衡功能。

请使用mysqldump;该脚本在很多方面都是错误的。它可能无助于回答您的问题,但您应该停止使用
mysql.*
函数。他们被弃用了。改为使用(从PHP5.1开始支持)或(从PHP4.1开始支持)。如果您不确定使用哪一个,那么您如何无法使用mysqldump?我只是好奇。@Dagon lol是的,我知道。但就像我说的,我不能使用mysqldump。但这不是我备份的永久解决方案。将获得新的机器,并将我的数据库迁移到我可以使用的linux设备lvm@Matt我会研究一下的,谢谢,希望我能把所有的mysql标签都改成mysqli/PDO?我使用myisam数据库b/c innodb必须获得许可才能使用。我需要一个热拷贝功能,因为全世界的人都在使用数据库。mysqldump会锁定dbs,如果我关闭了锁,我担心如果有人在备份过程中编辑它,备份会被破坏。虽然我知道这也不是一个理想的过程。我在网上找到的几个脚本中,有一个是有效的,而且我理解的,因为我只使用php编程。我不太懂。所以基本上我在创建一个临时表,从那里我可以运行脚本?但如果我这样做,这个过程也会花同样的时间,不是吗?我在一个仅包含文本的mysqldump中有几个大约1-2gb的大型数据库,因此复制数据库需要一段时间。我正在使用mysqldump,但意识到由于myisam dbs上的锁,这会降低生产效率,如果我只是在使用中移除锁并继续备份dbs,备份将无法运行。这就是为什么我需要myisam dbs的热拷贝备份。我的原始脚本使用了mysqldump和locks,这是另一个不锁定的脚本,输出和备份我可以使用。从机对我来说也不起作用,因为我们有太多的并发用户,我们必须使用临时表,这会导致从机复制出现很多错误(如果你说的从机就是这个意思的话)。mysqlhotcopy只能由innodb使用,innodb必须获得许可才能使用,hotcopy的功能就像我现在使用的myisam dbs的转储和锁定dbs一样。我将在获得新服务器后迁移到linux,并将使用lvm,但这需要几个月的时间,这就是为什么我需要帮助优化此脚本,因为它是一个短期/临时备份解决方案。谢谢你的意见,不过,我会研究同步。
mysqldump -u [username] -p[password] db_name > [timestamped_filename].sql