Mysql

MySQL 集群的主-主複製——雙向重複寫入

  • December 4, 2015

我創建了 2 個 MySQL 集群;每個集群都位於一個單獨的地理位置。我已經以 Master-Master 地理複製方式設置了這些集群,以便可以將數據寫入每個數據中心中的 2 個 SQL 節點中的任何一個(兩個集群之間總共有 4 個 SQL 節點),並且將在兩者中創建數據集群,無論數據是從哪裡插入的。

在所有 SQL 節點上啟用主從功能後,我看到的問題是,當我在一個集群中創建數據時,創建的數據會兩次寫入另一個集群。

例如:

[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 集群的預期一致,但是當我在另一個數據庫集群中執行查詢時,我看到:

[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)

如果我從第二個集群插入,結果是相似的;當我從最初寫入的數據庫(master)中查詢新數據時,它看起來很正常,但是當我從另一個集群中查詢數據時,我看到數據被寫入了兩次。

設置複製的方法:

在每個數據中心創建 MySQL 集群後,我啟用log-binserver-id在每個 SQL 節點的my.cnf文件中為每個 SQL 節點賦予一個唯一性。然後我從每個 SQL 節點授予複製從屬。我最終將數據中心 1 中的 SQL 節點 1 的複制從屬節點授予數據中心 2 中的 SQL 節點 1,然後繼續將數據中心 2 中的 SQL 節點 1 的複制從屬節點授予數據中心 1 中的 SQL 節點 1。這樣,兩個 SQL 節點都充當彼此的奴隸。對每個 MySQL 集群中的 SQL 節點 2 執行相同的方法。然後我繼續更改每個 SQL 節點上的主節點,如下所示:

第一個雙向複製通道的範例:

數據中心 1 中的 SQL 節點 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 節點 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;

每個數據中心的第二個 SQL 節點完成了相同的過程。因此,我希望每個 SQL 節點成為彼此的主節點和從節點,每個集群中的 SQL 節點 1 構成第一個雙向複製通道,每個集群中的 SQL 節點 2 構成第二個雙向複製通道複製通道。

show slave status\G;對於每個從站及其各自的主站,我的輸出看起來都不錯,每個從站都在查看主站的日誌文件和位置:

SQL 節點 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 節點 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

重申手頭的問題,當我在一個集群中創建數據時,它會在另一個集群中創建兩次。有人對為什麼會發生這種情況有任何建議嗎?

問題在於在每個數據中心的 SQL 節點 2 上啟用從屬伺服器。MySQL Cluster 確實支持多主複製,如文件頁面上的第一張圖所示。請注意每個集群中只有一個 SQL 節點如何參與循環複製拓撲。

並且在此頁面的引用中引用了重複問題,關於設置兩個複制通道,強調我的:

警告此時僅啟動主通道。僅在主複製通道發生故障時才啟動輔助複製通道,如第 18.6.8 節,“使用 MySQL 集群複製實現故障轉移”中所述。同時執行多個複制通道可能會導致在複製從站上創建不需要的重複記錄。

最後,我會提醒您在多個 MySQL 集群之間啟用 master-master。這種方式的複制仍然是非同步的,這意味著在某些時候你會遇到兩個集群之間的複制問題。

引用自:https://dba.stackexchange.com/questions/120654