MySQL高可用之組複製技術(3):配置多主模型的組複製

駿馬金龍發表於2018-06-22

MySQL組複製系列文章:

  1. MySQL組複製大綱
  2. MySQL組複製(1):組複製技術簡介
  3. MySQL組複製(2):配置單主模型的組複製
  4. MySQL組複製(3):配置多主模型的組複製
  5. MySQL組複製(4):組複製理論透徹分析

在這一篇,我演示的是如何配置MySQL組複製的多主模型(multi-primary)。在配置上,多主模型的組複製和單主模型基本沒區別。

本文僅為搭建和維護多主模型組複製拋塊小磚,若對其間涉及的術語和理論有所疑惑,可參看:

使用組複製技術,必須要了解它的要求和侷限性。見:組複製的要求和侷限性

1.組複製:單主和多主模型

MySQL組複製支援單主模型和多主模型,它們都能保證MySQL資料庫的高可用。

  1. 單主模型下:
    • 只有一個主節點,該主節點負責所有的寫操作,其他節點作為slave節點提供讀取服務(會自動設定為read-only)。
    • 在主節點故障,單主模型會自動選舉新的主節點。選舉後,剩餘節點將指向該節點。但是,客戶端還是會有部分請求路由到故障的主節點上,因此需要想辦法解決這樣的問題。這不是MySQL該考慮解決的問題,而是客戶端應用程式、資料庫中介軟體(常見的:ProxySQL、MySQL Router、mycat、amoeba、cobar等)該解決的問題。
    • 只要非自願離組的故障節點(自願、非自願離組,請參見配置單主模型的組複製)不超過大多數,組複製就不會被阻塞。
  2. 多主模型下:
    • 沒有master和slave的概念。所有的節點都可以讀、寫資料。
    • 因為所有節點都能提供讀寫服務,所以效能較之單主模型要好一些。
    • 配置多主模型的工作方式,比單主模型的限制更多。
    • 節點非自願故障後,除了影響一點效能,不會對組複製造成影響。除非故障的節點數過多,使得剩餘線上節點達不到”大多數”的要求。

2.單主和多主模型配置檔案的區別

以下是單主模型組複製的配置檔案:

[mysqld]
datadir=/data
socket=/data/mysql.sock

server-id=100                      # 必須
gtid_mode=on                       # 必須
enforce_gtid_consistency=on        # 必須
log-bin=/data/master-bin           # 必須
binlog_format=row                  # 必須
binlog_checksum=none               # 必須
master_info_repository=TABLE       # 必須
relay_log_info_repository=TABLE    # 必須
relay_log=/data/relay-log          # 必須,如果不給,將採用預設值
log_slave_updates=ON               # 必須
sync-binlog=1                      # 建議
log-error=/data/error.log
pid-file=/data/mysqld.pid

transaction_write_set_extraction=XXHASH64         # 必須
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"  # 必須
loose-group_replication_start_on_boot=off        # 建議設定為OFF
loose-group_replication_member_weigth = 40   # 非必需,mysql 5.7.20才開始支援該選項
loose-group_replication_local_address="ABCDEFGHIJK"   # 必須,下一行也必須
loose-group_replication_group_seeds="abcdefg"

其中每一行什麼意思,我在單主模型組複製中做了非常詳細的解釋。

多主模型和單主模型的配置檔案基本相同,除了需要加入:

group_replication_enforce_update_everywhere_checks=ON  # 非必需,但強烈建議
group_replication_single_primary_mode=OFF  # 必須,表示關閉單主模型,即使用多主

需要註釋權重行,因為多主模型下沒有master的概念,所以無需選舉的權重值。

# loose-group_replication_member_weigth = 40

此外,除非業務依賴於預設的repeatable read,否則建議將事務隔離級別設定為read committed,且不能設定為serializable級別(強制要求)。所以,如果允許,還可以加上:

transaction_isolation = `read-committed` 

3.配置多主模型

本文打算配置5個節點的多主模型複製組。

具體環境細節如下:

節點名稱 系統版本 MySQL版本 客戶端介面(eth0) 組內通訊介面(eth0) 資料狀態
s1 CentOS 7 MySQL 5.7.22 192.168.100.21 192.168.100.21 全新例項
s2 CentOS 7 MySQL 5.7.22 192.168.100.22 192.168.100.22 全新例項
s3 CentOS 7 MySQL 5.7.22 192.168.100.23 192.168.100.23 全新例項
s4 CentOS 7 MySQL 5.7.22 192.168.100.24 192.168.100.24 全新例項
s5 CentOS 7 MySQL 5.7.22 192.168.100.25 192.168.100.25 全新例項

每個節點向外提供MySQL服務和組內通訊都使用同一個介面。

1.修改主機名,新增DNS解析。

因為組內每個節點都使用主機名進行解析其他成員的地址,所以必須配置好主機名,並保證每個節點都能正確解析主機名。

在s1上執行:

hostnamectl set-hostname s1.longshuai.com
hostnamectl -H 192.168.100.22 set-hostname s2.longshuai.com
hostnamectl -H 192.168.100.23 set-hostname s3.longshuai.com
hostnamectl -H 192.168.100.24 set-hostname s4.longshuai.com
hostnamectl -H 192.168.100.25 set-hostname s5.longshuai.com

cat >>/etc/hosts<<eof
    192.168.100.21 s1.longshuai.com
    192.168.100.22 s2.longshuai.com
    192.168.100.23 s3.longshuai.com
    192.168.100.24 s4.longshuai.com
    192.168.100.25 s5.longshuai.com
eof

scp /etc/hosts 192.168.100.22:/etc
scp /etc/hosts 192.168.100.23:/etc
scp /etc/hosts 192.168.100.24:/etc
scp /etc/hosts 192.168.100.25:/etc

2.提供配置檔案。

以下是s1節點配置檔案。

[mysqld]
datadir=/data
socket=/data/mysql.sock

server-id=100                      # 必須
gtid_mode=on                       # 必須
enforce_gtid_consistency=on        # 必須
log-bin=/data/master-bin           # 必須
binlog_format=row                  # 必須
binlog_checksum=none               # 必須
master_info_repository=TABLE       # 必須
relay_log_info_repository=TABLE    # 必須
relay_log=/data/relay-log          # 必須,如果不給,將採用預設值
log_slave_updates=ON               # 必須
sync-binlog=1                      # 建議
log-error=/data/error.log
pid-file=/data/mysqld.pid


transaction_isolation = `read-committed`   # 建議項

transaction_write_set_extraction=XXHASH64         # 必須
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"  # 必須
loose-group_replication_enforce_update_everywhere_checks=ON  # 非必需,但強烈建議
loose-group_replication_single_primary_mode=OFF  # 必須,關閉單主模型,即使用多主
loose-group_replication_start_on_boot=off        # 建議設定為OFF
loose-group_replication_local_address="192.168.100.21:20001"   # 必須
# 下一行也必須,這裡我將所有節點都新增到種子節點列表中
loose-group_replication_group_seeds="192.168.100.21:20001,192.168.100.22:20002,192.168.100.23:20003,192.168.100.24:20004,192.168.100.25:20005"

s2、s3、s4和s5節點的配置檔案和s1類似,但server_idloose-group_replication_local_address必須改成各節點對應的值。

s2的配置(未包括和s1相同的配置):

server_id=110
loose-group_replication_local_address="192.168.100.22:20002"

s3的配置(未包括和s1相同的配置):

server_id=120
loose-group_replication_local_address="192.168.100.23:20003"

s4的配置(未包括和s1相同的配置):

server_id=130
loose-group_replication_local_address="192.168.100.24:20004"

s5的配置(未包括和s1相同的配置):

server_id=140
loose-group_replication_local_address="192.168.100.25:20005"

配置結束後,啟動mysqld例項。

systemctl start mysqld

3.建立複製使用者,並設定恢復通道”group_replication_recovery”。

我這裡將s1作為組內的第一個節點。所以只需在s1上建立複製使用者即可,以後其他節點加入組時,會將該操作複製走。

在s1上執行:

mysql> create user repl@`192.168.100.%` identified by `P@ssword1!`;
mysql> grant replication slave on *.* to repl@`192.168.100.%`;

設定恢復階段的非同步複製通道:

在s1上執行:

mysql> change master to 
            master_user=`repl`,
            master_password=`P@ssword1!`
            for channel `group_replication_recovery`;

注意:後面的操作中,如果沒有明確指定在s2、s3、s4和s5上執行,那麼都是在s1上執行的。有些操作是不允許在多個節點上都執行的。

4.在s1上安裝組複製外掛,並引導建立複製組。

安裝組複製外掛,在s1上執行:

mysql> install plugin group_replication soname `group_replication.so`;

以s1節點組的引導節點,在s1上執行:

mysql> set @@global.group_replication_bootstrap_group=on;
mysql> start group_replication;
mysql> set @@global.group_replication_bootstrap_group=off;

執行完上面的語句後,本實驗所需的複製組就已經被節點s1建立了。以後s2-s5節點就可以陸續地加入到組中。

在其他節點加組之前,先看下組中的節點s1是否已ONLINE。

mysql> select * from performance_schema.replication_group_membersG
*************************** 1. row ***************************
CHANNEL_NAME: group_replication_applier
   MEMBER_ID: a659234f-6aea-11e8-a361-000c29ed4cf4
 MEMBER_HOST: s1.longshuai.com
 MEMBER_PORT: 3306
MEMBER_STATE: ONLINE

5.向組中加入新節點:s2、s3、s4、s5。

在s2、s3、s4和s5上都執行:

change master to 
            master_user=`repl`,
            master_password=`P@ssword1!`
            for channel `group_replication_recovery`;

install plugin group_replication soname `group_replication.so`;

然後依次在s2、s3、s4和s5上執行下面的語句開啟組複製功能,開啟該功能後,將自動加入到組中。但注意,要依次執行,在每個start語句返回成功後再去下一個節點執行:

start group_replication;

6.檢視組中成員s1、s2、s3、s4、s5是否全都ONLINE。

在任意一個節點上執行:

mysql> select * from performance_schema.replication_group_membersG
*************************** 1. row ***************************
CHANNEL_NAME: group_replication_applier
   MEMBER_ID: 22e55db0-7604-11e8-b72d-000c29b06c3c
 MEMBER_HOST: s5.longshuai.com
 MEMBER_PORT: 3306
MEMBER_STATE: ONLINE
*************************** 2. row ***************************
CHANNEL_NAME: group_replication_applier
   MEMBER_ID: a5165443-6aec-11e8-a8f6-000c29827955
 MEMBER_HOST: s2.longshuai.com
 MEMBER_PORT: 3306
MEMBER_STATE: ONLINE
*************************** 3. row ***************************
CHANNEL_NAME: group_replication_applier
   MEMBER_ID: a659234f-6aea-11e8-a361-000c29ed4cf4
 MEMBER_HOST: s1.longshuai.com
 MEMBER_PORT: 3306
MEMBER_STATE: ONLINE
*************************** 4. row ***************************
CHANNEL_NAME: group_replication_applier
   MEMBER_ID: ba505889-6aec-11e8-a864-000c29b0bec4
 MEMBER_HOST: s3.longshuai.com
 MEMBER_PORT: 3306
MEMBER_STATE: ONLINE
*************************** 5. row ***************************
CHANNEL_NAME: group_replication_applier
   MEMBER_ID: bf12fe97-6aec-11e8-a909-000c29e55287
 MEMBER_HOST: s4.longshuai.com
 MEMBER_PORT: 3306
MEMBER_STATE: ONLINE
5 rows in set (0.00 sec)

4.測試多主模型的寫負載

多主模型下,所有節點都可以進行讀、寫操作。但請注意,組複製的幾個要求:表必須為innodb表(雖然建立myisam表不報錯,但修改資料會報錯)、每個表必須有主鍵、不能有級聯的外來鍵等。

在任意節點上執行以下寫操作進行測試:

create database mut_gr;
create table mut_gr.t1(id int primary key);
insert into mut_gr.t1 values(1),(2),(3),(4);

在任意節點上繼續執行寫操作:

insert into mut_gr.t1 values(5);

檢視資料是否都已同步到各節點上。

5.更多組複製維護的操作

關於組複製更多維護操作,比如如何重啟組、如何安全退組、如何重新加組等等,還是請參看單主模型的組複製,它們的維護是類似的,所以本文就不對重複內容做贅述了。

相關文章