MySQL Cluster でのレプリケーションでは、複製されるクラスタとレプリケーションスレーブ (スレーブは単一のサーバーである場合やクラスタである場合があります) の両方で SQL ノードとしての役割を果たす各 MySQL Server インスタンス上の mysql
データベースの数多くの専用のテーブルを使用します。これらのテーブルは mysql_install_db スクリプトによって MySQL のインストールプロセス中に作成され、バイナリログのインデックスデータを保存するテーブルを含みます。ndb_binlog_index
テーブルは各 MySQL サーバーに対してローカルであり、クラスタ化には使用されず、MyISAM
ストレージエンジンを使用します。すなわち、これは各 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=MyISAM DEFAULT CHARSET=latin1;
このテーブルのサイズは、バイナリログファイル当たりのエポック数およびバイナリログファイル数に依存します。一般的に、バイナリログファイル当たりのエポック数は、エポックごとに作成されるバイナリログの量とバイナリログファイルのサイズに依存し、エポックが小さくなるとファイル当たりのエポックが増えます。空のエポックは、--ndb-log-empty-epochs
オプションが OFF
のときでも、ndb_binlog_index
テーブルに挿入される結果となり、ファイル当たりのエントリ数はファイルが使用中である時間の長さに依存する点に注意してください。すなわち、次のとおりです。
[number of epochs per file] = [time spent per file] / TimeBetweenEpochs
ビジーな MySQL Cluster は定期的にバイナリログに書き込み、おそらく、ビジーでない MySQL Cluster よりも頻繁にバイナリログファイルを交替します。すなわち、--ndb-log-empty-epochs=ON
である「ビジーでない」 MySQL Cluster は、大量のアクティビティーを持つ MySQL Cluster に比べて、実際にはファイル当たりの ndb_binlog_index
行数をかなり多く持つことができます。
mysqld が --ndb-log-orig
オプションで起動されると、orig_server_id
と orig_epoch
のカラムに、それぞれ、イベントが発生したサーバーの ID と、イベントが発生元のサーバーで行なったエポックが格納されます。これは、複数のマスターを使用する MySQL Cluster のレプリケーションのセットアップに役立ちます。マルチマスターのセットアップでスレーブに適用されるいちばん高いエポックにいちばん近いバイナリログの位置を検出するために使用される SELECT
ステートメントは (セクション18.6.10「MySQL Cluster レプリケーション: マルチマスターと循環レプリケーション」を参照してください)、これら 2 つのカラム (インデックス化されていません) を使用します。これにより、特にマスターが --ndb-log-empty-epochs=ON
で実行しているときに、クエリーはテーブルスキャンを実行しなければならないため、フェイルオーバーを試みるときにパフォーマンスの問題につながる可能性があります。ここで示すように、これらのカラムにインデックスを追加することで、マルチマスターのフェイルオーバー時間を改善できます。
ALTER TABLE mysql.ndb_binlog_index
ADD INDEX orig_lookup USING BTREE (orig_server_id, orig_epoch);
このインデックスを追加しても、1 つのマスターから 1 つのスレーブに複製する場合はメリットがありません。これは、このような場合にバイナリログの位置の取得に使用するクエリーは orig_server_id
または orig_epoch
を利用しないためです。
next_position
および next_file
カラムの使用についての詳細は、セクション18.6.8「MySQL Cluster レプリケーションを使用したフェイルオーバーの実装」を参照してください。
次の図は、MySQL 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
テーブルはスレーブでのみ移入されます。このことは、マスターでは、このテーブルに行は含まれないことを意味しています。このため、ここで ndb_apply_status
に割り当てられる DataMemory
または IndexMemory
を考慮する必要がありません。
このテーブルはマスターで発生したデータから移入されるため、複製は許可されます。ただし、レプリケーションのフィルタリングルールまたはバイナリログのフィルタリングルールによって、意図せずにスレーブが ndb_apply_status
を更新しなかったり、マスターがバイナリログに書き込まなかったりすると、クラスタ間のレプリケーションが正しく動作しない場合があります。このようなフィルタリングルールに起因する潜在的な問題の詳細は、MySQL Cluster 間のレプリケーションで使用する、レプリケーションおよびバイナリロギングのフィルタリングルールを参照してください。
ndb_binlog_index
と ndb_apply_status
のテーブルは、ユーザーによって明示的に複製されることはないため、mysql
データベースに作成されます。通常、これらのテーブルのどちらかを作成または維持するには、ユーザーの介入は必要ありません。ndb_binlog_index
と ndb_apply_status
の両方とも NDB
バイナリログ (binlog) のインジェクタスレッドによって維持されるためです。これにより、マスターの mysqld プロセスは、NDB
ストレージエンジンによって実行された変更への更新が維持されます。NDB
binlog インジェクタスレッドは NDB
ストレージエンジンから直接イベントを受け取ります。NDB
インジェクタは、クラスタ内のすべてのデータイベントを取得する役割を担い、データを変更、挿入、または削除するすべてのイベントが ndb_binlog_index
テーブルに記録されたかを確認します。スレーブの I/O スレッドは、マスターのバイナリログからスレーブのリレーログにイベントを転送します。
ただし、レプリケーション用に MySQL Cluster を準備する初期の段階で、これらのテーブルの存在と完全性を確認することをお勧めします。マスターで mysql.ndb_binlog_index
テーブルに直接クエリーを発行することで、バイナリログに記録されたイベントデータを参照できます。これは、レプリケーションマスターまたはスレーブの MySQL サーバーのどちらかで SHOW BINLOG EVENTS
ステートメントを使用して実現することもできます。(セクション13.7.5.3「SHOW BINLOG EVENTS 構文」を参照してください。)
SHOW ENGINE NDB STATUS
の出力から有効な情報を取得することもできます。
ndb_schema
テーブルは、NDB
テーブルに行われたスキーマの変更を追跡するために使用されます。ここで示すように定義されます。
CREATE TABLE ndb_schema (
`db` VARBINARY(63) NOT NULL,
`name` VARBINARY(63) NOT NULL,
`slock` BINARY(32) NOT NULL,
`query` BLOB NOT NULL,
`node_id` INT UNSIGNED NOT NULL,
`epoch` BIGINT UNSIGNED NOT NULL,
`id` INT UNSIGNED NOT NULL,
`version` INT UNSIGNED NOT NULL,
`type` INT UNSIGNED NOT NULL,
PRIMARY KEY USING HASH (db,name)
) ENGINE=NDB DEFAULT CHARSET=latin1;
このセクションで前に述べた 2 つのテーブルとは異なり、ndb_schema
テーブルは MySQL SHOW
ステートメントでも、INFORMATION_SCHEMA
テーブルでも参照できません。ただし、ここで示すように、ndb_show_tables の出力で参照できます。
shell> ndb_show_tables -t 2
id type state logging database schema name
4 UserTable Online Yes mysql def ndb_apply_status
5 UserTable Online Yes ndbworld def City
6 UserTable Online Yes ndbworld def Country
3 UserTable Online Yes mysql def NDB$BLOB_2_3
7 UserTable Online Yes ndbworld def CountryLanguage
2 UserTable Online Yes mysql def ndb_schema
NDBT_ProgramExit: 0 - OK
ここで示すように、mysql およびほかの MySQL クライアントアプリケーションでこのテーブルの SELECT
を発行することも可能です。
mysql> SELECT * FROM mysql.ndb_schema WHERE name='City' \G
*************************** 1. row ***************************
db: ndbworld
name: City
slock:
query: alter table City engine=ndb
node_id: 4
epoch: 0
id: 0
version: 0
type: 7
1 row in set (0.00 sec)
これは、アプリケーションのデバッグで有効となる場合があります。
NDB
テーブルでスキーマの変更を行う場合、アプリケーションは ALTER TABLE
ステートメントを発行した MySQL クライアント接続でこのステートメントが戻るまで待ってから、更新されたテーブル定義の使用を試みます。
ndb_apply_status
テーブルまたは ndb_schema
テーブルがスレーブに存在しない場合、ndb_restore は存在しないテーブル (または複数のテーブル) を再作成します (Bug #14612)。
MySQL Cluster レプリケーションの競合の解決には、追加の mysql.ndb_replication
テーブルが必要です。現在、このテーブルは手動で作成する必要があります。これを行う方法については、セクション18.6.11「MySQL Cluster レプリケーションの競合解決」を参照してください。