web-dev-qa-db-ja.com

MySQL Clusterを使用したマスター-マスターレプリケーション-両方向の重複書き込み

2つのMySQL Clusterを作成しました。各クラスターは、地理的に離れた場所にあります。これらのクラスターをマスター-マスター、地理的レプリケーションの方法で設定したので、各データセンターの2つのSQLノード(2つのクラスター間で合計4つのSQLノード)にデータを書き込むことができ、データは両方に作成されますクラスタは、データがどこから挿入されたかには関係ありません。

すべてのSQLノードでマスター機能とスレーブ機能の両方を有効にした後に見られる問題は、1つのクラスターでデータを作成すると、作成されたデータが他のクラスターに2回書き込まれることです。

例えば:

_[sql_node_1_in_cluster_1] mysql> insert into numbers values (3,30),(4,40);
[sql_node_1_in_cluster_1] mysql> select * from numbers order by num1;
+------+------+
| num1 | num2 |
+------+------+
|    1 |   10 |
|    2 |   20 |
|    3 |   30 |
|    4 |   40 |
+------+------+
4 rows in set (0.00 sec)
_

このデータは最初のMySQL Clusterから期待どおりに見えますが、他のデータベースクラスターでクエリを実行すると、次のようになります。

_[sql_node_1_in_cluster_2] mysql> select * from numbers order by num1;
+------+------+
| num1 | num2 |
+------+------+
|    1 |   10 |
|    2 |   20 |
|    3 |   30 |
|    3 |   30 |
|    4 |   40 |
|    4 |   40 |
+------+------+
6 rows in set (0.01 sec)
_

2番目のクラスターから挿入を実行した場合の結果も同様です。最初に書き込まれたデータベース(マスター)から新しいデータをクエリすると正常に見えますが、他のクラスターからデータをクエリすると、データが2回書き込まれたことがわかります。

レプリケーションのセットアップ方法:

各データセンターでMySQL Clusterを作成した後、_log-bin_を有効にして、各SQLノードに各SQLノードの_server-id_ファイルで一意の_my.cnf_を指定しました。次に、各SQLノードからレプリケーションスレーブを許可します。データセンター1のSQL Node 1からデータセンター2のSQL Node 1へのレプリケーションスレーブを許可することになりました。その後、データセンターのSQL Node 1からレプリケーションスレーブを許可しました。 2 to SQL Node 1 in Data Center1。これにより、両方のSQLノードが互いにスレーブとして機能します。これと同じ方法が、各MySQL ClusterのSQL Node 2に対して実行されました。次に、各SQLノードのマスターを次のように変更しました。

最初の双方向レプリケーションチャネルの例:

データセンター1のSQL Node 1:

_[sql_node_1_in_cluster_1] mysql> CHANGE MASTER TO
-> MASTER_Host = 'sqlnode1_cluster2',
-> MASTER_USER = 'rep1',
-> MASTER_PASSWORD = 'password',
-> MASTER_LOG_FILE = 'sqlnode1_cluster2-bin.000007',
-> MASTER_LOG_POS = 120;
Query OK, 0 rows affected, 2 warnings (0.02 sec)

[sql_node_1_in_cluster_1] mysql> start slave;
_

データセンター2のSQL Node 1:

_[sql_node_1_in_cluster_2] mysql> CHANGE MASTER TO
-> MASTER_Host = 'sqlnode1_cluster1',
-> MASTER_USER = 'rep1',
-> MASTER_PASSWORD = 'password',
-> MASTER_LOG_FILE = 'sqlnode1_cluster1-bin.000007',
-> MASTER_LOG_POS = 120;
Query OK, 0 rows affected, 2 warnings (0.02 sec)

[sql_node_1_in_cluster_2] mysql> start slave;
_

これと同じプロセスが、各データセンターの2番目のSQLノードに対して完了しました。その結果、各SQLノードが互いにマスターおよびスレーブになることを期待しています。各クラスターのSQL Node 1は最初の双方向レプリケーションチャネルを作成し、SQL Node 2は各クラスターは、2番目の双方向レプリケーションチャネルを作成します。

_show slave status\G;_の出力は、各スレーブとそれぞれのマスターにとって私にはよく見えます。各スレーブはマスターのログファイルと位置を確認します。

SQL Node 1、クラスター2

_[sql_node_1_in_cluster_2] mysql> show master status;
+------------------------------+----------+--------------+------------------+-------------------+
| File                         | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------------------+----------+--------------+------------------+-------------------+
| sqlnode1_cluster2-bin.000011 |     8868 |              |                  |                   |
+------------------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)
_

SQL Node 1、クラスター1

_[sql_node_1_in_cluster_1] mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: sqlnode1_cluster2
                  Master_User: rep1
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: sqlnode1_cluster2-bin.000011
          Read_Master_Log_Pos: 8868
               Relay_Log_File: sqlnode1_cluster1-relay-bin.000002
                Relay_Log_Pos: 295
        Relay_Master_Log_File: sqlnode1_cluster2-bin.000011
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 8868
              Relay_Log_Space: 475
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 11
                  Master_UUID: 2ac24025-84ae-11e5-becf-0050568daf33
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
1 row in set (0.00 sec)

ERROR: 
No query specified
_

手元の問題を繰り返しますが、1つのクラスターでデータを作成すると、もう1つのクラスターでtwiceが作成されます。なぜこれが起こっているのかについて誰かが何か提案はありますか?

2
Chris Telinde

問題は、SQLでスレーブを有効にすることにありますNode 2各データセンターで。MySQLClusterは、 ドキュメントページの最初の図にあるように、マルチマスターレプリケーションをサポートしています。 。各クラスターのSQLノードが1つだけ循環レプリケーショントポロジに参加していることに注意してください。

そして、重複した問題は、このページからの引用で参照されています 2つのレプリケーションチャネルの設定 、私の強調:

警告この時点では、プライマリチャネルのみが開始されます。セクション18.6.8「MySQL Clusterレプリケーションによるフェイルオーバーの実装」で説明されているように、プライマリレプリケーションチャネルが失敗した場合にのみ、セカンダリレプリケーションチャネルが開始されます。 複数のレプリケーションチャネルを同時に実行すると、レプリケーションスレーブで不要な重複レコードが作成される可能性があります。

最後に、複数のMySQL Cluster間でmaster-masterを有効にすることについて警告します。この方法でのレプリケーションは依然として非同期です。つまり、ある時点で、2つのクラスター間でレプリケーションの問題が発生します。

2
Derek Downey