NDB Cluster 内のレプリケーションでは、レプリケートされるクラスタとレプリカの両方で SQL ノードとして機能する各 MySQL Server インスタンス上の mysql
データベース内の多数の専用テーブルが使用されます。 これは、レプリカが単一サーバーであるかクラスタであるかに関係なく当てはまります。 これらのテーブルは、MySQL のインストールプロセス中に作成され、バイナリログのインデックス作成データを格納するためのテーブルを含みます。 ndb_binlog_index
テーブルは各 MySQL サーバーに対してローカルであり、クラスタ化には関与しないため、InnoDB
ストレージエンジンを使用します。 つまり、ソースクラスタに参加している各 mysqld に個別に作成する必要があります。 (バイナリログ自体には、レプリケートされるクラスタ内のすべての MySQL サーバーからの更新が含まれます。) このテーブルは次のように定義されます。
CREATE TABLE `ndb_binlog_index` (
`Position` BIGINT(20) UNSIGNED NOT NULL,
`File` VARCHAR(255) NOT NULL,
`epoch` BIGINT(20) UNSIGNED NOT NULL,
`inserts` INT(10) UNSIGNED NOT NULL,
`updates` INT(10) UNSIGNED NOT NULL,
`deletes` INT(10) UNSIGNED NOT NULL,
`schemaops` INT(10) UNSIGNED NOT NULL,
`orig_server_id` INT(10) UNSIGNED NOT NULL,
`orig_epoch` BIGINT(20) UNSIGNED NOT NULL,
`gci` INT(10) UNSIGNED NOT NULL,
`next_position` bigint(20) unsigned NOT NULL,
`next_file` varchar(255) NOT NULL,
PRIMARY KEY (`epoch`,`orig_server_id`,`orig_epoch`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
古いリリース (NDB 7.5.2 より前) からアップグレードする場合は、MySQL のアップグレード手順を実行して、システムテーブルがアップグレードされていることを確認します。 (MySQL 8.0.16 の時点で、--upgrade=FORCE
オプションを使用してサーバーを起動します。 MySQL 8.0.16 より前は、サーバーの起動後に --force
および --upgrade-system-tables
オプションを指定して mysql_upgrade を起動してください。) システムテーブルのアップグレードにより、このテーブルに対して ALTER TABLE ... ENGINE=INNODB
ステートメントが実行されます。 このテーブルに対する MyISAM
ストレージエンジンの使用は、下位互換性のために引き続きサポートされています。
ndb_binlog_index
では、InnoDB
への変換後に追加のディスク領域が必要になる場合があります。 これが問題になった場合は、このテーブルの InnoDB
テーブルスペースを使用するか、ROW_FORMAT
を COMPRESSED
に変更するか、またはその両方を行うことで、領域を節約できます。 詳細は、セクション13.1.21「CREATE TABLESPACE ステートメント」、セクション13.1.20「CREATE TABLE ステートメント」 および セクション15.6.3「テーブルスペース」 を参照してください。
ndb_binlog_index
テーブルのサイズは、バイナリログファイルごとのエポックの数とバイナリログファイルの数によって異なります。 一般的に、バイナリログファイル当たりのエポック数は、エポックごとに作成されるバイナリログの量とバイナリログファイルのサイズに依存し、エポックが小さくなるとファイル当たりのエポックが増えます。 --ndb-log-empty-epochs
オプションが OFF
の場合でも、空のエポックによって ndb_binlog_index
テーブルへの挿入が生成されることに注意してください。つまり、ファイル当たりのエントリ数は、ファイルが使用されている時間の長さによって異なります。この関係は、次の式で表すことができます:
[number of epochs per file] = [time spent per file] / TimeBetweenEpochs
ビジー状態の NDB Cluster はバイナリログに定期的に書き込み、おそらく静かなバイナリログファイルよりも速くバイナリログファイルをローテーションします。 つまり、--ndb-log-empty-epochs=ON
を使用した 「quiet」 NDB Cluster は、実際には、多数のアクティビティーを持つものよりも、ファイルあたりの ndb_binlog_index
行数が多くなる可能性があります。
--ndb-log-orig
オプションを指定して mysqld を起動すると、orig_server_id
および orig_epoch
カラムにはそれぞれ、イベントが発生したサーバーの ID と、元のサーバーでイベントが発生したエポックが格納されます。これは、複数のソースを使用する NDB Cluster レプリケーション設定で役立ちます。 マルチソース設定 (セクション23.6.10「NDB Cluster レプリケーション: 双方向および循環レプリケーション」 を参照) でレプリカに適用されたエポックに最も近いバイナリログ位置を見つけるために使用される SELECT
ステートメントでは、インデックス付けされていないこれらの 2 つのカラムが使用されます。 特にソースが --ndb-log-empty-epochs=ON
で実行されている場合、クエリーでテーブルスキャンを実行する必要があるため、フェイルオーバーを試行するとパフォーマンスの問題が発生する可能性があります。 マルチソースのフェイルオーバー時間を改善するには、次に示すように、これらのカラムにインデックスを追加します:
ALTER TABLE mysql.ndb_binlog_index
ADD INDEX orig_lookup USING BTREE (orig_server_id, orig_epoch);
このような場合、バイナリログの位置を取得するために使用されるクエリーは orig_server_id
または orig_epoch
を使用しないため、単一のソースから単一のレプリカにレプリケートするときにこのインデックスを追加しても利点はありません。
next_position
および next_file
カラムの使用についての詳細は、セクション23.6.8「NDB Cluster レプリケーションによるフェイルオーバーの実装」を参照してください。
次の図は、NDB Cluster レプリケーションソースサーバー、バイナリログインジェクタスレッド、および mysql.ndb_binlog_index
テーブルの関係を示しています。
ndb_apply_status
という名前の追加のテーブルを使用して、ソースからレプリカにレプリケートされた操作のレコードを保持します。 ndb_binlog_index
の場合とは異なり、このテーブルのデータは (レプリカ) クラスタ内のいずれの SQL ノードにも固有ではないため、ndb_apply_status
では次に示すように NDBCLUSTER
ストレージエンジンを使用できます:
CREATE TABLE `ndb_apply_status` (
`server_id` INT(10) UNSIGNED NOT NULL,
`epoch` BIGINT(20) UNSIGNED NOT NULL,
`log_name` VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`start_pos` BIGINT(20) UNSIGNED NOT NULL,
`end_pos` BIGINT(20) UNSIGNED NOT NULL,
PRIMARY KEY (`server_id`) USING HASH
) ENGINE=NDBCLUSTER DEFAULT CHARSET=latin1;
ndb_apply_status
テーブルはレプリカにのみ移入されるため、ソースではこのテーブルに行が含まれることはありません。したがって、そこで DataMemory
を ndb_apply_status
に割り当てる必要はありません。
このテーブルはソース上で生成されたデータから移入されるため、レプリケートを許可するようにしてください。誤ってレプリカが ndb_apply_status
を更新できないようにしたり、ソースがバイナリログに書き込まれないようにしたりするレプリケーションフィルタリングまたはバイナリログフィルタリングの規則によって、クラスタ間のレプリケーションが正しく動作しなくなる可能性があります。 このようなフィルタリングルールに起因する潜在的な問題の詳細は、NDB Cluster 間のレプリケーションを使用したレプリケーションおよびバイナリログフィルタリング規則を参照してください。
ndb_binlog_index
と ndb_apply_status
のテーブルは、ユーザーによって明示的に複製されることはないため、mysql
データベースに作成されます。 これらのテーブルはどちらも NDB
バイナリログ (binlog) インジェクタスレッドによって保守されるため、通常、どちらのテーブルの作成または保守にもユーザーの介入は必要ありません。 これにより、ソース mysqld プロセスが NDB
ストレージエンジンによって実行された変更に更新されたままになります。 NDB
binlog インジェクタスレッドは NDB
ストレージエンジンから直接イベントを受け取ります。 NDB
インジェクタは、クラスタ内のすべてのデータイベントを取得する役割を担い、データを変更、挿入、または削除するすべてのイベントが ndb_binlog_index
テーブルに記録されたかを確認します。 レプリカ I/O スレッドは、ソースバイナリログからレプリカリレーログにイベントを転送します。
ndb_binlog_index
および ndb_apply_status
は自動的に作成および保守されますが、NDB Cluster をレプリケーション用に準備する最初の手順として、これらのテーブルの存在と整合性をチェックすることをお勧めします。 バイナリログに記録されたイベントデータを表示するには、ソースで mysql.ndb_binlog_index
テーブルを直接クエリーします。 これは、ソースまたはレプリカ SQL ノードのいずれかで SHOW BINLOG EVENTS
ステートメントを使用して実行することもできます。 (セクション13.7.7.2「SHOW BINLOG EVENTS ステートメント」を参照してください。)
SHOW ENGINE NDB STATUS
の出力から有効な情報を取得することもできます。
NDB
テーブルでスキーマの変更を行う場合、アプリケーションは ALTER TABLE
ステートメントを発行した MySQL クライアント接続でこのステートメントが戻るまで待ってから、更新されたテーブル定義の使用を試みます。
ndb_apply_status
テーブルがレプリカに存在しない場合は、ndb_restore によって再作成されます。
NDB Cluster レプリケーションの競合解決には、追加の mysql.ndb_replication
テーブルが存在する必要があります。 現在、このテーブルは手動で作成する必要があります。 これを行う方法については、セクション23.6.11「NDB Cluster レプリケーションの競合解決」を参照してください。