MariaDB Galera 클러스터, 강제 동기화

MariaDB Galera 클러스터, 강제 동기화

다중 마스터 Galera 클러스터에 3개의 서버가 있습니다. 최근 일부 오래된 데이터베이스를 가져왔는데 세 데이터베이스 모두에서 테이블이 생성되고 있지만 데이터가 복제되지 않는 것을 확인했습니다. 나는 주의를 기울이지 않았으며 이러한 오래된 데이터베이스는 모두 MyISAM 테이블을 사용하고 있었습니다. 따라서 앞으로는 이를 작동시키기 위해 가져오기 전에 InnoDB로 변환해야 한다는 것을 알고 있습니다.

그러나 기존 데이터를 동기화하는 공식적인 방법을 찾는 데에는 행운이 없습니다. 기존 테이블을 InnoDB로 변환하기 위해 실행하면 ALTER TABLE기존 데이터가 동기화되지 않습니다.

내 생각은 를 사용하여 테이블을 덤프한 다음(이제 변환되었으므로) 를 사용 mysqldump하여 다시 가져오는 것이었습니다 mysql -u user -p db < db.sql. 그게 작동하지 않을 이유는 없지만 더 좋은 방법이 있는지 궁금합니다.

답변1

이 문제를 공식적으로 처리할 수 있는 방법을 찾을 수 없어서 테이블을 개별적으로 덤프하고 다시 가져오는 아이디어를 냈습니다. 손으로 하고 싶지 않아서 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";
                }
            }
        }
    }

저는 이를 사용하여 약 2분 만에 수십 개의 데이터베이스에 걸쳐 수백 개의 테이블을 변환했습니다.

관련 정보