PHP - PDO MySQL резервного копирования на удаленный хост? - PullRequest
2 голосов
/ 26 сентября 2010

Добро пожаловать,

Как создать полную резервную копию моей базы данных (все таблицы внутри) на удаленном сервере MySQL с помощью PHP PDO?

Есть ли простой способ?

Ответы [ 3 ]

1 голос
/ 26 сентября 2010

Вам нужно будет выполнить 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 (например, идентификаторов первичного ключа) не вызывает ошибок и работает должным образом, поэтому $destDB->quote() в array_map() тогда должно быть безопасно, но я не знаю точно, применимо ли это ко всем типам данных и всем системам баз данных.
  • Выполнение всего за одну транзакцию предотвращает несогласованные резервные копии.
  • В примере предполагается, что в обеих базах данных имеется одинаковая структура базы данных, причем все столбцы отображаются в точно в одном и том же порядке .
  • Ваши таблицы должны быть удалены и построены в правильном порядке.не нарушать никаких ограничений внешнего ключа , в противном случае резервное копирование может завершиться неудачей.
  • Провести расширенное тестирование (в идеале на выделенной тестовой системе с копией ваших живых данных) сразличные сценарии (некоторые или все таблицы пустые, таблицы с большим количеством строк, все таблицы не пустые и т. д.), чтобы обеспечить его надежную работу и не нарушать сценарий резервного копированияn недостаточно памяти из-за низкого значения memory_limit ).Сравните базу данных назначения с источником, выгрузив их, например, с помощью mysqldump или подобного, чтобы убедиться, что они идентичны и резервное копирование завершено.Вы можете даже столкнуться с неприятными ошибками PDO в худшем случае, когда вам, возможно, придется обойтись - Google и SO ваши друзья: -).

РЕДАКТИРОВАТЬ:
Oneможет дополнительно использовать специальную INFORMATION_SCHEMA базу данных для запроса имен таблиц и автоматического определения зависимостей внешнего ключа.
Кроме того, вы можете отключить проверку внешнего ключа в целевой базе данных во времяпередать (и включить их впоследствии), если у вас есть собственные ссылки на внешние ключи для предотвращения сбоев из-за нарушений ограничений.

1 голос
/ 26 сентября 2010

Я бы начал с документации MySQL по репликации .Я бы не рекомендовал делать это с PHP и PDO.Вы получите лучшие результаты, если будете использовать правильный инструмент для работы.ИМХО.

0 голосов
/ 26 сентября 2010

Если речь идет о резервном копировании, вам следует придерживаться установленных инструментов администратора. Используйте SQLBuddy или PHPMySQLAdmin.

Вы можете написать систему дублирования, используя метод RPC или передачу данных с помощью JSON или чего-то еще. Но это требует защиты, будет медленным и полезным только для передачи контента, а не для репликации схемы SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...