一、主動模式的Master-Master(Master-Master in Active-Active Mode)

Master-Master複製的兩台伺服器,既是master,又是另一台伺服器的slave。如圖: mmaam
主動的Master-Master複製有一些特殊的用處。例如,地理上分佈的兩個部分都需要自己的可寫的資料副本。這種結構最大的問題就是更新衝突。假設一個表只有一行(一列)的資料,其值為1,如果兩個伺服器分別同時執行如下語句: 在第一個伺服器上執行:

mysql> UPDATE tbl SET col=col + 1;

在第二個伺服器上執行:

mysql> UPDATE tbl SET col=col * 2;

那麼結果是多少呢?一台伺服器是4,另一個伺服器是3,但是,這並不會產生錯誤。
實際上,MySQL並不支持其他一些DBMS支持的多主伺服器複製(Multimaster Replication),這是MySQL的複製功能很大的一個限制(多主伺服器的難點在於解決更新衝突),但是,如果你實在有這種需求,你可以採用MySQL Cluster,以及將Cluster和Replication結合起來,可以建立強大的高性能的資料庫平臺。但是,可以通過其他一些方式來類比這種多主伺服器的複製。

二、主動-被動模式的Master-Master(Master-Master in Active-Passive Mode)

這是master-master結構變化而來的,它避免了M-M的缺點,實際上,這是一種具有容錯和高可用性的系統。它的不同點在於其中一個服務只能進行唯讀操作。如圖:
mmapm
環境:
32位 Windows 2003 SP2 + MariaDB 5.3.12
32位 Debian6 + MariaDB 5.3.12
參考配置:

1
2
3
4
5
6
7
8
9
10
11
lower_case_table_names=1 #由於Linux大小寫敏感,另外需配置強制小寫 # Replication 配置 server-id=187186 #auto_increment_offset=2 #auto_increment_increment=2 log-bin=mysql-bin log-error=mysql-bin.err binlog_do_db=td_oa #主複製的庫 # Slave配置 report_host=esxi187oa master-host=213 master-port=3306 master-user=_[mysql_user]_ master-password=_[mysql_pwd]_ replicate-do-db=td_oa replicate-ignore-db=mysql #忽略系統庫 replicate-ignore-table=td_oa.user_online,td_oa.version #忽略特殊表 master-connect-retry=60

從伺服器狀態說明(SHOW SLAVE STATUS \G):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Slave_IO_State: Waiting for master to send event # IO的線程的狀態 Master_Host: 255 # 鏈結主伺服器的IP Master_User: mark # 主伺服器用戶名 Master_Port: 3306 # 主伺服器埠 Connect_Retry: 60 # 主從斷開後,多少秒重新鏈結 Master_Log_File: mysql-bin.000004 # 從伺服器I/O 線程當前讀取的主伺服器二進位日誌檔的名字 Read_Master_Log_Pos: 190 # 從伺服器I/O 線程從當前的主伺服器二進位日誌中讀取的位置起點。 Relay_Log_File: mysqld-relay-relay-bin.000002 # 從伺服器SQL 線程當前讀取並執行的中繼日誌檔的名字 Relay_Log_Pos: 336 # 從伺服器SQL 線程當前從中繼日誌中讀取執行的位置起點。 Relay_Master_Log_File: mysql-bin.000004 # 從伺服器中的SQL進程中正在執行的語句的位置 Slave_IO_Running: Yes # 從伺服器的IO線程運行是否開啟 Slave_SQL_Running: Yes # 從伺服器的SQL線程運行是否開啟 Replicate_Do_DB: td_oa # 主從複製的資料庫名 Replicate_Ignore_DB: mysql # 主從不需要複製的資料庫名 Replicate_Do_Table: # 主從複製的表 Replicate_Ignore_Table: td_oa.user_online,td_oa.version # 主從不需要複製的表 Replicate_Wild_Do_Table: # 可以跨庫複製的表 Replicate_Wild_Ignore_Table: # 不能跨庫複製的表 Last_Errno: 0 # 最後複製的錯誤號...0表示沒有錯誤 Last_Error: # 最後複製的錯誤資訊 Skip_Counter: 0 # 最近被使用的用於SQL_SLAVE_SKIP_COUNTER的值。(這個值表示跳過多少個事件在來執行SQL) Exec_Master_Log_Pos: 190 # SQL線程執行到主伺服器log-bin檔的位置.如果這個值與Read_Master_Log_Pos一樣.則可以證明 Relay_Log_Space: 492 # 所有原有的中繼日誌結合起來的總大小。 Until_Condition: None # 在START SLAVE語句的UNTIL子句中指定的值 Until_Log_File: # 在START SLAVE語句的UNTIL子句中指定的值 Until_Log_Pos: 0 # 在START SLAVE語句的UNTIL子句中指定的值 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 # 本欄位是從屬伺服器“落後”多少的一個指示。當從屬SQL線程正在運行時(處理更新), # 本欄位為在主伺服器上由此線程執行的最近的一個事件的時間標記開始,已經過的秒數。 # 當此線程被從屬伺服器I/O線程趕上,並進入閒置狀態,等待來自I/O線程的更多的事件時,本欄位為零。 # 總之,本欄位測量從屬伺服器SQL線程和從屬伺服器I/O線程之間的時間差距,單位以秒計。 # 如果主伺服器和從屬伺服器之間的網路連接較快,則從屬伺服器I/O線程會非常接近主伺服器, # 所以本欄位能夠十分近似地指示,從屬伺服器SQL線程比主伺服器落後多少。 # 如果網路較慢,則這種指示不準確;從屬SQL線程經常會趕上讀取速度較慢地從屬伺服器I/O線程, # 因此,Seconds_Behind_Master經常顯示值為0。即使I/O線程落後于主伺服器時,也是如此。 # 換句話說,本列只對速度快的網路有用。 # 即使主伺服器和從屬伺服器不具有相同的時鐘,時間差計算也會起作用(當從屬伺服器I/O線程啟動時,計算 # 時間差。並假定從此時以後,時間差保持不變)。 # 如果從屬SQL線程不運行,或者如果從屬伺服器I/O線程不運行或未與主伺服器連接, # 則Seconds_Behind_Master為NULL(意義為“未知”)。 # 舉例說明,如果在重新連接之前,從屬伺服器I/O線程休眠了master-connect-retry秒,則顯示NULL, # 因為從屬伺服器不知道主伺服器正在做什麼,也不能有把握地說落後多少。 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: