MySQL Group Replication(簡稱MGR)是MySQL官方於2016年12月推出的一個全新的高可用與高擴充套件的解決方案。MGR是MySQL官方在5.7.17版本引進的一個資料庫高可用與高擴充套件的解決方案,以外掛形式提供,實現了分散式下資料的最終一致性, 它是MySQL5.7版本出現的新特性,它提供了高可用、高擴充套件、高可靠的MySQL叢集服務。MySQL組複製分單主模式和多主模式,mysql 的複製技術僅解決了資料同步的問題,如果 master 當機,意味著資料庫管理員需要介入,應用系統可能需要修改資料庫連線地址或者重啟才能實現。(這裡也可以使用資料庫中介軟體產品來避免應用系統資料庫連線的問題,例如 mycat 和 atlas 等產品)。組複製在資料庫層面上做到了,只要叢集中大多數主機可用,則服務可用,也就是說3臺伺服器的叢集,允許其中1臺當機。
注意: 組中server可在獨立物理機執行,也可在同一臺機器,同一機器採用多例項,也就是邏輯認為是獨立機器; 組內每臺主機,都需要先安裝組複製外掛.否則會導致啟動失敗.
1. MGR組複製的特點
- 高一致性:基於分散式paxos協議實現組複製,保證資料一致性;
- 高容錯性:自動檢測機制,只要不是大多數節點都當機就可以繼續工作,內建防腦裂保護機制;
- 高擴充套件性:節點的增加與移除會自動更新組成員資訊,新節點加入後,自動從其他節點同步增量資料,直到與其他節點資料一致;
- 高靈活性:提供單主模式和多主模式,單主模式在主庫當機後能夠自動選主,所有寫入都在主節點進行,多主模式支援多節點寫入。
2. MGR與傳統複製的區別和大幅改進
2.1 傳統複製 (即非同步複製)
主-從複製:有一個主和不等數量的從。主節點執行的事務會非同步傳送給從節點,在從節點重新執行。即是在主節點執行和提交事務,然後把他們非同步的傳送到從節點,行復制的重新執行主節點的SQL語句,這是一個 shared-nothing 的系統,預設情況下所有 server 成員都有一個完整的資料副本。
2.2 半同步複製
它在協議中新增了一個同步步驟。 這意味著主節點在提交時需要等待從節點確認它已經接收到事務。只有這樣,主節點才能繼續提交操作。 半同步相對非同步來說, Master會確認Slave是否接到資料,更加安全。
2.3 並行複製
並行複製:複製->廣播->正式複製. 並行複製的介紹可在https://www.cnblogs.com/kevingrace/p/5569652.html 文中有介紹
2.4 組複製 (MGR)
MGR組複製原理
組複製是一種可用於實現容錯系統的技術。 複製組是一個通過訊息傳遞相互互動的 server 叢集。通訊層提供了原子訊息(atomic message)和完全有序資訊互動等保障機制實現了基於複製協議的多主更新 複製組由多個 server成員構成,並且組中的每個 server 成員可以獨立地執行事務。但所有讀寫(RW)事務只有在衝突檢測成功後才會提交。只讀(RO)事務不需要在衝突檢測,可以立即提交。句話說,對於任何 RW 事務,提交操作並不是由始發 server 單向決定的,而是由組來決定是否提交。準確地說,在始發 server 上,當事務準備好提交時,該 server 會廣播寫入值(已改變的行)和對應的寫入集(已更新的行的唯一識別符號)。然後會為該事務建立一個全域性的順序。最終,這意味著所有 server 成員以相同的順序接收同一組事務。因此,所有 server 成員以相同的順序應用相同的更改,以確保組內一致。
MySQL組複製協議工作流程:
需要注意:MGR組複製是一種 share-nothing 複製方案,其中每個 server 成員都有自己的完整資料副本。
MGR實現了基於複製協議的多主更新
-> 複製組由多個 server成員構成,並且組中的每個 server 成員可以獨立地執行事務。但所有讀寫(RW)事務只有在衝突檢測成功後才會提交。只讀(RO)事務不需要在衝突檢測,可以立即提交。
-> 換句話說,對於任何 RW 事務,提交操作並不是由始發 server 單向決定的,而是由組來決定是否提交。準確地說,在始發 server 上,當事務準備好提交時,該 server 會廣播寫入值(已改變的行)和對應的寫入集(已更新的行的唯一識別符號)。然後會為該事務建立一個全域性的順序。最終,這意味著所有 server 成員以相同的順序接收同一組事務。因此,所有 server 成員以相同的順序應用相同的更改,以確保組內一致。
-> 組複製使您能夠根據在一組 server 中複製系統的狀態來建立具有冗餘的容錯系統。因此,只要它不是全部或多數 server 發生故障,即使有一些 server 故障,系統仍然可用,最多隻是效能和可伸縮性降低,但它仍然可用。server 故障是孤立並且獨立的。它們由組成員服務來監控,組成員服務依賴於分散式故障檢測系統,其能夠在任何 server 自願地或由於意外停止而離開組時發出訊號。
-> 他們是由一個分散式恢復程式來確保當有 server 加入組時,它們會自動更新組資訊到最新。並且多主更新確保了即使在單個伺服器故障的情況下也不會阻止更新,不必進行 server故障轉移。因此,MySQL 組複製保證資料庫服務持續可用。
-> 值得注意的一點是,儘管資料庫服務可用,但當有一個 server 崩潰時,連線到它的客戶端必須定向或故障轉移到不同的 server。這不是組複製要解決的問題。聯結器,負載均衡器,路由器或其他形式的中介軟體更適合處理這個問題。
總之,MGR組複製提供了高可用性,高彈性,可靠的 MySQL 服務。
MGR故障檢測
故障檢測是提供關於哪些 server 可能已死的資訊(猜測)的分散式服務。 某個 server 無響應時觸發猜測,組中其餘成員進行協調決定以排除給定成員。如果某個 server 與組的其餘成員隔離,則它會懷疑所有其他 server 都失敗了。由於無法與組達成協議(因為它無法確保仲裁成員數),其懷疑不會產生後果。當伺服器以此方式與組隔離時,它無法執行任何本地事務。 線上 server 列表通常稱為檢視,新成員server的加入離開,無論是自願還是被迫的離開,該組都會動態地重新規劃其配置,並觸發檢視更新
MGR的限制
- 儲存引擎必須為Innodb,即僅支援InnoDB表,並且每張表一定要有一個主鍵,用於做write set的衝突檢測;
- 每個表必須提供主鍵;
- 只支援ipv4,網路需求較高;
- 必須開啟GTID特性,二進位制日誌格式必須設定為ROW,用於選主與write set;
- COMMIT可能會導致失敗,類似於快照事務隔離級別的失敗場景;
- 目前一個MGR叢集組最多支援9個節點;
- 不支援外來鍵於save point特性,無法做全域性間的約束檢測與部分部分回滾;
- 二進位制日誌binlog不支援Replication event checksums;
- 多主模式(也就是多寫模式) 不支援SERIALIZABLE事務隔離級別;
- 多主模式不能完全支援級聯外來鍵約束;
- 多主模式不支援在不同節點上對同一個資料庫物件併發執行DDL(在不同節點上對同一行併發進行RW事務,後發起的事務會失敗);
MGR組複製優勢
- 彈性複製(高擴充套件性):server動態新增移除
- 高可用分片(高擴充套件性):分片實現寫擴充套件,每個分片是一個複製組。
- 替代主從複製(高擴充套件性):整組寫入,避免單點爭用。
- 自動化系統:自動化部署Mysql複製到已有複製協議的自動化系統。
- 故障檢測與容錯:自動檢測,若服務faild,組內成員大多數達成認為該服務已不正常,則自動隔離。
- 組內成員會構成一個檢視,組內成員主動加入或離開(主動或被動),都會更新組配置,更新檢視。成員自願離開,先更新組配置,然後採用大多數成員(不包含主動脫離的成員)意見是否確認該成員離開更新檢視。如果是故障要排除,則需大多數服務確認(包括故障成員意見),然後才會更新組配置和檢視。
- 最大允許即時故障數:f=(n-1)/2,多數正常則正常
3. 組複製兩種執行模式
-> 在單主模式下, 組複製具有自動選主功能,每次只有一個 server成員接受更新。單寫模式group內只有一臺節點可寫可讀,其他節點只可以讀。對於group的部署,需要先跑起primary節點(即那個可寫可讀的節點,read_only = 0)然後再跑起其他的節點,並把這些節點一一加進group。其他的節點就會自動同步primary節點上面的變化,然後將自己設定為只讀模式(read_only = 1)。當primary節點意外當機或者下線,在滿足大多數節點存活的情況下,group內部發起選舉,選出下一個可用的讀節點,提升為primary節點。primary選舉根據group內剩下存活節點的UUID按字典序升序來選擇,即剩餘存活的節點按UUID字典序排列,然後選擇排在最前的節點作為新的primary節點。
-> 在多主模式下, 所有的 server 成員都可以同時接受更新。group內的所有機器都是primary節點,同時可以進行讀寫操作,並且資料是最終一致的。
按照我的理解來說:
單主模式:比多主模式多一個選舉程式,第一次引導開啟叢集的為主,後加入的為追隨者(也可以叫從機Slave),只有住的有讀寫許可權,別的追隨者在加入組的時候自動把許可權禁了。如果主的掛了,其他伺服器會根據UUID和一個值(類似權重)進行重新選主。每次選主都會重新把許可權禁一遍。
多主模式:所有伺服器加入組時,讀寫許可權全部放開,大家都可以讀寫,但是隻能更改不同行的資料,如果後加入叢集的伺服器改了一行資料,那前面的伺服器就不能再對這行資料進行改動了,如果改動則報事務回滾取消改動,而後加入的可以改前面加入叢集改過的資料。
4. 下面分別記錄下 MGR 基於單主模式和多主模式的叢集環境部署過程
4.1 準備環境
三臺伺服器 172.16.60.211 MGR-node1 server_id=1 172.16.60.212 MGR-node2 server_id=2 172.16.60.213 MGR-node3 server_id=3 [root@MGR-node1 ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) 為了方便實驗,關閉所有節點的防火牆 [root@MGR-node1 ~]# systemctl stop firewalld [root@MGR-node1 ~]# firewall-cmd --state not running [root@MGR-node1 ~]# cat /etc/sysconfig/selinux |grep "SELINUX=disabled" SELINUX=disabled [root@MGR-node1 ~]# setenforce 0 setenforce: SELinux is disabled [root@MGR-node1 ~]# getenforce Disabled 特別要注意一個關鍵點: 必須保證各個mysql節點的主機名不一致,並且能通過主機名找到各成員! 則必須要在每個節點的/etc/hosts裡面做主機名繫結,否則後續將節點加入group組會失敗!報錯RECOVERING!! [root@MGR-node1 ~]# cat /etc/hosts ........ 172.16.60.211 MGR-node1 172.16.60.212 MGR-node2 172.16.60.213 MGR-node3
4.2 在三個節點上安裝Mysql5.7
在三個mysql節點機上使用yum方式安裝Mysql5.7,參考:https://www.cnblogs.com/kevingrace/p/8340690.html 安裝MySQL yum資源庫 [root@MGR-node1 ~]# yum localinstall https://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm 安裝MySQL 5.7 [root@MGR-node1 ~]# yum install -y mysql-community-server 啟動MySQL伺服器和MySQL的自動啟動 [root@MGR-node1 ~]# systemctl start mysqld.service [root@MGR-node1 ~]# systemctl enable mysqld.service 設定登入密碼 由於MySQL從5.7開始不允許首次安裝後使用空密碼進行登入!為了加強安全性,系統會隨機生成一個密碼以供管理員首次登入使用, 這個密碼記錄在/var/log/mysqld.log檔案中,使用下面的命令可以檢視此密碼: [root@MGR-node1 ~]# cat /var/log/mysqld.log|grep 'A temporary password' 2019-01-11T05:53:17.824073Z 1 [Note] A temporary password is generated for root@localhost: TaN.k:*Qw2xs 使用上面檢視的密碼TaN.k:*Qw2xs 登入mysql,並重置密碼為123456 [root@MGR-node1 ~]# mysql -p #輸入預設的密碼:TaN.k:*Qw2xs ............. mysql> set global validate_password_policy=0; Query OK, 0 rows affected (0.00 sec) mysql> set global validate_password_length=1; Query OK, 0 rows affected (0.00 sec) mysql> set password=password("123456"); Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) 檢視mysql版本 [root@MGR-node1 ~]# mysql -p123456 ........ mysql> select version(); +-----------+ | version() | +-----------+ | 5.7.24 | +-----------+ 1 row in set (0.00 sec) ===================================================================== 溫馨提示 mysql5.7通過上面預設安裝後,執行語句可能會報錯: ERROR 1819 (HY000): Your password does not satisfy the current policy requirements 這個報錯與Mysql 密碼安全策略validate_password_policy的值有關,validate_password_policy可以取0、1、2三個值: 解決辦法: set global validate_password_policy=0; set global validate_password_length=1;
4.3 安裝和配置MGR資訊
1) 配置所有節點的組複製資訊 MGR-node01節點 [root@MGR-node1 ~]# cp /etc/my.cnf /etc/my.cnf.bak [root@MGR-node1 ~]# >/etc/my.cnf [root@MGR-node1 ~]# vim /etc/my.cnf [mysqld] datadir = /var/lib/mysql socket = /var/lib/mysql/mysql.sock symbolic-links = 0 log-error = /var/log/mysqld.log pid-file = /var/run/mysqld/mysqld.pid #複製框架 server_id=1 gtid_mode=ON enforce_gtid_consistency=ON binlog_checksum=NONE log_bin=binlog log_slave_updates=ON binlog_format=ROW master_info_repository=TABLE relay_log_info_repository=TABLE #組複製設定 #server必須為每個事務收集寫集合,並使用XXHASH64雜湊演算法將其編碼為雜湊 transaction_write_set_extraction=XXHASH64 #告知外掛加入或建立組命名,UUID loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" #server啟動時不自啟組複製,為了避免每次啟動自動引導具有相同名稱的第二個組,所以設定為OFF。 loose-group_replication_start_on_boot=off #告訴外掛使用IP地址,埠24901用於接收組中其他成員轉入連線 loose-group_replication_local_address="172.16.60.211:24901" #啟動組server,種子server,加入組應該連線這些的ip和埠;其他server要加入組得由組成員同意 loose-group_replication_group_seeds="172.16.60.211:24901,172.16.60.212:24901,172.16.60.213:24901" loose-group_replication_bootstrap_group=off report_host=172.16.60.211 report_port=3306 如上配置完成後, 將MGR-node1節點的/etc/my.cnf檔案拷貝到其他兩個節點 [root@MGR-node1 ~]# rsync -e "ssh -p22" -avpgolr /etc/my.cnf root@172.16.60.212:/etc/ [root@MGR-node1 ~]# rsync -e "ssh -p22" -avpgolr /etc/my.cnf root@172.16.60.213:/etc/ 3個MGR節點除了server_id、loose-group_replication_local_address、report_host 三個引數不一樣外,其他保持一致。 所以待拷貝完成後, 分別修改MGR-node2和MGR-node3節點/etc/my.cnf檔案的server_id、loose-group_replication_local_address、report_host 三個引數 2) 配置完成後, 要一次啟動資料庫,安裝MGR外掛,設定複製賬號(所有MGR節點都要執行) [root@MGR-node1 ~]# systemctl restart mysqld [root@MGR-node1 ~]# mysql -p123456 ............. mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so'; Query OK, 0 rows affected (0.13 sec) mysql> SET SQL_LOG_BIN=0; Query OK, 0 rows affected (0.00 sec) mysql> CREATE USER repl@'%' IDENTIFIED BY 'repl'; Query OK, 0 rows affected (0.00 sec) mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'%'; Query OK, 0 rows affected (0.00 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec) mysql> SET SQL_LOG_BIN=1; Query OK, 0 rows affected (0.00 sec) mysql> CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery'; Query OK, 0 rows affected, 2 warnings (0.21 sec)
4.4 啟動MGR單主模式
1) 啟動MGR,在主庫(172.16.60.11)節點上上執行 [root@MGR-node1 ~]# mysql -p123456 ............... mysql> SET GLOBAL group_replication_bootstrap_group=ON; Query OK, 0 rows affected (0.00 sec) mysql> START GROUP_REPLICATION; Query OK, 0 rows affected (2.31 sec) mysql> SET GLOBAL group_replication_bootstrap_group=OFF; Query OK, 0 rows affected (0.00 sec) 檢視MGR組資訊 mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+---------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ | group_replication_applier | 8769f936-3e51-11e9-acaa-005056ac6820 | 172.16.60.211 | 3306 | ONLINE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ 1 row in set (0.01 sec) 2) 在其他節點加入MGR叢集,在從庫(172.16.60.212,172.16.60.213)上執行 [root@MGR-node2 ~]# mysql -p123456 ................ mysql> START GROUP_REPLICATION; ERROR 3092 (HY000): The server is not configured properly to be an active member of the group. Please see more details on error log. 檢視日誌: [root@MGR-node2 ~]# tail -2000 /var/log/mysqld.log ..................... ..................... 2019-03-04T09:11:30.683714Z 0 [ERROR] Plugin group_replication reported: 'This member has more executed transactions than those present in the group. Local transactions: 87135ebb-3e51-11e9-8931-005056880888:1-2 > Group transactions: 851d03bb-3e51-11e9-8f8d-00505688047c:1-2, 8769f936-3e51-11e9-acaa-005056ac6820:1-2, aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-4' 2019-03-04T09:11:30.683817Z 0 [Warning] Plugin group_replication reported: 'The member contains transactions not present in the group. It is only allowed to join due to group_replication_allow_local_disjoint_gtids_join option' 解決辦法: mysql> set global group_replication_allow_local_disjoint_gtids_join=ON; Query OK, 0 rows affected, 1 warning (0.00 sec) 然後再接著加入MGR叢集 mysql> START GROUP_REPLICATION; Query OK, 0 rows affected, 1 warning (5.14 sec) 3) 再次檢視MGR組資訊 (在三個MGR節點上都可以檢視) mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+---------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ | group_replication_applier | 851d03bb-3e51-11e9-8f8d-00505688047c | 172.16.60.212 | 3306 | RECOVERING | | group_replication_applier | 87135ebb-3e51-11e9-8931-005056880888 | 172.16.60.213 | 3306 | RECOVERING | | group_replication_applier | 8769f936-3e51-11e9-acaa-005056ac6820 | 172.16.60.211 | 3306 | ONLINE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ 3 rows in set (0.00 sec) 發現新加入的MGR-node2 , MGR-node3兩個節點在叢集裡的狀態是RECOVERING!!! 檢視日誌 [root@MGR-node3 ~]# tail -2000 /var/log/mysqld.log ..................... ..................... 2019-03-04T09:15:35.146740Z 734 [ERROR] Slave I/O for channel 'group_replication_recovery': Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.', Error_code: 1236 解決辦法: 登入主庫172.16.60.211, 檢視被purge的GTID: [root@MGR-node1 ~]# mysql -p123456 .................... mysql> show global variables like 'gtid_purged'; +---------------+------------------------------------------+ | Variable_name | Value | +---------------+------------------------------------------+ | gtid_purged | 8769f936-3e51-11e9-acaa-005056ac6820:1-2 | +---------------+------------------------------------------+ 1 row in set (0.00 sec) 接著在兩個從庫172.16.60.212, 172.16.60.213的資料庫上執行下面命令,即跳過這個GTID: mysql> STOP GROUP_REPLICATION; Query OK, 0 rows affected (10.14 sec) mysql> reset master; Query OK, 0 rows affected (0.06 sec) mysql> set global gtid_purged = '8769f936-3e51-11e9-acaa-005056ac6820:1-2'; Query OK, 0 rows affected (0.24 sec) mysql> START GROUP_REPLICATION; Query OK, 0 rows affected, 1 warning (3.49 sec) 再次檢視檢視MGR組資訊 (在三個MGR節點上都可以檢視), mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+---------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ | group_replication_applier | 851d03bb-3e51-11e9-8f8d-00505688047c | 172.16.60.212 | 3306 | ONLINE | | group_replication_applier | 87135ebb-3e51-11e9-8931-005056880888 | 172.16.60.213 | 3306 | ONLINE | | group_replication_applier | 8769f936-3e51-11e9-acaa-005056ac6820 | 172.16.60.211 | 3306 | ONLINE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ 3 rows in set (0.00 sec) 通過上面可以看出: 三個MGR節點狀態為online,並且主節點為172.16.60.211,只有主節點可以寫入,其他兩個MGR節點只讀,MGR單主模式搭建成功。 ============================================================================== 驗證下MGR單主模式下節點資料的同步以及讀寫操作: 先在主庫節點172.16.60.211上建立測試資料庫 [root@MGR-node1 ~]# mysql -p123456 .............. mysql> CREATE DATABASE kevin CHARACTER SET utf8 COLLATE utf8_general_ci; Query OK, 1 row affected (0.06 sec) mysql> use kevin; Database changed mysql> create table if not exists haha (id int(10) PRIMARY KEY AUTO_INCREMENT,name varchar(50) NOT NULL); Query OK, 0 rows affected (0.24 sec) mysql> insert into kevin.haha values(1,"wangshibo"),(2,"guohuihui"),(3,"yangyang"),(4,"shikui"); Query OK, 4 rows affected (0.13 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> select * from kevin.haha; +----+-----------+ | id | name | +----+-----------+ | 1 | wangshibo | | 2 | guohuihui | | 3 | yangyang | | 4 | shikui | +----+-----------+ 4 rows in set (0.00 sec) 接著在其他的兩個從節點172.16.60.212和172.16.60.213上檢視資料, 發現主庫資料已經同步到兩個從庫上了 [root@MGR-node2 ~]# mysql -p123456 .................. mysql> select * from kevin.haha; +----+-----------+ | id | name | +----+-----------+ | 1 | wangshibo | | 2 | guohuihui | | 3 | yangyang | | 4 | shikui | +----+-----------+ 4 rows in set (0.00 sec) 然後嘗試在兩個從庫上更新資料, 發現更新失敗! 因為這是MGR單主模式, 從庫只能進行讀操作, 不能進行寫操作! [root@MGR-node3 ~]# mysql -p123456 ................. mysql> select * from kevin.haha; +----+-----------+ | id | name | +----+-----------+ | 1 | wangshibo | | 2 | guohuihui | | 3 | yangyang | | 4 | shikui | +----+-----------+ 4 rows in set (0.00 sec) mysql> delete from kevin.haha where id>3; ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement mysql> insert into kevin.haha values(11,"beijing"),(12,"shanghai"),(13,"anhui"); ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement 只有在主庫上才能進行寫操作 [root@MGR-node1 ~]# mysql -p123456 .............. mysql> insert into kevin.haha values(11,"beijing"),(12,"shanghai"),(13,"anhui"); Query OK, 3 rows affected (0.15 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from kevin.haha; +----+-----------+ | id | name | +----+-----------+ | 1 | wangshibo | | 2 | guohuihui | | 3 | yangyang | | 4 | shikui | | 11 | beijing | | 12 | shanghai | | 13 | anhui | +----+-----------+ 7 rows in set (0.00 sec)
4.5 切換到多主模式
MGR切換模式需要重新啟動組複製,因些需要在所有節點上先關閉組複製,設定 group_replication_single_primary_mode=OFF 等引數,再啟動組複製。
1) 停止組複製(在所有MGR節點上執行): mysql> stop group_replication; Query OK, 0 rows affected (9.08 sec) mysql> set global group_replication_single_primary_mode=OFF; Query OK, 0 rows affected (0.00 sec) mysql> set global group_replication_enforce_update_everywhere_checks=ON; Query OK, 0 rows affected (0.00 sec) 2) 隨便選擇某個MGR節點執行 (比如這裡選擇在MGR-node1節點): [root@MGR-node1 ~]# mysql -p123456 ............... mysql> SET GLOBAL group_replication_bootstrap_group=ON; Query OK, 0 rows affected (0.00 sec) mysql> START GROUP_REPLICATION; Query OK, 0 rows affected (2.20 sec) mysql> SET GLOBAL group_replication_bootstrap_group=OFF; Query OK, 0 rows affected (0.00 sec) 3) 然後在其他的MGR節點執行 (這裡指MGR-node2和MGR-node3節點上執行): mysql> START GROUP_REPLICATION; Query OK, 0 rows affected, 1 warning (5.89 sec) 4) 檢視MGR組資訊 (在任意一個MGR節點上都可以檢視) mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+---------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ | group_replication_applier | 851d03bb-3e51-11e9-8f8d-00505688047c | 172.16.60.212 | 3306 | ONLINE | | group_replication_applier | 87135ebb-3e51-11e9-8931-005056880888 | 172.16.60.213 | 3306 | ONLINE | | group_replication_applier | 8769f936-3e51-11e9-acaa-005056ac6820 | 172.16.60.211 | 3306 | ONLINE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ 3 rows in set (0.00 sec) 可以看到所有MGR節點狀態都是online,角色都是PRIMARY,MGR多主模式搭建成功。 ========================================= 驗證下MGR多主模式的節點資料同步: 在MGR-node1節點更新資料: [root@MGR-node1 ~]# mysql -p123456 ................. mysql> select * from kevin.haha; +----+-----------+ | id | name | +----+-----------+ | 1 | wangshibo | | 2 | guohuihui | | 3 | yangyang | | 4 | shikui | | 11 | beijing | | 12 | shanghai | | 13 | anhui | +----+-----------+ 7 rows in set (0.00 sec) mysql> delete from kevin.haha where id>10; Query OK, 3 rows affected (0.08 sec) 在MGR-node2節點更新資料 [root@MGR-node2 ~]# mysql -p123456 ............... mysql> select * from kevin.haha; +----+-----------+ | id | name | +----+-----------+ | 1 | wangshibo | | 2 | guohuihui | | 3 | yangyang | | 4 | shikui | +----+-----------+ 4 rows in set (0.00 sec) mysql> insert into kevin.haha values(11,"beijing"),(12,"shanghai"),(13,"anhui"); Query OK, 3 rows affected (0.08 sec) Records: 3 Duplicates: 0 Warnings: 0 在MGR-node3節點更新資料 [root@MGR-node3 ~]# mysql -p123456 ............. mysql> select * from kevin.haha; +----+-----------+ | id | name | +----+-----------+ | 1 | wangshibo | | 2 | guohuihui | | 3 | yangyang | | 4 | shikui | | 11 | beijing | | 12 | shanghai | | 13 | anhui | +----+-----------+ 7 rows in set (0.00 sec) mysql> delete from kevin.haha where id>11; Query OK, 2 rows affected (0.14 sec) mysql> select * from kevin.haha; +----+-----------+ | id | name | +----+-----------+ | 1 | wangshibo | | 2 | guohuihui | | 3 | yangyang | | 4 | shikui | | 11 | beijing | +----+-----------+ 5 rows in set (0.00 sec) 如上, MGR多主模式下, 所有節點都可以進行讀寫操作.
4.6 切回單主模式
1) 停止組複製(在所有MGR節點上執行): mysql> stop group_replication; Query OK, 0 rows affected (9.29 sec) mysql> set global group_replication_enforce_update_everywhere_checks=OFF; Query OK, 0 rows affected (0.00 sec) mysql> set global group_replication_single_primary_mode=ON; Query OK, 0 rows affected (0.00 sec) 2) 選擇一個節點作為主節點, 在主節點上執行 (這裡選擇MGR-node1節點作為主節點) [root@MGR-node1 ~]# mysql -p123456 ................ mysql> SET GLOBAL group_replication_bootstrap_group=ON; Query OK, 0 rows affected (0.00 sec) mysql> START GROUP_REPLICATION; Query OK, 0 rows affected (2.12 sec) mysql> SET GLOBAL group_replication_bootstrap_group=OFF; Query OK, 0 rows affected (0.00 sec) 3) 在其他剩餘的節點, 也就是從庫節點上執行 (這裡從庫節點指的就是MGR-node2和MGR-node3): mysql> START GROUP_REPLICATION; Query OK, 0 rows affected, 1 warning (6.16 sec) 4) 檢視MGR組資訊 (在任意一個MGR節點上都可以檢視) mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+---------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ | group_replication_applier | 851d03bb-3e51-11e9-8f8d-00505688047c | 172.16.60.212 | 3306 | ONLINE | | group_replication_applier | 87135ebb-3e51-11e9-8931-005056880888 | 172.16.60.213 | 3306 | ONLINE | | group_replication_applier | 8769f936-3e51-11e9-acaa-005056ac6820 | 172.16.60.211 | 3306 | ONLINE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ 3 rows in set (0.00 sec) 這樣就又切回到MGR單主模式了, 其中172.16.60.211是主節點,具有寫許可權. 另外兩個節點172.16.60.212和172.16.60.213是從庫節點, 只能讀不能寫.
4.7 故障切換
1) 單主模式 如果主節點掛掉了, 通過選舉程式會從從庫節點中選擇一個作為主庫節點. 如下模擬故障: 關閉主庫MGR-node1的mysqld服務 [root@MGR-node1 ~]# systemctl stop mysqld 接著在其他節點上檢視MGR組資訊. 比如在MGR-node2節點檢視 [root@MGR-node2 ~]# mysql -p123456 mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+---------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ | group_replication_applier | 851d03bb-3e51-11e9-8f8d-00505688047c | 172.16.60.212 | 3306 | ONLINE | | group_replication_applier | 87135ebb-3e51-11e9-8931-005056880888 | 172.16.60.213 | 3306 | ONLINE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ 2 rows in set (0.00 sec) 嘗試在MGR-node2節點更新資料 mysql> select * from kevin.haha; +----+-----------+ | id | name | +----+-----------+ | 1 | wangshibo | | 2 | guohuihui | | 3 | yangyang | | 4 | shikui | | 11 | beijing | | 12 | shanghai | | 13 | anhui | +----+-----------+ 7 rows in set (0.00 sec) mysql> delete from kevin.haha where id>10; Query OK, 3 rows affected (0.06 sec) 如上, 發現在之前的主庫MGR-node1節點掛掉後, MGR-node2節點可以進行寫操作了, 說明此時已經選舉MGR-node2節點為新的主節點了 那麼,MGR-node3節點還是從節點, 只能讀不能寫 [root@MGR-node3 ~]# mysql -p123456 .............. mysql> select * from kevin.haha; +----+-----------+ | id | name | +----+-----------+ | 1 | wangshibo | | 2 | guohuihui | | 3 | yangyang | | 4 | shikui | +----+-----------+ 4 rows in set (0.00 sec) mysql> insert into kevin.haha values(11,"beijing"),(12,"shanghai"),(13,"anhui"); ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement 然後再恢復MGR-node1節點, 恢復後, 需要手動啟用下該節點的組複製功能 [root@MGR-node1 ~]# systemctl start mysqld [root@MGR-node1 ~]# mysql -p123456 ............... mysql> START GROUP_REPLICATION; Query OK, 0 rows affected (3.15 sec) mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+---------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ | group_replication_applier | 851d03bb-3e51-11e9-8f8d-00505688047c | 172.16.60.212 | 3306 | ONLINE | | group_replication_applier | 87135ebb-3e51-11e9-8931-005056880888 | 172.16.60.213 | 3306 | ONLINE | | group_replication_applier | 8769f936-3e51-11e9-acaa-005056ac6820 | 172.16.60.211 | 3306 | ONLINE | +---------------------------+--------------------------------------+---------------+-------------+--------------+ 3 rows in set (0.00 sec) mysql> select * from kevin.haha; +----+-----------+ | id | name | +----+-----------+ | 1 | wangshibo | | 2 | guohuihui | | 3 | yangyang | | 4 | shikui | +----+-----------+ 4 rows in set (0.00 sec) mysql> insert into kevin.haha values(11,"beijing"),(12,"shanghai"),(13,"anhui"); ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement 發現MGR-node1節點恢復後, 則變為了從庫節點, 只能讀不能寫. 如果從節點掛了, 恢復後, 只需要手動啟用下該節點的組複製功能("START GROUP_REPLICATION;"), 即可正常加入到MGR組複製叢集內並自動同步其他節點資料. ============================================================= 2) 多主模式 如果某個節點掛了, 則其他的節點繼續進行同步. 當故障節點恢復後, 只需要手動啟用下該節點的組複製功能("START GROUP_REPLICATION;"), 即可正常加入到MGR組複製叢集內並自動同步其他節點資料.
基於Mysql8.0, 安裝MGR 單主/多主模式的叢集環境
上面案例是基於Mysql5.7版本的操作記錄, 如果換成Mysql8.0版本, 則稍微有些地方不一樣. Mysql8.0版本按照上面的操作, 在實操中沒有出現報錯. Mysql8.0安裝手冊: https://www.cnblogs.com/kevingrace/p/10482469.html 檢視組資訊, 會顯示主從角色: PRIMARY 和 SECONDARY 單主模式 mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+ | group_replication_applier | 9d9e69cb-3fb2-11e9-9420-005056ac6820 | 172.16.60.211 | 3306 | ONLINE | PRIMARY | 8.0.15 | | group_replication_applier | a5edb094-3fb2-11e9-9ddf-00505688047c | 172.16.60.212 | 3306 | ONLINE | SECONDARY | 8.0.15 | | group_replication_applier | a8e04386-3fb2-11e9-9eb3-005056880888 | 172.16.60.213 | 3306 | ONLINE | SECONDARY | 8.0.15 | +---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+ 3 rows in set (0.00 sec) 多主模式 mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+ | group_replication_applier | 9d9e69cb-3fb2-11e9-9420-005056ac6820 | 172.16.60.211 | 3306 | ONLINE | PRIMARY | 8.0.15 | | group_replication_applier | a5edb094-3fb2-11e9-9ddf-00505688047c | 172.16.60.212 | 3306 | ONLINE | PRIMARY | 8.0.15 | | group_replication_applier | a8e04386-3fb2-11e9-9eb3-005056880888 | 172.16.60.213 | 3306 | ONLINE | PRIMARY | 8.0.15 | +---------------------------+--------------------------------------+---------------+-------------+--------------+-------------+----------------+ 3 rows in set (0.00 sec) 如果節點發生故障, 在恢復後需要重新加入到MGR叢集裡, 正確的做法是: 先stop組複製, 然後再start組複製! 不然可能會造成加入到叢集后的狀態是"RECOVERING"! 正確的做法: mysql> stop GROUP_REPLICATION; Query OK, 0 rows affected (8.18 sec) mysql> START GROUP_REPLICATION; Query OK, 0 rows affected (4.16 sec)
設定MGR組叢集的白名單網段: 新增節點所在網段
或者出現報錯: '[GCS] The member is leaving a group without being on one.' 這是因為沒有設定白名單網段:需要新增節點自己所在網段. 在任意一個MGR節點上執行: [root@MGR-node1 ~]# mysql -p123456 ................. # 新增白名單網段 mysql> stop group_replication; Query OK, 0 rows affected (9.41 sec) mysql> set global group_replication_ip_whitelist="127.0.0.1/32,172.16.60.0/24,172.16.50.0/24,172.16.51.0/24"; Query OK, 0 rows affected (0.00 sec) mysql> start group_replication; Query OK, 0 rows affected (3.37 sec) mysql> show variables like "group_replication_ip_whitelist"; +--------------------------------+-----------------------------------------------------------+ | Variable_name | Value | +--------------------------------+-----------------------------------------------------------+ | group_replication_ip_whitelist | 127.0.0.1/32,172.16.60.0/24,172.16.50.0/24,172.16.51.0/24 | +--------------------------------+-----------------------------------------------------------+ 1 row in set (0.01 sec) group_replication_ip_whitelist = <ip,net,...> 表示設定白名單,若不配置預設為AUTOMATIC,自動識別本機網口的私網地址和私網網段,127.0.0.1 連線請求始終被允許, 一定要注意: 配置白名單前面一定要先關閉 Group Replication, 及先要執行"stop group_replication;" 也可以在/etc/my.cnf檔案裡配置白名單資訊.