MySQL 組複製實現了基於複製協議的多主更新(單主模式)。 複製組由多個 server成員構成,並且組中的每個 server 成員可以獨立地執行事務。但所有讀寫(RW)事務只有在衝突檢測成功後才會提交。只讀(RO)事務不需要在衝突檢測,可以立即提交。 對於任何 RW 事務,提交操作並不是由始發 s ...
MySQL Group Replication簡述
MySQL 組複製實現了基於複製協議的多主更新(單主模式)。
複製組由多個 server成員構成,並且組中的每個 server 成員可以獨立地執行事務。但所有讀寫(RW)事務只有在衝突檢測成功後才會提交。只讀(RO)事務不需要在衝突檢測,可以立即提交。
對於任何 RW 事務,提交操作並不是由始發 server 單向決定的,而是由組來決定是否提交。準確地說,在始發 server 上,當事務準備好提交時,該 server 會廣播寫入值(已改變的行)和對應的寫入集(已更新的行的唯一標識符)。然後會為該事務建立一個全局的順序。最終,這意味著所有 server 成員以相同的順序接收同一組事務。因此,所有 server 成員以相同的順序應用相同的更改,以確保組內一致。
組複製使您能夠根據在一組 server 中複製系統的狀態來創建具有冗餘的容錯系統。因此,只要它不是全部或多數 server 發生故障,即使有一些 server 故障,系統仍然可用,最多只是性能和可伸縮性降低,但它仍然可用。server 故障是孤立並且獨立的。它們由組成員服務來監控,組成員服務依賴於分散式故障檢測系統,其能夠在任何 server 自願地或由於意外停止而離開組時發出信號。
他們是由一個分散式恢復程式來確保當有 server 加入組時,它們會自動更新組信息到最新。並且多主更新確保了即使在單個伺服器故障的情況下也不會阻止更新,不必進行 server故障轉移。因此,MySQL 組複製保證資料庫服務持續可用。
值得註意的一點是,儘管資料庫服務可用,但當有一個 server 崩潰時,連接到它的客戶端必須定向或故障轉移到不同的 server。 這不是組複製要解決的問題。連接器,負載均衡器,路由器或其他形式的中間件更適合處理這個問題。MySQL 組複製提供了高可用性,高彈性,可靠的 MySQL 服務。 MySQL組複製的一些限制:
1 不支持XA事務
2 表需要有主鍵
3 採用GTID+binlog的方式進行複製
4 只支持IPV4的網路
5 網路性能對於集群影響很大 ,需要低延遲,高帶寬
6 多主不支持同一對象但是不同實例的併發的DDL+DML混合操作
7 不支持串列化操作 不支持RR模式的間隙鎖,最好採用RC模式配合組複製
8 多主不支持外鍵約束
9 不支持事務保存點
10 集群性能取決於最差的硬體機器,所以推薦所有硬體統一配置
11 mysqldump無法備份GR實例
12 目前集群限制最多允許9個節點。
以上參考了網路上一些博客,原理的東西網上東西還是很多的,大家可以自行百度。
關於組複製的一些詳細加強,可以看一下我們星耀隊的譯文MySQL 8.0.2複製新特性(翻譯)
1:安裝環境
機器 | IP |
---|---|
SERVER1 | 10.103.16.31 |
SERVER2 | 10.103.16.34 |
SERVER3 | 10.103.16.35 |
MySQL的版本是5.7.20,我們先在三台主機安裝好MySQL並且啟動,詳細安裝參考MySQL5.7.20編譯安裝,基本環境搭建完成以後我們來看一下MySQL Group Replication的配置
2:配置安裝MySQL Group Replication
我們現在三台機器上已經配置好了三台MySQL服務,我們要在我們當前配置文件的基礎上加上GR的一些參數,我們以SERVER1為例:
binlog_checksum = NONE #MGR本身不支持binlog的checksum校驗 transaction_write_set_extraction = XXHASH64 loose-group_replication_group_name = "00e575aa-0cc0-11e8-9186-0050569341db" # 組名,此處可拿select uuid();生成 loose-group_replication_start_on_boot = off # 在mysqld啟動時不自動啟動組複製 loose-group_replication_local_address = "10.103.16.31:24901" loose-group_replication_group_seeds = "10.103.16.34:24901,10.103.16.35:24901,10.103.16.31:24901" loose-group_replication_bootstrap_group = off
我們之前已經加過一些必須的參數了,我們看看GR需要的其他參數:
gtid-mode=on enforce_gtid_consistency = ON #GTID模式是組複製的基礎技術 master_info_repository = TABLE relay_log_info_repository = TABLE #管理複製的元數據和恢復用,記錄同步的信息,便於管理和恢復 log-bin=row #必須是ROW格式 log_slave_updates = ON #需要記錄事務的binlog,用作以後的恢復用,哪怕不是寫入點,也需要
接下來我們要創建GR所使用的賬號:
set sql_log_bin=0; GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repl'@'%' IDENTIFIED BY '123456'; flush privileges; set sql_log_bin=1;
我們先在主庫執行:
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='123456' FOR CHANNEL 'group_replication_recovery'; INSTALL PLUGIN group_replication SONAME 'group_replication.so'; set global group_replication_allow_local_disjoint_gtids_join=ON; START GROUP_REPLICATION;
然後在SERVER2,和server3上執行:
INSTALL PLUGIN group_replication SONAME 'group_replication.so'; START GROUP_REPLICATION;
然後去看一下節點:
mysql> select * from performance_schema.replication_group_members; ERROR 2006 (HY000): MySQL server has gone away No connection. Trying to reconnect... Connection id: 145 Current database: mxq +---------------------------+--------------------------------------+-------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+-------------+-------------+--------------+ | group_replication_applier | 096769f1-de4e-11e7-bc85-0050569355e1 | sdw1 | 3306 | ONLINE | | group_replication_applier | 6899e4bf-de91-11e7-a3bb-005056930bed | sdw2 | 3306 | ONLINE | | group_replication_applier | c6b0f3b3-de40-11e7-9dbd-0050569341db | mdw | 3306 | ONLINE | +---------------------------+--------------------------------------+-------------+-------------+--------------+ 3 rows in set (0.00 sec)
我們可以通過查看MEMBER_STATE來確認節點的狀態:
online
offline 離線
recoving 恢復中
unreachable 不可到達,查看錯誤日誌
error 同步發生錯誤,查看錯誤日誌
查看一下主節點是那個:
mysql> SELECT b.member_id, b.member_host, b.member_port FROM performance_schema.global_status a JOIN performance_schema.replication_group_members b -> ON a.variable_value = b.member_id WHERE a.variable_name= 'group_replication_primary_member'; +--------------------------------------+-------------+-------------+ | member_id | member_host | member_port | +--------------------------------------+-------------+-------------+ | c6b0f3b3-de40-11e7-9dbd-0050569341db | mdw | 3306 | +--------------------------------------+-------------+-------------+ 1 row in set (0.00 sec)
我們可以看到現在主節點是SERVER1,GR當中所有的從節點都是預設為read_only的。我們也可以通過以下系統表來檢測GR的信息:
mysql> select * from performance_schema.replication_group_member_stats\G *************************** 1. row *************************** CHANNEL_NAME: group_replication_applier VIEW_ID: 15181587863063562:15 MEMBER_ID: c6b0f3b3-de40-11e7-9dbd-0050569341db COUNT_TRANSACTIONS_IN_QUEUE: 0 COUNT_TRANSACTIONS_CHECKED: 0 COUNT_CONFLICTS_DETECTED: 0 COUNT_TRANSACTIONS_ROWS_VALIDATING: 0 TRANSACTIONS_COMMITTED_ALL_MEMBERS: 00e575aa-0cc0-11e8-9186-0050569341db:1-17 LAST_CONFLICT_FREE_TRANSACTION: 1 row in set (0.00 sec)
我們可以看到現在的三台機器是單主模式的,我們把他修改為多主模式的話怎麼改呢,但是我們強烈建議不要使用多主模式 ,因為多主模式下很容易hang住整個集群,而且很多的限制都是限制多主模式,如果我們要把單主修改為多主,只用做如下操作就好:
SERVER2,SERVER3:
STOP GROUP_REPLICATION; SET GLOBAL group_replication_single_primary_mode=FALSE; SET GLOBAL group_replication_enforce_update_everywhere_checks=TRUE;
SERVER1:
STOP GROUP_REPLICATION; SET GLOBAL group_replication_single_primary_mode=FALSE; SET GLOBAL group_replication_enforce_update_everywhere_checks=TRUE; SET GLOBAL group_replication_bootstrap_group=on; START GROUP_REPLICATION; SET GLOBAL group_replication_bootstrap_group=off;
然後SERVER2,SERVER3:
SET GLOBAL group_replication_bootstrap_group=on; START GROUP_REPLICATION; SET GLOBAL group_replication_bootstrap_group=off;
我們在查看一下節點信息:
mysql> select * from performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+-------------+-------------+--------------+ | group_replication_applier | 096769f1-de4e-11e7-bc85-0050569355e1 | sdw1 | 3306 | ONLINE | | group_replication_applier | 6899e4bf-de91-11e7-a3bb-005056930bed | sdw2 | 3306 | ONLINE | | group_replication_applier | c6b0f3b3-de40-11e7-9dbd-0050569341db | mdw | 3306 | ONLINE | +---------------------------+--------------------------------------+-------------+-------------+--------------+ 3 rows in set (0.00 sec)
發現三個節點已經全部OK了,做一下測試:
SERVER1:
mysql> use mxq; Database changed mysql> create table gr(id int ,name varchar(10),primary key(id)); Query OK, 0 rows affected (0.06 sec) mysql> insert into gr(1,'a'); ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1,'a')' at line 1 mysql> insert into gr values(1,'a'); Query OK, 1 row affected (0.05 sec)
SERVER2:
mysql> insert into gr values(2,'a'); Query OK, 1 row affected (0.01 sec)
SERVER3:
mysql> insert into gr values(3,'a'); Query OK, 1 row affected (0.04 sec)
然後查看數據:
mysql> select * from gr; +----+------+ | id | name | +----+------+ | 1 | a | | 2 | a | | 3 | a | +----+------+ 3 rows in set (0.00 sec)
這樣就OK了。