在这一篇, 我演示的是如何配置 MySQL 组复制的多主模型(multi-primary). 在配置上, 多主模型的组复制和单主模型基本没区别.
本文仅为搭建和维护多主模型组复制抛块小砖, 若对其间涉及的术语和理论有所疑惑, 可参看:
单主模型相关内容的大长文: 配置单主模型的组复制.
组复制的理论: MySQL 组复制官方手册翻译.
使用组复制技术, 必须要了解它的要求和局限性. 见: 组复制的要求和局限性.
1. 组复制: 单主和多主模型
MySQL 组复制支持单主模型和多主模型, 它们都能保证 MySQL 数据库的高可用.
单主模型下:
只有一个主节点, 该主节点负责所有的写操作, 其他节点作为 slave 节点提供读取服务(会自动设置为 read-only).
在主节点故障, 单主模型会自动选举新的主节点. 选举后, 剩余节点将指向该节点. 但是, 客户端还是会有部分请求路由到故障的主节点上, 因此需要想办法解决这样的问题. 这不是 MySQL 该考虑解决的问题, 而是客户端应用程序, 数据库中间件 (常见的: ProxySQL,MySQL Router,mycat,amoeba,cobar 等) 该解决的问题.
只要非自愿离组的故障节点 (自愿, 非自愿离组, 请参见配置单主模型的组复制) 不超过大多数, 组复制就不会被阻塞.
多主模型下:
没有 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 级别(强制要求). 所以, 如果允许, 还可以加上:
tx_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
- tx_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_id 和
loose-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_members\G
- *************************** 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_members\G
- *************************** 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. 更多组复制维护的操作
关于组复制更多维护操作, 比如如何重启组, 如何安全退组, 如何重新加组等等, 还是请参看单主模型的组复制, 它们的维护是类似的, 所以本文就不对重复内容做赘述了.
来源: https://www.cnblogs.com/f-ck-need-u/p/9215013.html