У меня есть три сервера в кластере мультиведущего устройства Galera. Я недавно импортировал некоторые старые базы данных и заметил, что таблицы составлялись через все три, но данные не копировались. Оказывается, что я не обращал внимание, и эти старые базы данных все использовали таблицы MyISAM. Таким образом, я знаю, что в будущем, должен буду преобразовать их в InnoDB перед введением их, чтобы заставить их работать.
Однако у меня нет удачи при нахождении официального способа синхронизировать существующие данные. Выполнение ALTER TABLE
преобразовать существующие таблицы в InnoDB не синхронизирует существующие данные.
Моя мысль состояла в том, чтобы вывести таблицу (теперь, когда она была преобразована) с mysqldump
, затем возвратите его в с mysql -u user -p db < db.sql
. Я не вижу оснований, почему это не работало бы, но я задаюсь вопросом, существует ли лучший путь.
я не смог найти официального способа справиться с этим, так что я пошел с идеей сбрасывать столы по отдельности и реимпортировать их. Не желая делать это вручную, я взбил PHP скрипт, чтобы сделать это за меня. Я размещаю его здесь на случай, если кто-нибудь еще сочтет это полезным.
/*
* InnoDB Convert
* Converts existing non-InnoDB tables to InnoDB, then re-imports the
* data so that it's replicated across the cluster.
*/
// Configuration
$_config['db'] = array(
'type' => 'mysql',
'host' => 'localhost',
'username' => 'user',
'password' => 'password'
);
// Establish database connection
try {
$pdo = new PDO(
$_config['db']['type'] . ':host=' . $_config['db']['host'],
$_config['db']['username'],
$_config['db']['password']
);
} catch ( PDOException $e ) {
echo 'Connection failed: ' . $e->getMessage();
}
// Get list of databases
$db_query = <<<SQL
SHOW DATABASES
SQL;
$db_result = $pdo->prepare( $db_query );
$db_result->execute();
while ( $db_row = $db_result->fetch( PDO::FETCH_ASSOC )) {
// Look through databases, but ignores the ones that come with a
// MySQL install and shouldn't be part of the cluster
if ( !in_array( $db_row['Database'], array( 'information_schema', 'mysql', 'performance_schema', 'testdb' ))) {
$pdo->exec( "USE {$db_row['Database']}" );
$table_query = <<<SQL
SHOW TABLES
SQL;
$table_result = $pdo->prepare( $table_query );
$table_result->execute();
while ( $table_row = $table_result->fetch( PDO::FETCH_ASSOC )) {
// Loop through all tables
$table = $table_row["Tables_in_{$db_row['Database']}"];
$engine_query = <<<SQL
SHOW TABLE STATUS WHERE Name = :table
SQL;
$engine_result = $pdo->prepare( $engine_query );
$engine_result->execute( array(
':table' => $table
));
$engine_row = $engine_result->fetch( PDO::FETCH_ASSOC );
if ( $engine_row['Engine'] != 'InnoDB' ) {
// Engine is not equal to InnoDB, let's convert it
echo "Converting '$table' on '{$db_row['Database']}' from '{$engine_row['Engine']}' to InnoDB:\n";
echo "Modifying engine...";
$change_query = <<<SQL
ALTER TABLE $table ENGINE=InnoDB
SQL;
$change_result = $pdo->prepare( $change_query );
$change_result->execute();
echo "done!\n";
echo " Exporting table...";
exec( "mysqldump -h {$_config['db']['host']} -u {$_config['db']['username']} -p{$_config['db']['password']} {$db_row['Database']} $table > /tmp/dump-file.sql" );
echo "done!\n";
echo " Re-importing table...";
exec( "mysql -h {$_config['db']['host']} -u {$_config['db']['username']} -p{$_config['db']['password']} {$db_row['Database']} < /tmp/dump-file.sql" );
echo "done!\n";
unlink( '/tmp/dump-file.sql' );
echo "done!\n";
}
}
}
}
Я успешно использовал его для преобразования сотен таблиц в пару десятков баз данных примерно за две минуты.
.