【MySQL】—基于Docker安装部署MySQL高可用之MGR集群
架构原理
MGR(MySQL Group Replication)是MySQL官方在MySQL 5.7.17版本中以插件形式推出的主从复制高可用技术,它基于原生的主从复制,将各节点归入到一个组中,通过组内节点的通信协商(组通信协议基于Paxos算法),实现数据的强一致性、故障探测、冲突检测、节点加组、节点离组等等功能。
这3个节点互相通信,每当有事件发生,都会向其他节点传播该事件,然后协商,如果大多数节点都同意这次的事件,那么该事件将通过,否则该事件将失败或回滚。只有一个主节点可以接受写操作,主节点故障时可以自动选举主节点。
优点:
强一致性、高容错性、高扩展性、高灵活性
局限:
仅支持InnoDB表且每张表一定要有一个主键(用于做写入集的冲突检测)、必须打开GTID特性、日志格式为ROW、不支持大事务(大小最好不超过143MB)、一个MGP集群最多支持9个节点(节点过多性能负载大)、不支持外键约束、二进制日志不支持Binlog Event Checksum
局限性总结:
1、不适合大事务场景。
2、要求网络环境好,如果异地,最好使用专线。
3、最多支持9个节点,节点过多性能负载大。
4、不支持外键约束。
5、每张表一定要有一个主键,用于做写入集的冲突检测。
适用场景:
金融交易、重要数据存储、对主从一致性要求高的场景
核心数据总量未过亿
读多写少的应用场景,如互联网电商
一、环境准备
1、查看宿主机的环境
操作系统
[root@kubernetes ~]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core)
Docker版本
[root@kubernetes ~]# docker --versionDocker version 20.10.24, build 297e128
镜像版本
mysql:8.0.20
2、准备环境
拉取镜像
[root@kubernetes ~]# docker pull mysql:8.0.20
创建容器网络
docker network create --subnet=172.72.0.0/24 mysql-network
创建数据目录,mysql的数据目录。
mkdir -p /data/mysql-mgr/mysql-mgr-master/conf.d
mkdir -p /data/mysql-mgr/mysql-mgr-master/data
mkdir -p /data/mysql-mgr/mysql-mgr-slave01/conf.d
mkdir -p /data/mysql-mgr/mysql-mgr-slave01/data
mkdir -p /data/mysql-mgr/mysql-mgr-slave02/conf.d
mkdir -p /data/mysql-mgr/mysql-mgr-slave02/data
二、部署mgr集群
1、拉起容器
docker run -d --name mysql-mgr-master -h mysql-mgr-master \
-p 13066:3306 -p 33011:33011 \
--net=mysql-network --ip 172.72.0.21 \
-v /data/mysql-mgr/mysql-mgr-master/conf.d:/etc/mysql/conf.d -v /data/mysql-mgr/mysql-mgr-master/data:/var/lib/mysql/ \
-e MYSQL_ROOT_PASSWORD=123456 \
-e TZ=Asia/Shanghai \
--privileged=true mysql:8.0.20
docker run -d --name mysql-mgr-slave01 -h mysql-mgr-slave01 \
-p 23066:3306 -p 33012:33012 \
--net=mysql-network --ip 172.72.0.22 \
-v /data/mysql-mgr/mysql-mgr-slave01/conf.d:/etc/mysql/conf.d -v /data/mysql-mgr/mysql-mgr-slave01/data:/var/lib/mysql/ \
-e MYSQL_ROOT_PASSWORD=123456 \
-e TZ=Asia/Shanghai \
--privileged=true mysql:8.0.20
docker run -d --name mysql-mgr-slave02 -h mysql-mgr-slave02 \
-p 33066:3306 -p 33013:33013 \
--net=mysql-network --ip 172.72.0.23 \
-v /data/mysql-mgr/mysql-mgr-slave02/conf.d:/etc/mysql/conf.d -v /data/mysql-mgr/mysql-mgr-slave02/data:/var/lib/mysql/ \
-e MYSQL_ROOT_PASSWORD=123456 \
-e TZ=Asia/Shanghai \
--privileged=true mysql:8.0.20
2、查看集群容器
[root@kubernetes ~]# docker ps -a|grep mysql-mgr
cfd43a333add mysql:8.0.20 "docker-entrypoint.s…" 25 seconds ago Up 24 seconds 0.0.0.0:33013->33013/tcp, :::33013->33013/tcp, 33060/tcp, 0.0.0.0:33066->3306/tcp, :::33066->3306/tcp mysql-mgr-slave02
18c94b5202b7 mysql:8.0.20 "docker-entrypoint.s…" 31 seconds ago Up 31 seconds 0.0.0.0:33012->33012/tcp, :::33012->33012/tcp, 33060/tcp, 0.0.0.0:23066->3306/tcp, :::23066->3306/tcp mysql-mgr-slave01
e0bbcd47f46f mysql:8.0.20 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:33011->33011/tcp, :::33011->33011/tcp, 33060/tcp, 0.0.0.0:13066->3306/tcp, :::13066->3306/tcp mysql-mgr-master[root@kubernetes ~]#
3、修改配置mysql参数配置文件
rm -rf /data/mysql-mgr/mysql-mgr-master/conf.d/my.cnf
rm -rf /data/mysql-mgr/mysql-mgr-slave01/conf.d/my.cnf
rm -rf /data/mysql-mgr/mysql-mgr-slave02/conf.d/my.cnf
mysql-mgr集群master配置文件
cat > /data/mysql-mgr/mysql-mgr-master/conf.d/my.cnf <<"EOF"
[mysqld]
user=mysql
port=3306
character_set_server=utf8mb4
secure_file_priv=''
server-id = 802033060
default-time-zone = '+8:00'
log_timestamps = SYSTEM
log-bin =
binlog_format=row
binlog_checksum=NONE
log-slave-updates=1
skip-name-resolve
auto-increment-increment=2
auto-increment-offset=1
gtid-mode=ON
enforce-gtid-consistency=on
default_authentication_plugin=mysql_native_password
max_allowed_packet = 500M
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay_log=mysql-mgr-master-relay-bin-ip21
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address= "172.72.0.21:33011"
loose-group_replication_group_seeds= "172.72.0.21:33011,172.72.0.22:33012,172.72.0.23:33013"
loose-group_replication_bootstrap_group=OFF
loose-group_replication_ip_whitelist="172.72.0.21,172.72.0.22,172.72.0.23"
report_host=172.72.0.21
report_port=3306
EOF
mysql-mgr集群slave01配置文件
cat > /data/mysql-mgr/mysql-mgr-slave01/conf.d/my.cnf <<"EOF"
[mysqld]
user=mysql
port=3306
character_set_server=utf8mb4
secure_file_priv=''
server-id = 802033061
default-time-zone = '+8:00'
log_timestamps = SYSTEM
log-bin =
binlog_format=row
binlog_checksum=NONE
log-slave-updates=1
gtid-mode=ON
enforce-gtid-consistency=ON
skip_name_resolve
default_authentication_plugin=mysql_native_password
max_allowed_packet = 500M
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay_log=mysql-mgr-slave-relay-bin-ip22
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address= "172.72.0.22:33012"
loose-group_replication_group_seeds= "172.72.0.21:33011,172.72.0.22:33012,172.72.0.23:33013"
loose-group_replication_bootstrap_group=OFF
loose-group_replication_ip_whitelist="172.72.0.21,172.72.0.22,172.72.0.23"
report_host=172.72.0.22
report_port=3306
EOF
mysql-mgr集群slave02配置文件
cat > /data/mysql-mgr/mysql-mgr-slave02/conf.d/my.cnf <<"EOF"
[mysqld]
user=mysql
port=3306
character_set_server=utf8mb4
secure_file_priv=''
server-id = 802033062
default-time-zone = '+8:00'
log_timestamps = SYSTEM
log-bin =
binlog_format=row
binlog_checksum=NONE
log-slave-updates=1
gtid-mode=ON
enforce-gtid-consistency=ON
skip_name_resolve
default_authentication_plugin=mysql_native_password
max_allowed_packet = 500M
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay_log=mysql-mgr-slave-relay-bin-ip23
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address= "172.72.0.23:33013"
loose-group_replication_group_seeds= "172.72.0.21:33011,172.72.0.22:33012,172.72.0.23:33013"
loose-group_replication_bootstrap_group=OFF
loose-group_replication_ip_whitelist="172.72.0.21,172.72.0.22,172.72.0.23"
report_host=172.72.0.23
report_port=3306
EOF
4、做好mysql的配置文件后,重启容器。
[root@kubernetes ~]# docker restart `docker ps -a |grep mysql-mgr |awk -F " " '{print $1}'`
cfd43a333add
18c94b5202b7
e0bbcd47f46f
[root@kubernetes ~]#
5、进入容器内部
5.1、主节点
[root@kubernetes ~]# docker exec -it mysql-mgr-master bash
root@mysql-mgr-master:/# mysql -uroot -p
查看hostname,server_id和server_uuid
mysql>
mysql> select @@hostname,@@server_id,@@server_uuid;
+------------------+-------------+--------------------------------------+| @@hostname | @@server_id | @@server_uuid |+------------------+-------------+--------------------------------------+| mysql-mgr-master | 802033060 | 348ecc41-194c-11ee-9c6e-0242ac480014 |+------------------+-------------+----------------------------------
主节点安装MGR插件
安装插件
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
mysql> show plugins;
2、设置复制账号(所有节点执行)
SET SQL_LOG_BIN=0;
CREATE USER repl@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO repl@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='123456' FOR CHANNEL 'group_replication_recovery';
3、启动MGR单主模式
启动MGR,在主库上执行
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
-- 查看MGR组信息
mysql> SELECT * FROM performance_schema.replication_group_members;
5.2、slave01节点
[root@kubernetes ~]# docker exec -it mysql-mgr-slave01 bash
连接登陆mysql
root@mysql-mgr-slave01:/# mysql -uroot -p、
1、slave01安装插件
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
mysql> show plugins;
2、设置复制账号
SET SQL_LOG_BIN=0;
CREATE USER repl@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO repl@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='123456' FOR CHANNEL 'group_replication_recovery';
3、节点加入MGR从节点01:
START GROUP_REPLICATION;
-- 查看MGR组信息
SELECT * FROM performance_schema.replication_group_members;
5.3、slave02节点
[root@kubernetes ~]# docker exec -it mysql-mgr-slave02 bash
连接登陆mysql
root@mysql-mgr-slave02:/# mysql -uroot -p、
1、slave01安装插件
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
mysql> show plugins;
2、设置复制账号
SET SQL_LOG_BIN=0;
CREATE USER repl@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO repl@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='123456' FOR CHANNEL 'group_replication_recovery';
3、节点加入MGR从节点02:
START GROUP_REPLICATION;
-- 查看MGR组信息
SELECT * FROM performance_schema.replication_group_members;
可以看到,3个节点状态为online,并且主节点为172.72.0.21,只有主节点可以写入,其他节点只读,MGR单主模式搭建成功。