プライマリクラスタのレプリケーションプロセスが失敗した場合、セカンダリレプリケーションチャネルに切り替えることができます。 次に、この実現に必要なステップについて説明します。
-
最新のグローバルチェックポイント (GCP) の時刻を取得します。 つまり、次のクエリーを使用して、レプリカクラスタの
ndb_apply_status
テーブルから最新のエポックを判別する必要があります:mysqlR'> SELECT @latest:=MAX(epoch) -> FROM mysql.ndb_apply_status;
ソースとレプリカが各ホストで実行されている循環レプリケーショントポロジでは、
ndb_log_apply_status=1
を使用している場合、NDB Cluster エポックは複製バイナリログに書き込まれます。 つまり、ndb_apply_status
テーブルには、このホスト上のレプリカおよびこのホストで実行されているレプリケーションソースサーバーのレプリカとして機能する他のホストのレプリカに関する情報が含まれます。この場合、このレプリカの最新のエポックを決定して、このレプリカの設定に使用された
CHANGE REPLICATION SOURCE TO
|CHANGE MASTER TO
ステートメントのIGNORE_SERVER_IDS
オプションにリストされていないエポックをこのレプリカバイナリログ内の他のレプリカから除外する必要があります。 このようなエポックを除外する理由は、このレプリカソースの準備に使用されたCHANGE REPLICATION SOURCE TO
|CHANGE MASTER TO
ステートメントのIGNORE_SERVER_IDS
リストに一致するサーバー ID を持つmysql.ndb_apply_status
テーブルの行も、レプリカ独自のサーバー ID を持つ行に加えて、ローカルサーバーからの行とみなされるためです。 このリストは、SHOW REPLICA | SLAVE STATUS
の出力からReplicate_Ignore_Server_Ids
として取得できます。 このリストを取得し、前のバージョンのクエリーと同様に、@latest
という名前の変数に最大のエポックを選択する、ここに示すクエリーでignore_server_ids
に置換することを前提としています:mysqlR'> SELECT @latest:=MAX(epoch) -> FROM mysql.ndb_apply_status -> WHERE server_id NOT IN (ignore_server_ids);
場合によっては、前述のクエリーの
WHERE
条件に含めるサーバー ID のリストとserver_id IN
を使用する方が、より単純または効率的 (あるいはその両方) な場合があります。server_id_list
-
ステップ 1 で示したクエリーから取得した情報を使用して、ソースクラスタの
ndb_binlog_index
テーブルから対応するレコードを取得します。次のクエリーを使用して、ソースの
ndb_binlog_index
テーブルから必要なレコードを取得できます:mysqlS'> SELECT -> @file:=SUBSTRING_INDEX(next_file, '/', -1), -> @pos:=next_position -> FROM mysql.ndb_binlog_index -> WHERE epoch >= @latest -> ORDER BY epoch ASC LIMIT 1;
これらは、プライマリレプリケーションチャネルの失敗以降にソースに保存されたレコードです。 ここでは、ユーザー変数
@latest
を使用して、ステップ 1 で取得した値を表します。 もちろん、ある mysqld インスタンスが、ほかのサーバーインスタンスに設定されたユーザー変数には直接アクセスできません。 これらの値は、手動またはアプリケーションによる 2 番目のクエリーに対する「「プラグイン済」」である必要があります。重要START REPLICA | SLAVE
を実行する前に、レプリカ mysqld が--slave-skip-errors=ddl_exist_errors
で起動されていることを確認する必要があります。 そうしないと、レプリケーションが重複 DDL エラーで停止する可能性があります。 -
セカンダリレプリカサーバーで次のクエリーを実行して、セカンダリチャネルを同期化できるようになりました:
mysqlR'> CHANGE MASTER TO -> MASTER_LOG_FILE='@file', -> MASTER_LOG_POS=@pos; Or from MySQL 8.0.23: mysqlR'> CHANGE REPLICATION SOURCE TO -> SOURCE_LOG_FILE='@file', -> SOURCE_LOG_POS=@pos;
ここでも、ステップ 2 で取得してステップ 3 で適用した値を表すためにユーザー変数 (この場合は
@file
と@pos
) を使用しています。実際には、これらの値を手動で挿入するか、関係する両方のサーバーにアクセスできるアプリケーションを使用して挿入する必要があります。注記@file
は'/var/log/mysql/replication-source-bin.00001'
などの文字列値であるため、SQL またはアプリケーションコードで使用する場合は引用符で囲む必要があります。 ただし、@pos
で表される値は引用符で囲む必要はありません。 通常、MySQL は文字列を数字に変換しようとしますが、この場合は例外です。 -
セカンダリレプリカ mysqld で適切なコマンドを発行して、セカンダリチャネルでレプリケーションを開始できるようになりました:
mysqlR'> START SLAVE; Or from MySQL 8.0.22: mysqlR'> START REPLICA;
セカンダリレプリケーションチャネルがアクティブになったら、プライマリの不具合を調べて、修復できます。 これを行うために必要な正確なアクションは、プライマリチャネルが失敗した理由によって異なります。
セカンダリレプリケーションチャネルは、プライマリレプリケーションチャネルの停止時や停止した場合にのみ、起動されます。 複数のレプリケーションチャネルを同時に実行すると、不要な重複レコードがレプリカに作成される可能性があります。
障害が単一のサーバーに制限されている場合は、理論上、S
から R'
または S'
から R
にレプリケートできる必要があります。