Clúster MariaDB Galera, sincronización forzada

Clúster MariaDB Galera, sincronización forzada

Tengo tres servidores en un clúster Galera multimaestro. Recientemente importé algunas bases de datos antiguas y noté que las tablas se estaban creando en las tres, pero los datos no se replicaban. Resulta que no estaba prestando atención y todas estas bases de datos antiguas usaban tablas MyISAM. Así que sé que en el futuro tendré que convertirlos a InnoDB antes de incorporarlos para que funcionen.

Sin embargo, no tengo suerte para encontrar una forma oficial de sincronizar los datos existentes. Ejecutar ALTER TABLEpara convertir las tablas existentes a InnoDB no sincroniza los datos existentes.

Mi idea era deshacerme de la tabla (ahora que se ha convertido) con mysqldump, y luego traerla de nuevo con mysql -u user -p db < db.sql. No veo ninguna razón por la que eso no funcione, pero me pregunto si hay una manera mejor.

Respuesta1

No pude encontrar una forma oficial de manejar esto, así que se me ocurrió la idea de deshacerme de las tablas individualmente y volver a importarlas. Como no quería hacerlo a mano, preparé un script PHP para que lo hiciera por mí. Lo publico aquí por si alguien más lo encuentra útil.

/*
 * 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";
                }
            }
        }
    }

Lo usé con éxito para convertir cientos de tablas en un par de docenas de bases de datos en aproximadamente dos minutos.

información relacionada