Mysql innodb cluster搭建原理及过程说明

1.架构图

Mysql innodb cluster搭建原理及过程说明


Mysql innodb cluster搭建原理及过程说明

2.原理说明:

MySQL InnoDB集群提供了一个集成的,本地的,HA解决方案。Mysq Innodb Cluster是利用组复制的 pxos 协议,保障数据一致性,组复制支持单主模式和多主模式。

MySQL InnoDB集群由以下几部分组成:

- MySQL Servers with Group Replication:向集群的所有成员复制数据,同时提供容错、自动故障转移和弹性。MySQL Server 5.7.17或更高的版本。

- MySQL Router:确保客户端请求是负载平衡的,并在任何数据库故障时路由到正确的服务器。MySQL Router 2.1.3或更高的版本。

- MySQL Shell:通过内置的管理API创建及管理Innodb集群。MySQL Shell 1.0.9或更高的版本。


3. 准备工作

1) 准备5台服务器


Mysql innodb cluster搭建原理及过程说明

1) 关闭防火墙

2) 各节点配置/etc/hosts的主机名和IP(重要)


3. 搭建过程

1)各软件下载地址

Mysql: https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.28-linux-glibc2.12-x86_64.tar.gz

Mysql-shell: https://dev.mysql.com/get/Downloads/MySQL-Shell/mysql-shell-8.0.19-linux-glibc2.12-x86-64bit.tar.gz

Mysql-router:https://dev.mysql.com/get/Downloads/MySQL-Router/mysql-router-8.0.19-linux-glibc2.12-x86_64.tar.xz

2) 安装mysql5.7.28,此步骤略

3) 解压安装mysql shell,172.16.7.32,172.16.7.33,172.16.7.34 这3台服务器都要安装

[root@db32 local]# tar -zxvf /usr/local/mysql-shell-8.0.19-linux-glibc2.12-x86-64bit.tar.gz

[root@db32 local]# mv mysql-shell-8.0.19-linux-glibc2.12-x86-64bit mysql-shell

[root@db32 local]# export PATH=/usr/local/mysql-shell/bin/:$PATH

以下是测试连接

[root@db32 local]# mysqlsh

MySQL Shell 8.0.19

Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates.

Other names may be trademarks of their respective owners.

Type '\\help' or '\\?' for help; '\\quit' to exit.

MySQL JS >

4) 配置3台服务器的my.cnf参数配置并重启mysql 服务,以下参数是必须的,其他的参数自行添加

172.16.7.32

[mysqld]

character-set-server=utf8mb4

port=3306

socket=/tmp/mysql.sock

basedir=/usr/local/mysql

datadir=/usr/local/mysql/data

log-error=/usr/local/mysql/data/mysql-error.log

pid-file=/usr/local/mysql/data/mysql.pid

user = mysql

tmpdir = /tmp

default-storage-engine=INNODB


#复制框架

server_id=17216732

gtid_mode=ON

enforce_gtid_consistency=ON

master_info_repository=TABLE

relay_log_info_repository=TABLE

binlog_checksum=NONE

log_slave_updates=ON

log_bin=binlog

binlog_format=ROW

max_connections=200

max_allowed_packet=16M

#组复制设置

#server必须为每个事务收集写集合,并使用XXHASH64哈希算法将其编码为散列

transaction_write_set_extraction=XXHASH64

#告知插件加入或创建组命名,UUID

loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"

#server启动时不自启组复制,为了避免每次启动自动引导具有相同名称的第二个组,所以设置为OFF。

loose-group_replication_start_on_boot=off

#告诉插件使用IP地址,端口33061用于接收组中其他成员转入连接

loose-group_replication_local_address="172.16.7.32:33061"

#启动组server,种子server,加入组应该连接这些的ip和端口;其他server要加入组得由组成员同意

loose-group_replication_group_seeds="172.16.7.32:33061,172.16.7.33:33061,172.16.7.34:33061"

loose-group_replication_ip_whitelist="172.16.7.32,172.16.7.33,172.16.7.34,127.0.0.1/8"

loose-group_replication_bootstrap_group=off

# 使用MGR的单主模式

loose-group_replication_single_primary_mode=on

loose-group_replication_enforce_update_everywhere_checks=off

172.16.7.33

[mysqld]

character-set-server=utf8mb4

port=3306

socket=/tmp/mysql.sock

basedir=/usr/local/mysql

datadir=/usr/local/mysql/data

log-error=/usr/local/mysql/data/mysql-error.log

pid-file=/usr/local/mysql/data/mysql.pid

user = mysql

tmpdir = /tmp

default-storage-engine=INNODB


#复制框架

server_id=17216733

gtid_mode=ON

enforce_gtid_consistency=ON

master_info_repository=TABLE

relay_log_info_repository=TABLE

binlog_checksum=NONE

log_slave_updates=ON

log_bin=binlog

binlog_format=ROW

max_connections=200

max_allowed_packet=16M

#组复制设置

#server必须为每个事务收集写集合,并使用XXHASH64哈希算法将其编码为散列

transaction_write_set_extraction=XXHASH64

#告知插件加入或创建组命名,UUID

loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"

#server启动时不自启组复制,为了避免每次启动自动引导具有相同名称的第二个组,所以设置为OFF。

loose-group_replication_start_on_boot=off

#告诉插件使用IP地址,端口33061用于接收组中其他成员转入连接

loose-group_replication_local_address="172.16.7.33:33061"

#启动组server,种子server,加入组应该连接这些的ip和端口;其他server要加入组得由组成员同意

loose-group_replication_group_seeds="172.16.7.32:33061,172.16.7.33:33061,172.16.7.34:33061"

loose-group_replication_ip_whitelist="172.16.7.32,172.16.7.33,172.16.7.34,127.0.0.1/8"

loose-group_replication_bootstrap_group=off

# 使用MGR的单主模式

loose-group_replication_single_primary_mode=on

loose-group_replication_enforce_update_everywhere_checks=off

172.16.7.34

[mysqld]

character-set-server=utf8mb4

port=3306

socket=/tmp/mysql.sock

basedir=/usr/local/mysql

datadir=/usr/local/mysql/data

log-error=/usr/local/mysql/data/mysql-error.log

pid-file=/usr/local/mysql/data/mysql.pid

user = mysql

tmpdir = /tmp

default-storage-engine=INNODB


#复制框架

server_id=17216734

gtid_mode=ON

enforce_gtid_consistency=ON

master_info_repository=TABLE

relay_log_info_repository=TABLE

binlog_checksum=NONE

log_slave_updates=ON

log_bin=binlog

binlog_format=ROW

max_connections=200

max_allowed_packet=16M

#组复制设置

#server必须为每个事务收集写集合,并使用XXHASH64哈希算法将其编码为散列

transaction_write_set_extraction=XXHASH64

#告知插件加入或创建组命名,UUID

loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"

#server启动时不自启组复制,为了避免每次启动自动引导具有相同名称的第二个组,所以设置为OFF。

loose-group_replication_start_on_boot=off

#告诉插件使用IP地址,端口33061用于接收组中其他成员转入连接

loose-group_replication_local_address="172.16.7.34:33061"

#启动组server,种子server,加入组应该连接这些的ip和端口;其他server要加入组得由组成员同意

loose-group_replication_group_seeds="172.16.7.32:33061,172.16.7.33:33061,172.16.7.34:33061"

loose-group_replication_ip_whitelist="172.16.7.32,172.16.7.33,172.16.7.34,127.0.0.1/8"

loose-group_replication_bootstrap_group=off

# 使用MGR的单主模式

loose-group_replication_single_primary_mode=on

loose-group_replication_enforce_update_everywhere_checks=off

2) 创建cluster集群

1).进到172.16.7.32的 mysql-shell 的安装目录,登陆mysql-shell

bin/mysqlsh

复制代码

mysql-js> shell.connect('root@localhost:3306');

#连接成功后

#配置实例

dba.configureLocalInstance();

#此时会让选择创建管理cluster的用户,我选1,使用root管理,并且允许远程登陆“%”

#接着查看实例状态

dba.checkInstanceConfiguration("root@localhost:3306");

复制代码

如果出现:

You can now use it in an InnoDB Cluster.

{

"status": "ok"

}

说明配置成功。

2).登陆manager管理节点,讲router和shell都解压到/usr/local/文件夹下分别为mysql-route和mysql-shell

3).登陆manager节点的shell,连接master,创建cluster

复制代码

bin/mysqlsh

# 连接01

mysql-js> shell.connect('[email protected]:3306');

# 创建一个 cluster,命名为 'myCluster'

mysql-js> var cluster = dba.createCluster('myCluster');

# 创建成功后,查看cluster状态

mysql-js> cluster.status();

创建后,可以看到master已经添加进cluster,

MySQL 172.16.7.32:3306 ssl JS > cluster.status();

{

"clusterName": "myCluster",

"defaultReplicaSet": {

"name": "default",

"primary": "db32:3306",

"ssl": "REQUIRED",

"status": "OK_NO_TOLERANCE",

"statusText": "Cluster is NOT tolerant to any failures.",

"topology": {

"db32:3306": {

"address": "db32:3306",

"mode": "R/W",

"readReplicas": {},

"role": "HA",

"status": "ONLINE"

}

},

"topologyMode": "Single-Primary"

},

"groupInformationSourceMember": "db32:3306"

}

3) 添加172.16.7.33从节点,登录到172.16.7.33服务器上面执行

登陆shell,执行配置

bin/mysqlsh

mysql-js> shell.connect('root@localhost:3306');

mysql-js> dba.configureLocalInstance();

停掉mysql服务,在配置文件my.cnf末尾添加配置:

loose-group_replication_allow_local_disjoint_gtids_join=ON

重启mysql后,通过manager节点的shell,将slave1添加到cluster:

# 添加实例,在主节点(172.16.7.32)上面执行

cluster.addInstance('[email protected]:3306');

# 创建成功后,查看cluster状态

mysql-js> cluster.status();

成功后状态:

MySQL 172.16.7.32:3306 ssl JS > cluster.status();

{

"clusterName": "myCluster",

"defaultReplicaSet": {

"name": "default",

"primary": "db32:3306",

"ssl": "REQUIRED",

"status": "OK_NO_TOLERANCE",

"statusText": "Cluster is NOT tolerant to any failures.",

"topology": {

"db32:3306": {

"address": "db32:3306",

"mode": "R/W",

"readReplicas": {},

"role": "HA",

"status": "ONLINE"

},

"db33:3306": {

"address": "db33:3306",

"mode": "R/O",

"readReplicas": {},

"role": "HA",

"status": "ONLINE"

}

},

"topologyMode": "Single-Primary"

},

"groupInformationSourceMember": "db32:3306"

}

4) 添加172.16.7.34从节点,登录到172.16.7.34服务器上面执行

登陆shell,执行配置

bin/mysqlsh

mysql-js> shell.connect('root@localhost:3306');

mysql-js> dba.configureLocalInstance();

停掉mysql服务,在配置文件my.cnf末尾添加配置:

loose-group_replication_allow_local_disjoint_gtids_join=ON

重启mysql后,通过manager节点的shell,将slave1添加到cluster:

# 添加实例,在主节点(172.16.7.32)上面执行

cluster.addInstance('[email protected]:3306');

# 创建成功后,查看cluster状态

mysql-js> cluster.status();

成功后状态:

MySQL 172.16.7.32:3306 ssl JS > cluster.status();

{

"clusterName": "myCluster",

"defaultReplicaSet": {

"name": "default",

"primary": "db32:3306",

"ssl": "REQUIRED",

"status": "OK",

"statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",

"topology": {

"db32:3306": {

"address": "db32:3306",

"mode": "R/W",

"readReplicas": {},

"role": "HA",

"status": "ONLINE"

},

"db33:3306": {

"address": "db33:3306",

"mode": "R/O",

"readReplicas": {},

"role": "HA",

"status": "ONLINE"

},

"db34:3306": {

"address": "db34:3306",

"mode": "R/O",

"readReplicas": {},

"role": "HA",

"status": "ONLINE"

}

},

"topologyMode": "Single-Primary"

},

"groupInformationSourceMember": "db32:3306"

}


2) 问题描述,如果从库发生重启,那么重启后节点不在MGR组里面了,通过start group_replication;命令不成功,那么则设置

show variables like '%gtids_join%';

set global group_replication_bootstrap_group=on;

set global slave_preserve_commit_order=on;

start group_replication;

问题2

Dba.getCluster: Dba.getCluster: Unable to get cluster. The instance 'host-192-168-1-101:3306'

may belong to a different ReplicaSet as the one registered in the Metadata since the value of 'group_replication_group_name'

does not match the one registered in the ReplicaSet's Metadata: possible split-brain scenario. Please connect to another member of the ReplicaSet to get the Cluster. (RuntimeError)

//最致命的错误,master/slave的数据不一致所致,没办法,只能重新来

dba.dropMetadataSchema();

问题3

如果slave起不起来,则执行以下

set global group_replication_bootstrap_group=on;

set global slave_preserve_commit_order=on;

show variables like '%replication_allow_local_disjoint_gtids_join%';

show variables like '%slave_preserve_commit_order%';

set global group_replication_allow_local_disjoint_gtids_join=ON;

start group_replication;


问题4

作者在搭建过程中出现slave节点在重启mysql服务器,start group_replication 报错,无论如何都不能开启

错误提示如下:

2020-03-23T11:01:08.364104Z 0 [Warning] Plugin group_replication reported: 'read failed'

2020-03-23T11:01:08.383678Z 0 [ERROR] Plugin group_replication reported: '[GCS] The member was unable to join the group. Local port: 33061'

2020-03-23T11:02:08.315089Z 2 [ERROR] Plugin group_replication reported: 'Timeout on wait for view after joining group'

2020-03-23T11:02:08.315188Z 2 [Note] Plugin group_replication reported: 'Requesting to leave the group despite of not being a member'

2020-03-23T11:02:08.315242Z 2 [ERROR] Plugin group_replication reported: '[GCS] The member is leaving a group without being on one.'

最后通过添加my.cnf配置白名单解决,但是如果本机有多个IP,记得添加多个

loose-group_replication_ip_whitelist="172.16.7.32,172.16.7.33,172.16.7.34,127.0.0.1/8"

3. 安装mysql-router及配置mysql-router

172.16.7.30 172.16.7.31上面执行以下命令

[root@db30 local]# tar -Jxvf mysql-router-8.0.19-linux-glibc2.12-x86_64.tar.xz

[root@db30 local]# mv mysql-router-8.0.19-linux-glibc2.12-x86_64/ mysqlrouter

[root@db30 local]# echo 'export PATH=/usr/local/mysqlrouter/bin/:$PATH' >> /etc/profile

[root@db30 local]# source /etc/profile

[root@db30 local]# /usr/local/mysql-router/bin/mysqlrouter --bootstrap [email protected]:3306 -d myrouter --user=root

这里会在当前目录下产生mysql-router 目录, 并生成router配置文件,默认通过route连接mysql后, 6446端口连接后可以进行读写操作. 6447端口连接后只能进行只读操作.

然后启动mysql-route

myrouter/start.sh

查看route进程:

ps -ef|grep myrouter

netstat -tunlp|grep (route的pid)

这样就可以使用MySQL客户端连接router了. 下面验证下连接router:

a) 管理节点本机mysql-shell连接:

mysqlsh --uri root@localhost:6446

b) 管理节点本机mysql连接:

mysql -u root -h 127.0.0.1 -P 6446 -p

c) 远程客户机通过route连接mysql

mysql -u root -h manager_ip -P 6446 -p

4. 配置myrouter的keepalived 以下是172.16.7 30的配置,172.16.7.31的配置参考30服务器即可

keepalived.conf脚本如下:

! Configuration File for keepalived

global_defs {

notification_email {

[email protected]

[email protected]

[email protected]

}

notification_email_from [email protected]

smtp_server 192.168.200.1

smtp_connect_timeout 30

router_id LVS_DEVEL

vrrp_skip_check_adv_addr

#vrrp_strict

vrrp_garp_interval 0

vrrp_gna_interval 0

}

vrrp_script checkmysqlrouter {

script "/etc/keepalived/check_myrouter.sh"

interval 2

weight -20

fall 3

rise 2

}


vrrp_instance VI_1 {

state MASTER

interface ens32

virtual_router_id 51

priority 100

advert_int 1

authentication {

auth_type PASS

auth_pass 1111

}

virtual_ipaddress {

172.16.7.35

}

track_script {

checkmysqlrouter

}

}

check_myrouter.sh脚本如下

#!/bin/sh

aa=`ps -fe|grep myrouter |wc -l`

echo $aa

if [ $aa -ne 4 ]

then

service keepalived stop

#echo "aaa"

else

echo "runing....."

fi

5. 获取群集信息 mager节点执行(172.16.7.32)

mysql-js> shell.connect('root@localhost:3306');

MySQL localhost:3306 ssl JS > var aa=dba.getCluster('myCluster');

MySQL localhost:3306 ssl JS > aa.status();


分享到:


相關文章: