mysql group replication觀點及實踐


一:個人看法

Mysql  Group Replication  隨着5.7發布3年了。作為技術愛好者。mgr 是繼 oracle database rac 之后。

又一個“真正” 的群集,怎么做到“真正” ? 怎么做到解決復制的延遲,怎么做到強數據一致性?基於全局的GTID就能解決? 圍繞這些問題進行了一些mgr 的實踐,

為未來的數據庫高可用設計多條選擇。

mysql5.7手冊17章可以看到其原理,網絡上也很多同志寫了關於其技術原理,這里自己對比rac理解下:

作為shared nothing (mgr)架構,其數據一致性實現較 shared everything(RAC) 架構要難,

MGR通過一致性(Paxos)協議,保證數據在復制組內的存活節點里是一致的,復制組內的各成員都可以進行讀寫,

其實現機制是,當某個實例發起事務提交時,會向組內發出廣播,由組內成員決議事務是否可以正常提交,

MGR在遇到事務沖突時(多節點同時修改同一行數據),會自動識別沖突,並根據提交時間讓先提交的事務成功執行,后提交的事務回滾,其原理示意圖如下:

對於 sharad nothing 架構,必須要了解分布式協議PAXOS,分布式狀態機 理論,而在這塊我翻閱了很多資料,發現其實並不是很成熟的。從上圖可以看出來MGR 的沖突檢測機制

類似於 rac 的gird 群集組件 也具備通告廣播的群集服務。但本質架構上有所不同。一切依賴於 復制組的軟件實現。如果這里出了問題,那么整個群集一致性難以得到保證。

 

二:搭建過程

這個過程比較粗糙,網絡上有不少寫的比較細的可以參考

 

1:MGR 必須3節點以上,這個道理不在解釋,先配置my.cnf
    我這里用一台機器模擬3個mysql 節點進行搭建,着重理解紅色參數,對於性能優化和理解mgr 有很大幫助
port=3306
basedir=/home/mysql
datadir=/home/mysql/data3
socket = /home/mysql/data3/mysql3.sock
log_error=/home/mysql/data3/mysql3.error
slow_query_log=on
slow_query_log_file=/home/mysql/data3/slow3.log
long_query_time=3
character_set_server=utf8
lower_case_table_names=1
max_connections=1000
max_connect_errors=1000
explicit_defaults_for_timestamp=1
explicit_defaults_for_timestamp
log-slow-admin-statements=1
log-queries-not-using-indexes=1
expire-logs-days = 15
open_files_limit=65535
innodb_log_file_size = 100m
innodb_log_files_in_group = 3
innodb_file_per_table = 1
innodb_buffer_pool_size=10240M
 
 
#mgr
 
server-id=333
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates = 1
master_info_repository=table
relay_log_info_repository=table
binlog_checksum=none
log-bin=/home/mysql/data3/mysql-bin
binlog_format=row
 
###指示服務器對於每個事務,它必須收集寫集並使用XXHASH64散列算法將其編碼為散列。
transaction_write_set_extraction=XXHASH64 
 
 
###創建的組名稱
loose-group_replication_group_name="335e89d8-2f49-4425-9add-1eeb8134f8fc"
 
###指示插件在服務器啟動時不自動啟動操作,add my 美團點評,是開啟的
###配置成員后,您可以設置 group_replication_start_on_boot 為on,以便在服務器引導時自動啟動Group Replication。
 
loose-group_replication_start_on_boot=on
 
 
 
#loose-group_replication_member_weight = 40
loose-group_replication_local_address="172.31.50.160:20003"
 
#設置組成員的主機名和端口,新成員使用它們建立與組的連接。這些成員稱為種子成員。建立連接后,將列出組成員身份信息
#可以查詢 performance_schema.replication_group_members
 
 
loose-group_replication_group_seeds="172.31.50.160:20001,172.31.50.160:20002,172.31.50.160:20003,172.31.50.160:20004"
 
 
 
# singe or multi mode  這里2個參數不開啟則為單主模式
#loose-group_replication_single_primary_mode = off
#loose-group_replication_enforce_update_everywhere_checks = on
 
 
 
#當成員在發生故障轉移時被選為主要成員的可能性的權重百分比,和server_uuid 配合進行選舉
#如果主要成員離開單主要組,則執行選舉,並從組中的其余服務器中選擇新的主要成員。
#這次選舉是通過查看新視圖,並根據值來訂購潛在的新原選 group_replication_member_weight。
#假設該組正在運行所有運行相同MySQL版本的成員,則具有最高值的成員將 group_replication_member_weight 被選為新的主要成員。
#如果多個服務器具有相同 group_replication_member_weight的服務器,
#則根據服務器的優先級對服務器進行優先級排序 server_uuid按字典順序和選擇第一個。
#選擇新主節點后,它將自動設置為讀寫,其他副節點仍為輔助節點,因此為只讀節點。
group_replication_member_weight=80
 
 
 
 
#少數組成員由於網絡中斷且無法連接到多數成員的成員在離開組之前等待多長時間參數
#少數組將永遠等待網絡重新連接。在使用停止組復制之前,將阻止少數組處理的任何事務
loose-group_replication_unreachable_majority_timeout=5
 
 
 
 
 
#壓縮發生在組通信引擎級別,之前數據被交給組通信線程,所以它發生在mysql用戶會話線程的上下文中。事務有效網絡負載可以在被發送到組之前被壓縮,
#並且在被接收時被解壓縮。壓縮是有條件的,並且取決於配置的閾值。默認情況下啟用壓縮,此外,它並不要求組中的所有服務器節點都啟用壓縮機制,
#在接收到消息時,成員檢查消息信封以驗證它是否被壓縮,如果需要,則成員解壓縮該事務,然后將其傳遞到上層
#默認情況下啟用壓縮,閾值為1000000字節(1MB)。壓縮閾值以字節為單位。
#美團這里設置為128k。
group_replication_compression_theeshold=131072
 
 
 
 
 
#配置組接受的最大事務大小(以字節為單位)。
#回滾大於此大小的事務。使用此選項可避免導致組失敗的大型事務。
#大型事務可能導致組的問題,無論是在內存分配還是網絡帶寬消耗方面,
#這可能導致故障檢測器觸發,因為給定成員在忙於處理大事務時無法訪問。
#設置為0時,組接受的事務大小沒有限制,並且可能存在導致組失敗的大型事務的風險。根據組中所需的工作負載大小調整此變量的值。
group_replication_transaction_size_limit=20971520
2:主節點建立復制賬戶,安裝組復制插件,開啟組復制,這里插入測試數據,為了體現mgr的一些限制和特性
     比如不支持MYISAM引擎。綠色字體插入數據報錯。
create user repl@'%' identified by 'repl123'; grant replication slave on *.* to repl@'%'; change master to master_user='repl', master_password='repl123'
            for channel 'group_replication_recovery'; select * from mysql.slave_relay_log_info\G install plugin group_replication soname 'group_replication.so'; set @@global.group_replication_bootstrap_group=on; ---->是否是Group Replication的引導節點,初次搭建集群的時候需要有一個節點設置為ON來啟動Group Replication start group_replication; set @@global.group_replication_bootstrap_group=off; select * from performance_schema.replication_group_members; create database test; use test; create table t1(id int); create table t2(id int)engine=myisam; create table t3(id int primary key)engine=myisam; --->不支持 create table t4(id int primary key);

3:其它節點加入組復制

 change master to master_user='repl', master_password='repl123'
            for channel 'group_replication_recovery'; install plugin group_replication soname 'group_replication.so'; set global group_replication_allow_local_disjoint_gtids_join=1; start group_replication; 

注意:

一個節點加入組復制會有本地的事物產生,比如更改密碼,加入測試數據等。上述紅字可以可以規避上述事務,強制加入,也可以在本地事務開始之前進行

sql_log_bin=0;
start transaction..........
sql_log_bin=1

 

4:維護

   任意一節點啟動,停止組復制。

 

start group_replication;
stop group_replication;

 

查看所有在線的組復制節點

select * from performance_schema.replication_group_members;

 

查看誰是主節點,單主模式下,能查出值,多主模式下無法查出。

select b.member_host the_master,a.variable_value master_uuid
    from performance_schema.global_status a
    join performance_schema.replication_group_members b
    on a.variable_value = b.member_id
    where variable_name='group_replication_primary_member';


+------------+--------------------------------------+
| the_master | master_uuid |
+------------+--------------------------------------+
| calldb3 | cc4958ae-a1cc-11e8-9334-00155d322c00 |
+------------+--------------------------------------+

 

 

三:vip的實施

       mgr 並不提供vip 的概念。在單主模式下,必須啟用vip實現才能做到 HA 的作用,這里的策略網絡上也很多,我們基於keepalived 進行思考

      

要實現上述策略,考慮故障節點的情況

1:故障節點 mysql 實例崩潰,守護進程也不能拉起改實例,需要VIP 漂移。

2:故障節點系統崩潰,段時間無法進行恢復。需要VIP 漂移。

3:判定誰是主節點,vip就漂移到主節點

基於以上3點。keepalived 除了系統故障vip漂移的功能,還需要mysql 實例崩潰的判定主節點漂移功能

具體實現:

[root@calldb1 ~]# cat /etc/keepalived/keepalived.conf
vrrp_script chk_mysql_port {
script "/etc/keepalived/chk_mysql.sh"  ---判斷實例存活
interval 2
weight -5
fall 2
rise 1
}
vrrp_script chk_mysql_master {
script "/etc/keepalived/chk_mysql2.sh"  ---判斷主節點
interval 2
weight 10
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 88
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.0.100
}

track_script {
chk_mysql_port
chk_mysql_master
}

}

判定腳本如下:

[root@calldb1 ~]# cat /etc/keepalived/chk_mysql.sh
#!/bin/bash
netstat -tunlp |grep mysql
a=`echo $?`
if [ $a -eq 1 ] ;then
service keepalived stop
fi
[root@calldb1 ~]# cat /etc/keepalived/chk_mysql2.sh
#!/bin/bash
host=`/data/mysql/bin/mysql -h127.0.0.1 -uroot -pxxx -e "SELECT * FROM performance_schema.replication_group_members WHERE MEMBER_ID = (SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member')" |awk 'NR==2{print}'|awk -F" " '{print $3}'`
host2=`hostname`
if [ $host == $host2 ] ;then
exit 0
else
exit 1
fi

 

 四:采坑的地方:

1:一個節點加入組的時候,因沒有種子的概念,那么它就是中心,所以要申明他是中心:

set @@global.group_replication_bootstrap_group=on;

 2:如果沒有在etc/hosts 文件配置ip地址到主機的解析,那么組復制一直會出現:

2019-04-30T21:58:24.604720+08:00 42 [Note] Plugin group_replication reported: 'Retrying group recovery connection with another donor. Attempt 6/10'
2019-04-30T21:59:24.605458+08:00 42 [Note] 'CHANGE MASTER TO FOR CHANNEL 'group_replication_recovery' executed'. Previous state master_host='sanborn1', master_port= 3306, master_log_file='', master_log_pos= 4, master_bind=''. New state master_host='sanborn1', master_port= 3306, master_log_file='', master_log_pos= 4, master_bind=''.
2019-04-30T21:59:24.610029+08:00 42 [Note] Plugin group_replication reported: 'Establishing connection to a group replication recovery donor 75af6fe1-6a92-11e9-8bf8-005056a1d54e at sanborn1 port: 3306.'
2019-04-30T21:59:24.611927+08:00 50 [Warning] Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
2019-04-30T21:59:24.645794+08:00 50 [ERROR] Slave I/O for channel 'group_replication_recovery': error connecting to master 'repl@sanborn1:3306' - retry-time: 60  retries: 1, Error_code: 2005
2019-04-30T21:59:24.645847+08:00 50 [Note] Slave I/O thread for channel 'group_replication_recovery' killed while connecting to master
2019-04-30T21:59:24.645861+08:00 50 [Note] Slave I/O thread exiting for channel 'group_replication_recovery', read up to log 'FIRST', position 4
2019-04-30T21:59:24.646002+08:00 42 [ERROR] Plugin group_replication reported: 'There was an error when connecting to the donor server. Please check that group_replication_recovery channel credentials and all MEMBER_HOST column values of performance_schema.replication_group_members table are correct and DNS resolvable.'
2019-04-30T21:59:24.646064+08:00 42 [ERROR] Plugin group_replication reported: 'For details please check performance_schema.replication_connection_status table and error log messages of Slave I/O for channel group_replication_recovery.'
2019-04-30T21:59:24.646271+08:00 42 [Note] Plugin group_replication reported: 'Retrying group recovery connection with another donor. Attempt 7/10'

 

 直到脫離群集,狀態一直是recovering

 

mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 75af6fe1-6a92-11e9-8bf8-005056a1d54e | sanborn1    |        3306 | ONLINE       |
| group_replication_applier | 8e091df0-6b4c-11e9-896b-005056a175f4 | sanborn2    |        3306 | RECOVERING   |
| group_replication_applier | ae657017-6b4c-11e9-8548-005056a1c149 | sanborn3    |        3306 | RECOVERING   |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.01 sec)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM