MySQL 組複製實現了基於複製協議的多主更新(單主模式)。html
複製組由多個 server成員構成,而且組中的每一個 server 成員能夠獨立地執行事務。但全部讀寫(RW)事務只有在衝突檢測成功後纔會提交。只讀(RO)事務不須要在衝突檢測,能夠當即提交。mysql
對於任何 RW 事務,提交操做並非由始發 server 單向決定的,而是由組來決定是否提交。準確地說,在始發 server 上,當事務準備好提交時,該 server 會廣播寫入值(已改變的行)和對應的寫入集(已更新的行的惟一標識符)。而後會爲該事務創建一個全局的順序。最終,這意味着全部 server 成員以相同的順序接收同一組事務。所以,全部 server 成員以相同的順序應用相同的更改,以確保組內一致。sql
組複製使您可以根據在一組 server 中複製系統的狀態來建立具備冗餘的容錯系統。所以,只要它不是所有或多數 server 發生故障,即便有一些 server 故障,系統仍然可用,最多隻是性能和可伸縮性下降,但它仍然可用。server 故障是孤立而且獨立的。它們由組成員服務來監控,組成員服務依賴於分佈式故障檢測系統,其可以在任何 server 自願地或因爲意外中止而離開組時發出信號。數據庫
他們是由一個分佈式恢復程序來確保當有 server 加入組時,它們會自動更新組信息到最新。而且多主更新確保了即便在單個服務器故障的狀況下也不會阻止更新,沒必要進行 server故障轉移。所以,MySQL 組複製保證數據庫服務持續可用。bootstrap
值得注意的一點是,儘管數據庫服務可用,但當有一個 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複製新特性(翻譯)併發
機器 | IP |
---|---|
SERVER1 | 172.16.16.31 |
SERVER2 | 172.16.16.34 |
SERVER3 | 172.16.16.35 |
MySQL的版本是5.7.20,咱們先在三臺主機安裝好MySQL而且啓動,詳細安裝參考MySQL5.7.20編譯安裝,基本環境搭建完成之後咱們來看一下MySQL Group Replication的配置app
咱們如今三臺機器上已經配置好了三臺MySQL服務,咱們要在咱們當前配置文件的基礎上加上GR的一些參數,咱們以SERVER1爲例:負載均衡
# GR 配置項 其中loose前綴表示若Group Replication plugin未加載 mysql server仍繼續啓動 binlog_checksum=NONE #MGR自己不支持binlog的checksum校驗 transaction_write_set_extraction=XXHASH64 group_replication_group_name="00e575aa-0cc0-11e8-9186-0050569341db" # 組名 group_replication_start_on_boot=off # 在mysqld啓動時不自動啓動組複製 group_replication_local_address="172.16.16.35:24901" group_replication_group_seeds="172.16.16.34:24901,172.16.16.35:24901,172.16.16.31:24901" 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:
START GROUP_REPLICATION;
咱們在查看一下節點信息:
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了。
SERVER2,SERVER3:
STOP GROUP_REPLICATION; SET GLOBAL group_replication_enforce_update_everywhere_checks=OFF; SET GLOBAL group_replication_single_primary_mode=TRUE;
SERVER1:
STOP GROUP_REPLICATION; SET GLOBAL group_replication_enforce_update_everywhere_checks=OFF; SET GLOBAL group_replication_single_primary_mode=TRUE; SET GLOBAL group_replication_bootstrap_group=on; START GROUP_REPLICATION; SET GLOBAL group_replication_bootstrap_group=off;
而後SERVER2,SERVER3:
START GROUP_REPLICATION;
這樣就OK了。