PHP - PDO mysql备份到远程主机?

时间:2010-09-25 22:09:30

标签: php mysql pdo

欢迎,

如何使用PHP PDO创建我的数据库(所有表内)的完整备份到远程mysql服务器?

有简单的方法吗?

3 个答案:

答案 0 :(得分:1)

我会从MySQL documentation on replication开始。我不建议用PHP和PDO这样做。当您使用正确的工具完成工作时,您将获得更好的结果。 IMHO。

答案 1 :(得分:1)

您必须在源数据库中的每个表上执行SELECT * FROM [table],然后在目标数据库上运行一个大事务,删除所有以前的表数据,然后插入新数据。 基本上类似于这个片段:

<?php
// $srcDB and $destDB are instances of PDO.
// $tableNames is an array of tables in the correct order.
//
//   $srcDB = new PDO(...);
//   $destDB = new PDO(...);
//   $tableNames = array('table1', 'table2');

$srcDB->beginTransaction();
$destDB->beginTransaction();

try {
    foreach ($tableNames as $tableName) {
        // Fetch records from source
        $srcStatement = $srcDB->query('SELECT * FROM '.$tableName);
        $rows = $srcStatement->fetchAll(PDO::FETCH_NUM);
        // Free resources allocated by query
        $srcStatement->closeCursor();
        $srcStatement = null;

        if ( count($rows) === 0 )
            continue; // No rows

        // Prepare records to insert
        $insertValues = array();
        foreach ($rows as $row)
            $insertValues[] = '('.implode(',', array_map(array($destDB, 'quote'), $row)).')';

        // Clear destination table      
        if ( $destDB->exec('DELETE FROM '.$tableName) === false )
            throw new Exception('DELETE failed for table '.$tableName);

        // Write records
        if ( $destDB->exec('INSERT INTO '.$tableName.' VALUES '.implode(',', $insertValues)) === false )
            throw new Exception('INSERT failed for table '.$tableName);
    }

} catch (Exception $e) {
    $srcDB->rollBack();
    $destDB->rollBack();
    throw $e;
}

$result = $destDB->commit();
$srcDB->rollBack(); // or $srcDB->commit() - we did not change the source DB though

if ( !$result )
    throw new Exception('Commit failed');

// Success
?>

注意:

  • 至少对于MySQL,引用INT(例如主键ID)不会导致错误并且正常工作,因此$destDB->quote()中的array_map()应该是安全的,但我不确定是否这适用于所有数据类型和所有数据库系统。
  • 在单个事务中执行所有操作可防止备份不一致。
  • 该示例假定您在两个数据库中具有相同的数据库结构,所有列都以完全相同的顺序显示。
  • 您的表格必须以正确的顺序删除和构建,以免违反任何外键约束,否则备份可能会失败。
  • 广泛测试(理想情况下,在具有实时数据副本的专用测试系统上),具有不同的场景(部分或全部表为空,表格包含大量行,所有表格均为非空等) )确保它可靠地工作,并且由于memory_limit setting低,备份脚本不会耗尽​​内存。通过转储它们来比较目标数据库和源,例如使用mysqldump等来验证它们是否相同并且备份是否完整。您甚至可能在最糟糕的情况下遇到令人讨厌的PDO错误,您可能需要解决这些问题 - Google和SO是您的朋友: - 。)。

修改
另外还可以使用特殊INFORMATION_SCHEMA database来查询表名并自动确定外键依赖关系 此外,当您具有自引用外键关系以防止因约束违规而导致失败时,您可能希望在传输期间在目标数据库上disable foreign key checks(并在之后重新启用它们)。

答案 2 :(得分:0)

如果是备份,你应该坚持使用既定的管理工具。使用SQLBuddy或PHPMySQLAdmin。

您可以使用RPC方法编写复制系统或使用JSON或其他方式进行数据传输。但这需要保护,速度很慢,只对内容传输有帮助,而不是SQL模式复制。