スマートスタイル TECH BLOG

データベース&クラウド技術情報

MySQL NDB Clustrer to InnoDBレプリケーション環境を構築してみた

MySQL NDB Clusterでも、通常のMySQL同様にレプリケーションを組む事ができます。

MySQL NDB Clusterをマスターに、InnoDBエンジンを使用したMySQLをスレーブにした構成も、Oracle社ではサポートされています。

今回は、上記の構成での構築手順をご紹介します。

VM環境

HOST名 IP 用途
mgm 192.168.33.230 管理ノード
data1 192.168.33.231 データノード
data2 192.168.33.232 データノード
sql1 192.168.33.233 SQLノード
sql2 192.168.33.234 SQLノード
slave 192.168.33.235 InnoDBスレーブ

OS

CentOS 7.3

MySQL NDB Clusterバージョン

7.5.8

管理/データノードのデータディレクトリ

/var/lib/mysql-cluster

SQLノード/InnoDBスレーブのデータディレクトリ

/var/lib/mysql

以下のVagrantfileを使用することで上記環境が作成されます。

Vagrantfile一式
※多数のyumを実行しますので、Network通信にご注意ください。

vagrantについては説明を割愛しますので、公式をご確認ください。

MySQL NDB Cluster起動については以下を参考に行います。

21.2.5 Initial Startup of NDB Cluster

MySQL NDB Cluster、スレーブサーバの全ノードが正常に起動している事を前提とします。

マスター側のレプリケーション準備

SQLノードの/etc/my.cnfには以下の設定を追記します。

重要なのはndb_log_update_as_writeです。
MySQL NDB Clusterはそのアーキテクチャ上、UPDATEを”WRITE”としてバイナリログに書き込みますが、 InnoDBでは”WRITE”を解釈することができず、レプリケーションエラーとなります。
そのため、UPDATE操作はUPDATEとして書き出すように設定を行います。

※設定後はmysqldの再起動を実施

レプリケーションのためのユーザーを作成します。
もし、複数のSQLノードをマスターとする可能性がある場合は、全てのSQLノードにユーザーを作成してください。

マスターにテストデータを作成します。
いずれかのSQLノードで一度実行して下さい。

マスター側でバックアップを取得

データ自体のバックアップは、MySQL NDB Clusterネイティブのバックアップを使用します。
以下は管理ノードで実行します。

後述するレプリケーションの開始のために、StopGCPの値が必要となりますので、
控えておいてください。

バックアップはデフォルトでは各データノードの<データディレクトリ>/BACKUP配下に出力されます。
出力されたバックアップはデータノードごとに水平分割されたデータが含まれています。
この事より、全データノード分のバックアップが必要です。

また、スレーブ側では一部の構造を変更する必要がありますので、メタデータのみのバックアップを、mysqldumpで取得します。

いずれかのSQLノードで実行します。

データバックアップをInnoDBへリストアするための準備

MySQL NDB ClusterのネイティブバックアップはそのままInnoDBのテーブルにリストアすることはできません。
幾つかのリストア方法が考えられますが、ここではndb_restoreコマンドを使用して一度TSVに書き出した後、LOAD DATA INFILE文でデータをリストアする方法をご紹介します。

まずは、スレーブサーバに全てのバックアップを集約します。
バックアップファイルには、各データノードのNodeIdが付いているため、上書きされる心配はありません。

スレーブサーバで以下のようにTSVファイルを作成します。

上記の操作により、tab-files配下にTSVが出力されます。

そして、もう一つ行わなければならない作業がバックアップ中の更新処理によって出力されたREDOログの適用です。
こちらは、ndb_restoreコマンドにより、SQLとして出力することができます。

※バックアップ中に更新がなかった場合は出力されません。

今回はデータ量も少ないため、こちらの操作は行いませんでした。

また、MySQL NDB Clusterにはmysql.ndb_apply_statusという、マスターからのレプリケーション操作を記録するためのテーブルがありますが、 このテーブルは管理ノードに接続した際に作成されるものであるため、InnoDBのスレーブには存在しません。
ですので、手動で作成します。

※ndb_apply_statusはもともとndbclusterエンジンですので、innodbに変更します。

スレーブの設定

以下のパラメータを追記します。

ndb_index%から始まるテーブルは、ndbclusterエンジンにおけるインデックスの統計情報が格納されますが、それ以外のエンジンを使用する場合は不要ですので除外します。

また、MySQL NDB Clusterでは通常エラーが発生するようなINSERT時のユニークキーの重複をエラーにせずに同じキーのデータを上書きするという動作となっていますので、スレーブでも追随する必要があります。
そのためslave_exec_mode=IDEMPOTENTを設定しなければなりません。

また、innodb-page-sizeを32Kにすることが推奨されます。
inndb_page_sizeはデータディレクトリの初期化時に指定する必要があります。
ndbclusterとinnodbで行の最大長が異なり、ndbclusterでは14K、innodbではデフォルトは8Kであるためサイズの大きい行のレプリケーション時にエラーとなる可能性があります。
ただし、innodb_page_sizeを変更するとテーブル圧縮が使用できなくなるため、ご注意ください。

スレーブ側でスキーマ作成

metadata.sqlをスレーブサーバに配置し、スキーマを作成します。

スレーブサーバがInnoDBである場合、スレーブ側でのユニークキーや外部キーの使用はレプリケーションエラーの原因となりやすく、推奨されません。
そのため、スレーブでは一度メタデータをリストアした後、ユニークキー、外部キーを削除し、一意性やリレーションについては、マスター側で担保します。
そして必要に応じてインデックスの貼り直しを行います。
InnoDB側では実行されるクエリに合わせて、インデックス構成を変更してもよいでしょう。

外部キーに関連しますが、MySQL NDB ClusterとInnoDBのレプリケーションではon update/delete cascade はレプリケーションされないため、サポートされませんのでご注意ください。

リストアの実行

すでにスキーマはリストアしましたので、LOAD DATA IN FILEでデータをリストアします。

そして、バックアップ中にデータ更新があった場合は、SQLファイルを実行します。

これでバックアップ時点までのデータが格納されたスレーブサーバができました。
以降、レプリケーションの設定を行います。

バイナリログのポジションを取得

スレーブサーバでレプリケーションを開始するためにはbinlogのpositionが必要です。
そのため、マスターにてバックアップを取得した時点のGCPを元にpositionを取得します。
なお、バックアップ以降全く更新がない場合は、以下SQLでポジションが表示されません。
ここではテストデータを再度投入します。

スレーブでレプリケーションを開始

あとは通常のレプリケーション同様にCHANGE MASTERでマスターの情報を登録し、slaveを開始します。

レプリケーションの正常性確認

正常にレプリケーションされる事をご確認ください。

以上でレプリケーション環境の作成ができました。
ndbclusterエンジンが不得手とするJOINの高速化、バックアップ用DB等、InnoDBによるスレーブの用途は多岐に渡ります。
MySQL NDB Clusterでのレプリケーションでお困りの際にはぜひご検討ください。


MySQL

 

Return Top