MySQLのマルチマスターレプリケーション

この記事では、MySQLサーバーに基づくフェイルセーフデータベースサブシステムの展開プロセスについて説明します。





読む前に、 この記事を読むことをお勧めします。



職場では、別の地域(アジア)のサイトミラーを作成するという疑問が生じました。 なぜなら パケットの通過時間は非常に長く、地理的な遠隔性が影響し、グレートチャイニーズファイアウォールもキャンセルされていないため、アジア地域にミラーを作成することにしました。 エンジンの転送に問題はありませんでした。ユーザーファイルはrsyncを介して安全に同期できますが、データベースに問題がありました。 ユーザーがアジアにオブジェクトを追加した場合はどうなりますか? このオブジェクトは、ローカルミラーのユーザーだけでなく、他のすべてのユーザーにも表示される必要があります。



MySQLクラスタリングの問題の調査を開始しました。 多くの興味深い詳細が判明しました。 たとえば、Ubuntuディストリビューターに含まれるサーバーのバージョン(テストベンチで使用)は、NDB(ネットワークデータベース)ストレージエンジンをサポートしていません。 NDBをサポートすると噂されているmysql-maxバージョン、またはmysql-clusterをインストールする必要があります。 最も興味深いのは、debパッケージがないため、バイナリまたはソースからインストールすることです。 バイナリシステムからのインストールに成功しませんでした。 古いサーバーを削除することはできませんでした(パッケージは削除され、ファイルはすべて適切な場所にあります)。 正直に2日間これを試したので、私はこのベンチャーを辞めました。 私はソースからコンパイルしようとしませんでしたが、これが最良のオプションだと思います。



マスターマスターレプリケーション



画像



一般に、研究の次の段階は複製でした。 それから私はこれが私が必要なものであることに気づきました。 中央サーバーがあり、リージョンにはそこから更新を運ぶレプリカがあります。 ただし、レプリカからの更新がメインデータベースに含まれることを確認する必要があります。 結局のところ、マスターマスターレプリケーションを行う必要があります。 つまり 最初のサーバーは2番目のサーバーのマスターになり(2番目はスレーブとして接続します)、2番目のサーバーは最初のサーバーのマスターになります(最初のサーバーはスレーブとして接続します)。 Ubuntu Server 9.10に基づいた仮想マシンで実施されたテスト



したがって、ubuntu1サーバー(192.168.0.21)、mysql config:



[mysqld]

# ,

server-id = 1



# ,

log-bin = /var/lib/mysql/mysql-bin



# ,

relay-log = /var/lib/mysql/mysql-relay-bin

relay-log-index = /var/lib/mysql/mysql-relay-bin.index

replicate-do-db = test_db

master-host=192.168.0.22 #ubuntu2

master-user=replication

master-password=password_of_user_replication

master-port=3306








2番目の場合、同様に、別のIPマスターとサーバー番号のみ。



サーバーを再起動します。 次に、ユーザー複製を作成し、複製する権利を与えます。

mysql@ubuntu1> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'replication'@'192.168.0.22' IDENTIFIED BY 'password';

mysql@ubuntu2> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'replication'@'192.168.0.21' IDENTIFIED BY 'password';








次に、スレーブをマスターにバインドする必要があります。 これは次のように行われます。

ubuntu1をマスターとしてubuntu2にバインドします。

まず、データベース内のエントリをブロックします。

mysql@ubuntu1> SET GLOBAL read_only = OFF;





詳細については、 こちらをご覧ください。



mysql@ubuntu1> show master status;

+------------------+----------+--------------+------------------+

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+------------------+----------+--------------+------------------+

| mysql-bin.000006 | 7984 | | |

+------------------+----------+--------------+------------------+

1 row in set (0,00 sec)








Fileの値とそこから位置を取り、ウィザードを接続します。

mysql@ubuntu2> slave stop; #

mysql@ubuntu2> CHANGE MASTER TO MASTER_HOST = "192.168.0.22", MASTER_USER = "replication", MASTER_PASSWORD = "password_of_user_replication", MASTER_LOG_FILE = "mysql-bin.000006", MASTER_LOG_POS = 7984;

mysql@ubuntu2> slave start;






その後、次のいずれかの方法で接続を確認できます

mysql@ubuntu2>load data from master;





どちらかを通して

mysql@ubuntu2> show slave status;





エラーがなければ、ウィザードは接続されています。

このサーバーを最初のマスターとして接続します(まったく同じように行われます)。

その結果、2つのサーバーのシステムがあり、任意のサーバーに変更を加えると、2番目のサーバーに複製されます。



マルチマスターレプリケーション



しかし、これは十分ではないように思えました。 3台目のサーバーを追加する場合はどうですか? 最初は線形トポロジについて考えました。

ubuntu1 <-> ubuntu2 <-> ubunt3およびスタートポロジーです。 しかし、悲しいかな、それは現実とはほど遠いものでした。 MySQLは、単一のスレーブが複数のマスターを持つことを許可しません。 そして、線形トポロジでは、これはubuntu2になります。 誰かが1つのスレーブを複数のマスターに結び付ける方法を知っていれば、その情報に感謝します。

星も線形にフィットせず、リングは残ります。 そして、私はしようと思いました。



画像



このスキームでは、各サーバーにはマスターが1つしかなく、リングが閉じているという事実により、更新はリング内のどこからでもすべてのサーバーに到達します。 ここで重要なのは、ウィザードが独自の更新をスレーブに送信するだけでなく 、ウィザードの更新も送信するために、my.cnf行を[mysqld]セクション追加することです。

log-slave-updates





それぞれ各サーバーの設定で。



チェックし、スキームが機能したことを嬉しく思いました。 データベースが変更されるたびに、変更は実際にサーバーの残りの部分に複製されます。



自動インクリメントフィールド



自動インクリメントフィールドを含む新しい行が異なるマスターサーバーに追加されると、競合が発生する可能性があります。 これを防ぐには、データベースサーバーでの自動インクリメントのシーケンスのステップを変更する必要があります。



異なるマスターでこれらのパラメーターの正しい(競合しない)値を選択すると、マルチマスター構成で使用されるサーバーは、レコードを挿入するときに競合しないAUTO_INCREMENT値を使用します。 たとえば、N個のマスターサーバーの場合、次の値を設定します。



たとえば、auto_increment_increment = 10およびauto_increment_offset = 3を使用すると、次のフィールド値3、13、23が生成され、10、7を使用すると、7、17、27などになります。



耐障害性



結局のところ、サーバーの1つをドロップしようとするしかありませんでした。 ubuntu2から食べ物を引き出します。 次にロードします。 なに?

ubnutu2に対するその後の変更は、問題なくubuntu3およびubuntu1に複製されます。 ただし、ubuntu2で他のサーバーに加えられた変更は複製されません。 ubuntu3のshow slave statusを見て、マスターが失われていることを確認します。

レシピとして、次のものを提供できます。

データベースサーバーを起動した後、現在のサーバーのスレーブからマスターを解き、再度バインドします。 なぜなら トポロジでは、どのサーバーにもリングスレーブが1つしかないため、タスクが簡素化されます。 アルゴリズムは次のようになります。

1. ubuntu2が電源でシャットダウンし、再び起動します

2.自宅のubuntu2:

-レプリケートされたデータベースを書き込み用にロックしますmysql@ubuntu2> SET GLOBAL read_only = OFF;





-ログの名前と位置を確認しますmysql@ubuntu2> show master status;





2. mysqlを介してクライアントがスレーブ(ubuntu3)にログオンするubuntu2

-スレーブmysql@ubuntu3> slave stop;



から自身をmysql@ubuntu3> slave stop;





-自分自身をマスターとして宣言します: mysql@ubuntu3> CHANGE MASTER TO MASTER_HOST = "192.168.0.22", MASTER_USER = "replication", MASTER_PASSWORD = "password_of_user_replication", MASTER_LOG_FILE = "mysql-bin.000006", MASTER_LOG_POS = 5161;



前の手順で取得したログ名と位置を使用します。

-スレーブを再度バインドします: mysql@ubuntu3> slave start;





このスクリプトの実装の準備はできていませんが、perl / php / python / bashで何を書くかを考えます...

このトピックに関するhabrasocietyの考えを聞いてうれしいです。 記事が有用であることが判明した場合は、まだクラスタリングに対処し、クラスター複製を行う計画を書いてください。



All Articles