MySQL Group Replication组复制单主模式部署方法

MySQL Group Replication(MGR)是自MySQL 5.7.17版本引入的一个服务器插件,可用于创建高可用、可扩展、容错的复制拓扑结构。

组复制可以在单主模式下操作,其中只有一个服务器接受更新,这个单主是系统自动选举出来的。对于高级用户,也可以部署为多主模式,其中所有服务器都可以接受更新。

MGR对属于同一组的服务器自动进行协调,对于要提交的事务,组成员必须就全局事务序列中给定事务的顺序达成一致。提交或回滚事务由每个服务器单独完成,但所有服务器都必须做出相同的决定。如果存在网络分区,导致成员无法达成事先定义的分割策略,则在解决此问题之前系统不会继续进行,这是一种内置的自动裂脑保护机制。

MGR由组通信系统(Group Communication System,GCS)协议支持,该系统提供故障检测机制、组成员服务以及安全且有序的消息传递。所有这些属性都是创建系统的关键,可确保在服务器组中一致地复制数据。该技术的核心是Paxos算法的实现,它充当组通信引擎。

使用场景

  1. 弹性复制。服务器的数量能够动态增加或减少,并且尽可能减小副作用,例如云数据库服务。
  2. 高可用分片。分片是实现写扩展的流行方法,MGR实现高可用分片,其中每个分片映射到复制组。
  3. 主从复制的替代方案。某些情况下,使用单个主服务器会使其成为热点,写入整组更具可扩展性。

基本条件

  1. 必须使用InnoDB存储引擎。
  2. 每个数据表都必须有主键。

系统环境

本人测试环境的操作系统采用CentOS7.9,mysql版本为8.0.23,对应的mysql-shell和mysql-router均为8.0.23。

主机名 主机IP 应用集
mysql-cluster-router-1 10.10.200.201 mysql, mysql-router, mysql-shell
mysql-cluster-router-2 10.10.200.202 mysql, mysql-router
mysql-cluster-router-3 10.10.200.203 mysql, mysql-router

建议mysql-server和mysql-router部署在一起,mysql-shell可以创建新服务器单独部署。

设置防火墙

# 设置selinux
setenforce 0
sed -i '/^SELINUX/s/enforcing/disabled/g' /etc/selinux/config

# 如果不能禁用selinux,须安装semanage
# yum install -y policycoreutils-python-utils
# 放行组复制通信端口33061
# semanage port -a -t mysqld_port_t -p tcp 33061
# 设置seboolean
# setsebool -P mysql_connect_any=ON

# 设置firewalld
# 禁用firewalld,或者放行mysql端口,一般选择放行端口
firewall-cmd --permanent --zone=public --add-port=3306/tcp
firewall-cmd --permanent --zone=public --add-port=3316/tcp
firewall-cmd --permanent --zone=public --add-port=3326/tcp
firewall-cmd --permanent --zone=public --add-port=33061/tcp
firewall-cmd --reload

安装MySQL8

配置yum源(Redhat7/CentOS7),修改/etc/yum.repos.d/mysql-community.repo

[mysql80-community]
name=MySQL 8.0 Community Server
baseurl=http://repo.mysql.com/yum/mysql-8.0-community/el/7/$basearch/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql

安装MySQL8

yum clean all
yum makecache
yum install mysql-community-server

离线安装方法可参照MySQL5.7升级至MySQL8.0详细步骤中的相关内容。

配置MySQL8

# 先通过以下命令生成组ID,备用
uuidgen
# 生成的uuid:2e5cc2a4-13f8-441f-a25d-cb6f53e14da9

修改配置文件/etc/my.cnf

[mysqld]

datadir   = /var/lib/mysql
socket    = /var/lib/mysql/mysql.sock

log-error = /var/log/mysqld.log
pid-file  = /var/run/mysqld/mysqld.pid

# 本配置文件中的部分参数并非唯一,请根据实际需求调整

# 设置时区和字符集
default-time_zone    = '+8:00'
character-set-server = utf8mb4
collation-server     = utf8mb4_general_ci
skip-character-set-client-handshake

# 设置默认的密码认证方式
default-authentication-plugin = mysql_native_password

# 设置数据库引擎
disabled_storage_engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
sql_mode                 = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

# 集群相关设置
# 另外两台mysql的server_id分别是202和203
server_id                 = 201
gtid_mode                 = ON
enforce_gtid_consistency  = 1
master_info_repository    = TABLE
relay_log_info_repository = TABLE
binlog_checksum           = NONE
log_slave_updates         = ON

# 开启binlog日志
log-bin               = mysql-bin
binlog_format         = ROW
max_binlog_size       = 1G
binlog_cache_size     = 8M
max_binlog_cache_size = 256M

# 需要创建目录/var/lib/mysql/bin-log
relay-log       = /var/lib/mysql/bin-log/relay-log
relay-log-index = /var/lib/mysql/bin-log/relay-log-index

binlog_transaction_dependency_tracking = WRITESET
slave_parallel_type                    = LOGICAL_CLOCK
slave_preserve_commit_order            = ON

slow_query_log                = ON
slow_query_log_file           = /var/log/mysql/mysqld-slow.log
long_query_time               = 5
log_queries_not_using_indexes = OFF

# 禁用域名访问
skip-name-resolve
report-host = '10.10.200.201'

# 组复制基本配置

transaction_write_set_extraction   = XXHASH64
loose-group_replication_group_name = "2e5cc2a4-13f8-441f-a25d-cb6f53e14da9"

# 集群启动后立即复制
loose-group_replication_start_on_boot   = ON
# 另外两台mysql的loose-group_replication_local_address分别改为各自的IP
loose-group_replication_local_address   = "10.10.200.201:33061"
loose-group_replication_group_seeds     = "10.10.200.201:33061,10.10.200.202:33061,10.10.200.203:33061"
loose-group_replication_bootstrap_group = OFF
loose-group_replication_ip_whitelist    = "10.10.200.0/24"
# 启用单一主节点模式,多主易脑裂
loose-group_replication_single_primary_mode              = ON
loose-group_replication_enforce_update_everywhere_checks = OFF

初始化mysql:

# 创建bin-log日志目录:
mkdir -p /var/lib/mysql/bin-log
# 启动mysql
systemctl start mysqld
# 获取初始密码
grep "temporary password" /var/log/mysqld.log
# 登录mysql
mysql -uroot -p

配置MySQL复制账号:

set sql_log_bin=0;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'PASSword_123';

CREATE USER 'mycluster'@'%' identified by 'MyCluster_123';
grant all privileges on *.* to 'mycluster'@'%' with grant option;

flush privileges;
quit

安装MySQL-Shell

访问MySQL-Shell下载页面获取对应版本的mysql-shell,以8.0.23版本为例:

wget https://dev.mysql.com/get/Downloads/MySQL-Shell/mysql-shell-8.0.23-1.el7.x86_64.rpm
yum -y localinstall mysql-shell-8.0.23-1.el7.x86_64.rpm

配置集群

在任意一台安装了mysql-shell的主机上执行集群配置操作即可。

mysqlsh --log-level=DEBUG3

# 检查节点配置状态
dba.checkInstanceConfiguration('mycluster@10.10.200.201:3306');
dba.checkInstanceConfiguration('mycluster@10.10.200.202:3306');
dba.checkInstanceConfiguration('mycluster@10.10.200.203:3306');

# 配置节点
dba.configureLocalInstance('mycluster@10.10.200.201');
dba.configureLocalInstance('mycluster@10.10.200.202');
dba.configureLocalInstance('mycluster@10.10.200.203');

# 创建集群
shell.connect('mycluster@10.10.200.201:3306');
var cluster = dba.createCluster('myCluster');

# 将节点加入集群
cluster.addInstance('mycluster@10.10.200.202:3306');
cluster.addInstance('mycluster@10.10.200.203:3306');

# 检查集群状态
cluster.status()
cluster.describe();

# 检查节点运行状态
cluster.checkInstanceState('mycluster@10.10.200.201:3306');
cluster.checkInstanceState('mycluster@10.10.200.202:3306');
cluster.checkInstanceState('mycluster@10.10.200.203:3306');

# 退出mysqlsh
\q

节点配置状态正常,其他两个节点也是ok状态才行

成功配置节点,其他两个节点相同

成功将节点加入集群,其他两个节点相同

执行以下SQL语句验证集群:

SELECT * from performance_schema.replication_group_members;
SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'group_replication_primary_member';

集群管理常用命令

mysqlsh --log-level=DEBUG3

# 重启集群方法,慎用!!!
# 一般在整个集群停宕以后使用,且启动过程很慢
dba.rebootClusterFromCompleteOutage('myCluster');

# 将节点重新加入集群
cluster.rejoinInstance('mycluster@10.10.200.203')

销毁集群

执行以下MySQL-shell命令解散集群:

shell.connect('mycluster@10.10.200.201:3306')
var cluster = dba.getCluster('myCluster')
cluster.removeInstance('mycluster@10.10.200.202:3306',{force:true})
cluster.removeInstance('mycluster@10.10.200.203:3306',{force:true})
cluster.dissolve({force:true})
dba.dropMetadataSchema();

执行以下SQL语句清理数据:

stop group_replication;
reset master;
reset slave;

安装MySQL-Router

访问MySQL-Router下载页面获取对应版本的mysql-router,以8.0.23版本为例:

wget https://dev.mysql.com/get/Downloads/MySQL-Router/mysql-router-community-8.0.23-1.el7.x86_64.rpm
yum -y localinstall mysql-router-community-8.0.23-1.el7.x86_64.rpm

安装完成后,可以通过以下命令初始化mysql-router:

mysqlrouter --bootstrap cluster@10.10.200.201:3306 --directory /opt/mysqlrouter --conf-use-sockets --force --user=root

不过,我个人还是更习惯手动修改配置文件,修改配置/etc/mysqlrouter/mysqlrouter.conf

[DEFAULT]
logging_folder = /var/log/mysqlrouter
runtime_folder = /var/run/mysqlrouter
config_folder  = /etc/mysqlrouter

[logger]
level = INFO

[keepalive]
interval = 60

[routing:myCluster_rw]
bind_address     = 0.0.0.0
bind_port        = 3316
destinations     = 10.10.200.201:3306,10.10.200.202:3306,10.10.200.203:3306
routing_strategy = first-available
protocol         = classic
max_connections  = 65535

[routing:myCluster_ro]
bind_address     = 0.0.0.0
bind_port        = 3326
destinations     = 10.10.200.202:3306,10.10.200.203:3306
routing_strategy = round-robin
protocol         = classic
max_connections  = 65535

建议取消以mysqlrouter为启动用户,修改配置/usr/lib/systemd/system/mysqlrouter.service

[Unit]
Description=MySQL Router
After=syslog.target
After=network.target

[Service]
Type=simple
# 注释以下两行
# User=mysqlrouter
# Group=mysqlrouter

PIDFile=/var/run/mysqlrouter/mysqlrouter.pid

ExecStart=/usr/bin/mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf

PrivateTmp=true

[Install]
WantedBy=multi-user.target

注意配置防火墙(见本文开篇),完成所有动作后启动服务:

systemctl daemon-reload
systemctl enable mysqlrouter
systemctl start mysqlrouter

原创文章禁止转载:技术学堂 » MySQL Group Replication组复制单主模式部署方法

精彩评论

1+8=

感谢您的支持与鼓励

支付宝扫一扫打赏

微信扫一扫打赏