【Mysql】——MySQL 5.7 MGR(單主模式)

一、前言

       mysql應該是廣大開發們用的最多的數據庫了。單節點mysql沒啥好說的,官方文檔看起來就行了。不過對於集羣來說,高可用這些就有點迷糊了,今天這個文章只是淺層次的總結一下。在5.7.17的官方文檔中有詳細地描述如何設置Single-Primary MGR的方法。Deploying Group Replication in Single-Primary Mode(https://dev.mysql.com/doc/refman/5.7/en/group-replication-deploying-in-single-primary-mode.html)

      MGR(MySQL Group Replication)是MySQL官方在5.7.17版本引進的一個數據庫高可用與高擴展的解決方案,以插件形式提供,實現了分佈式下數據的最終已執行,總結MGR的特點如下:

  • 高一致性:基於分佈式paxos協議實現組複製,保證數據一致性
  • 高容錯性:自動檢測機制,只要不是大多數節點都宕機就可以繼續工作,內置防腦裂保護機制;
  • 高擴展性:節點的添加與移除會自動更新組成員信息,新節點加入後,自動從其他節點同步增量數據,知道與其他節點數據一致;
  • 高靈活性:提供單住和多主模式,單主模式在主庫宕機後能夠自動選主,所有寫入都在主節點進行,多主模式支持多節點寫入。

二、知識點

       主從複製,一主多從,主庫提供讀寫功能,從庫提供只讀功能。當一個事務在master 提交成功時,會把binlog文件同步到從庫服務器上落地爲relay log給slave端執行,這個過程主庫是不考慮從庫是否有接收到binlog文件,有可能出現這種情況,當主庫commit一個事務後,數據庫發生宕機,剛好它的binlog還沒來得及傳送到slave端,這個時候選任何一個slave端都會丟失這個事務,造成數據不一致情況。 爲了避免出現主從數據不一致的情況,MySQL引入了半同步複製,添加多了一個從庫反饋機制,即半同步複製。這個有兩種方式設置:

  • 主庫執行完事務後,同步binlog給從庫,從庫ack反饋接收到binlog,主庫提交commit,反饋給客戶端,釋放會話;
  • 主庫執行完事務後,主庫提交commit ,同步binlog給從庫,從庫ack反饋接收到binlog,反饋給客戶端,釋放會話; 

但是,雖然滿足了一主多從,讀寫分析,數據一致,但是,依舊有兩個弊端:

  • 寫操作只能在master上;
  • 如果master宕機,需要人爲選擇新主並重新給其他的slave端執行change master;

爲了解決一系列問題,官方推出了MySQL Group Replication,從group replication發佈以後,就有3種方法來實現MySQL的高可用集羣:

  • 異步複製
  • 半同步複製
  • group replication

 

三、Group Replication原理

      MySQL Group Replication有兩種模式,單主模式single-primary mode和多主模式multi-primary mode,在同一個group內,不允許兩種模式同時存在,並且若要切換到不同模式,必須修改配置後重新啓動集羣。

1、單主模式

在單主模式下,只有一個節點可以讀寫,其他節點提供只讀服務。單主模式下,該參數 _ 必須被設置爲 FALSE ,當主節點宕掉,自動會根據服務器的server_uuid變量和group_replication_member_weight變量值,選擇下一個slave誰作爲主節點,group_replication_member_weight的值最高的成員被選爲新的主節點,該參數默認爲50,建議可以在節點上設置不同值;在group_replication_member_weight值相同的情況下,group根據數據字典中 server_uuid排序,排序在最前的被選擇爲主節點。

  • 單主模式中發現當前的主服務器,該值VARIABLE_VALUE爲實例節點的server_uuid:

select * from performance_schema.global_status WHERE VARIABLE_NAME like '%group_replication%';

四、簡單查詢

# 開啓單主模式
mysql> set global group_replication_single_primary_mode=on;
Query OK, 0 rows affected (0.00 sec)

mysql> SET GLOBAL group_replication_bootstrap_group=ON;
Query OK, 0 rows affected (0.00 sec)

# 設置使用組複製的用戶
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.07 sec)

mysql> start group_replication;
Query OK, 0 rows affected, 1 warning (2.08 sec)

mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)



mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 1fa7b3ca-9475-11e8-a217-5254004e7cfe | 172.17.0.48 |        3306 | ONLINE       |
| group_replication_applier | 81d824f1-90ba-11e8-a83d-52540043d75a | 172.17.0.2  |        3306 | ONLINE       |
| group_replication_applier | b13df29e-90b6-11e8-8d1b-525400fc3993 | 172.17.0.37 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.00 sec)

mysql> show variables like '%read_on%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_read_only      | OFF   |
| read_only             | OFF   |
| super_read_only       | OFF   |
| transaction_read_only | OFF   |
| tx_read_only          | OFF   |
+-----------------------+-------+
5 rows in set (0.00 sec)


mysql> show variables like '%server_uuid%';
+---------------+--------------------------------------+
| Variable_name | Value                                |
+---------------+--------------------------------------+
| server_uuid   | b13df29e-90b6-11e8-8d1b-525400fc3993 |
+---------------+--------------------------------------+
1 row in set (0.00 sec)

mysql> select * from performance_schema.global_status WHERE VARIABLE_NAME like '%group_replication%';
+----------------------------------+--------------------------------------+
| VARIABLE_NAME                    | VARIABLE_VALUE                       |
+----------------------------------+--------------------------------------+
| group_replication_primary_member | b13df29e-90b6-11e8-8d1b-525400fc3993 |
+----------------------------------+--------------------------------------+
1 row in set (0.01 sec)

mysql> show variables like '%group_replication_member_weight%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| group_replication_member_weight | 80    |
+---------------------------------+-------+
1 row in set (0.00 sec)

1、登錄到數據庫

mysql > mysql -uroot -pyourpassword  

2、關閉二進制日誌記錄功能

mysql > set sql_log_bin=0;  

3、創建一個用於複製的用戶,不建議用root用戶

mysql > grant replication slave on *.* to rpl_user@'%' identified by 'rpl_pass';  

mysql > flush privileges;  

4、開啓二進制日誌記錄功能

mysql > set sql_sql_log_bin = 1;  

5、 設置使用組複製的用戶

mysql > change master to master_user='rpl_user',master_password='rpl_pass' for channel 'group_replication_recovery';  

6、安裝組複製插件

mysql > install PLUGIN group_replication SONAME 'group_replication.so';  

7、開啓插件自動引用組功能

mysql > set global group_replication_bootstrap_group = ON;  

8、 開啓組複製

mysql > start group_replication;  

9、關閉插件自動引用組功能

mysql > set global group_replication_bootstrap_group = OFF;  

10、查看組內節點和節點狀態

查看組內成員

mysql> select * from performance_schema.replication_group_members; 
+---------------------------+--------------------------------------+----------------------------------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST                            | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+----------------------------------------+-------------+--------------+
| group_replication_applier | 5d5b3ceb-9cdc-11ea-a3f6-0242ac11000e | mysql-cluster-0.mysql-cluster-gvr.test |        3306 | ONLINE       |
| group_replication_applier | 70f1b749-9cdc-11ea-b2a7-0242ac11000f | mysql-cluster-1.mysql-cluster-gvr.test |        3306 | ONLINE       |
+---------------------------+--------------------------------------+----------------------------------------+-------------+--------------+
2 rows in set (0.01 sec)
  • CHANNEL_NAME : 顯示的值永遠爲group_replication_applier

  • MEMBER_ID : 節點serer_uuid

  • MEMBER_PORT : 節點服務端口,取值爲server_port指定的端口

  • MEMBER_HOST : 如果沒有配置report_host選項,那麼取值爲機器的hostname,可以通過report_host配置指定具體的IP

  • MEMBER_STATE : 節點狀態

  • MEMBER_STATE字段顯示當前節點的狀態,根據官方文檔,取值和介紹如下所示:

取值 解釋 狀態是否在集羣內同步
ONLINE 表示該節點可正常提供服務 YES
RECOVERING 表示當前節點正在從其他節點恢復數據 YES
OFFLINE 表示GR插件已經加載,但是該節點不屬於任何一個GR組 NO
ERROR 表示節點在recovery階段出現錯誤或者從其他節點同步狀態中出現錯誤 NO
UNREACHABLE 節點處於不可達狀態,無法與之發生網絡通訊 NO

從上表可以知道,只有ONLINERECOVERING兩種狀態會在集羣中得到同步。這個狀態同步是指狀態在所有節點上面查詢均能保持一致的意思。至於OFFLINEERRORUNREABLE,做以下說明:

  • 只有在當前OFFLINE節點查詢replication_group_members表才能得到OFFLINE狀態,在其他節點上查詢replication_group_members表,則一般沒有該節點的狀態(很好理解,因爲OFFLINE節點已經不屬於這個GR組了)
  • 只有在當前ERROR節點查詢replication_group_members表才能得到ERROR狀態,同上面的OFFLINE,在其他節點上查詢也看不到該節點
  • 假設節點A與B網絡通訊失敗,那麼在節點A上查詢replication_group_members表,有可能得到B的狀態爲UNREACHABLE

五、題外話(MGR的限制)

  • 僅支持InnoDB表,並且每張表一定要有一個主鍵,用於做write set的衝突檢測;

  • 必須打開GTID特性,二進制日誌格式必須設置爲ROW,用於選主與write set

  • COMMIT可能會導致失敗,類似於快照事務隔離級別的失敗場景

  • 目前一個MGR集羣最多支持9個節點

  • 不支持外鍵於save point特性,無法做全局間的約束檢測與部分部分回滾

  • 二進制日誌不支持binlog event checksum

 

六、參考資料

參考文章1:https://yq.aliyun.com/articles/702208

參考文章2:https://www.jianshu.com/p/cbe3ba27295c

參考文章3:https://database.51cto.com/art/202004/615706.htm?mobile

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章