MariaDB Galera Cluster, Synchronisierung erzwingen

MariaDB Galera Cluster, Synchronisierung erzwingen

Ich habe drei Server in einem Multimaster-Galera-Cluster. Ich habe kürzlich einige alte Datenbanken importiert und dabei festgestellt, dass die Tabellen in allen drei erstellt wurden, die Daten jedoch nicht repliziert wurden. Es stellte sich heraus, dass ich nicht aufgepasst hatte und diese alten Datenbanken alle MyISAM-Tabellen verwendeten. Ich weiß also, dass ich diese in Zukunft in InnoDB konvertieren muss, bevor ich sie einführe, damit sie funktionieren.

Ich habe jedoch kein Glück bei der Suche nach einer offiziellen Möglichkeit, die vorhandenen Daten zu synchronisieren. Beim ALTER TABLEKonvertieren der vorhandenen Tabellen in InnoDB werden die vorhandenen Daten nicht synchronisiert.

Mein Gedanke war, die Tabelle (nachdem sie konvertiert wurde) mit zu sichern und mysqldumpsie dann mit wieder zu importieren mysql -u user -p db < db.sql. Ich sehe keinen Grund, warum das nicht funktionieren sollte, frage mich aber, ob es einen besseren Weg gibt.

Antwort1

Ich konnte keine offizielle Methode finden, dies zu handhaben, also habe ich mir überlegt, die Tabellen einzeln zu sichern und sie dann erneut zu importieren. Da ich das nicht von Hand machen wollte, habe ich ein PHP-Skript erstellt, das das für mich erledigt. Ich poste es hier, falls es jemand anderes nützlich findet.

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

Ich habe es erfolgreich verwendet, um Hunderte von Tabellen in mehreren Dutzend Datenbanken in etwa zwei Minuten zu konvertieren.

verwandte Informationen