MySQL官方在4月终于推出了一套完整的、高可用的Mysql解决方案--MySQL InnoDB Cluster。这绝对是程序员的福音。以往做mysql主从高可用非常繁琐,很多坑。现在利用官方的解决方案--MySQL InnoDB Cluster可以比较方便的搭建mysql高可用集群,虽然也挺多坑的。
至于--MySQL InnoDB Cluster有什么优点缺点,这里不比较了,可以到官网直接看就好。
最近刚好项目需要搭建数据库高可用,于是便尝试使用官方推荐的方案--MySQL InnoDB Cluster。
因为这个是新推出的,网上这方面的资料比较少,官方的文档也介绍太简单,我在搭建过程中也遇到很多问题。
最后还是成功搭建,这里把搭建过程给大家分享一下,希望对需要的朋友有所帮助。
开始:
1、准备需要的环境
我使用的系统版本:centos7.x
首先下载搭建需要的软件:
mysql 下载地址:
https://dev.mysql.com/downloads/mysql/
mysql-shell 下载地址:
https://dev.mysql.com/downloads/shell/
mysql-router 下载地址:
https://dev.mysql.com/downloads/router/
都选择 Linux Generic 版本即可
准备3台服务器,node01、node02、node03
node01作为 cluster 节点,负责创建 cluster,并作为 cluster 的路由
2、环境配置
在各台服务器中配置好 hosts,这一步很重要,否则可能会出现无法同步的情况,因为数据库需要根据member_host同步,如果不配置,默认就是localhost,这样时无法通信的。
# vim /etc/hosts
如:
172.30.12.20 node03
172.30.12.17 node02
172.30.12.14 node01
让hosts文件生效
# source /etc/hosts
然后重启服务器:
# reboot -f
通过命令 hostnamectl 查看瞬态主机名称是否是设置的名称
Static hostname: localhost.localdomain
Transient hostname: node01 #这个就是瞬态主机名称,mysql会根据这个来设置host
Icon name: computer-desktop
Chassis: desktop
Machine ID: 9ac67df3c56f4ff18f0a7855490589bc
Boot ID: f6f4356539884b8ba2ee79774b918359
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-514.el7.x86_64
Architecture: x86-64
如果你不想重启服务器,也可以通过下面的命令动态设置:
hostnamectl --transient set-hostname node01
(1)安装基础软件
node 01、02、03 上安装好 mysql
与 mysql-shell
node01 上安装 mysql-router
2. shell
# 直接解压即可
tar zxf mysql-shell-1.0.9-linux-glibc2.12-x86-64bit.tar.gz mysql-shell
# 直接解压即可
tar zxf mysql-router-2.1.3-linux-glibc2.12-x86-64bit.tar.gz mysql-router
在node01的mysql配置文件加入高可用和集群配置(根据自己的情况设置目录):
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8
socket=/usr/mysql/mysql/lib/mysql.sock
[mysqld]
#skip-name-resolve
#设置3306端口
port = 3306
socket=/usr/mysql/mysql/lib/mysql.sock
# 设置mysql的安装目录
basedir=/usr/mysql/mysql
# 设置mysql数据库的数据的存放目录
datadir=/usr/mysql/mysql/data
# 允许最大连接数
max_connections=200
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
max_allowed_packet=16M
#高可用
server_id=1
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
transaction_write_set_extraction=XXHASH64
#主从复制配置
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
#注意:这里的地址不能用 node01:24901 这种写法,要用IP,否则无法通信
loose-group_replication_local_address= "172.30.12.14:24901"
loose-group_replication_group_seeds= "172.30.12.14:24901,172.30.12.17:24901,172.30.12.20:24901"
loose-group_replication_single_primary_mode=TRUE
#loose-group_replication_bootstrap_group= off
#loose-group_replication_enforce_update_everywhere_checks= FALSE
#loose-group_replication_start_on_boot=off
disabled_storage_engines = MyISAM,BLACKHOLE,FEDERATED,CSV,ARCHIVE
report_port = 3306
进到 mysql-shell 的安装目录,登录 shell ,执行配置
bin/mysqlsh
连接到本机MySQL,执行配置命令
# 连接,需要输入密码(123456)
mysql-js> shell.connect('root@localhost:3306');
# 执行配置命令,也需要密码
mysql-js> dba.configureLocalInstance();
Please provide the password for 'root@localhost:3306':
Detecting the configuration file...
Default file not found at the standard locations.
Please specify the path to the MySQL configuration file: /etc/my.cnf
MySQL user 'root' cannot be verified to have access to other hosts in the network.
Detecting the configuration file...
Found configuration file at standard location: /etc/my.cnf
Do you want to modify this file? [Y|n]: [Y|n]: y
Validating instance...
The instance 'localhost:3306' is valid for Cluster usage
You can now use it in an InnoDB Cluster.
{
"status": "ok"
}
status
为 ok
说明配置没问题了,可以用来创建cluster
通过 mysql-shell 连接 node01 创建 cluster
登录 shell,连接 node01,创建 cluster
bin/mysqlsh
# 连接01
mysql-js> shell.connect('root@node01:3306');
# 创建一个 cluster,命名为 'myCluster'
mysql-js> var cluster = dba.createCluster('myCluster');
# 创建成功后,查看cluster状态
mysql-js> cluster.status();
{
"clusterName": "myCluster",
"defaultReplicaSet": {
"name": "default",
"primary": "node01:3306",
"status": "OK_NO_TOLERANCE",
"statusText": "Cluster is NOT tolerant to any failures. 1 member is not active",
"topology": {
"node01:3306": {
"address": "node01:3306",
"mode": "R/W",
"readReplicas": {},
"role": "HA",
"status": "ONLINE"
}
}
}
}
配置 node02 的 mysql 并启动
编辑配置文件 my.cnf
,内容与 node01 上的一样,只有2行不同
server_id=2
改成本机的IP:loose-group_replication_local_address= "172.30.12.17:24901"
通过本机 mysql-shell 对 mysql 进行配置
登录 shell ,执行配置
bin/mysqlsh
mysql-js> shell.connect('root@localhost:3306');
mysql-js> dba.configureLocalInstance();
停掉 mysql,修改 my.cnf,添加配置项
# 在末尾添加
group_replication_allow_local_disjoint_gtids_join=ON
重启MySQL
通过 node01 的 mysql-shell 添加 node02 到 cluster
# 添加实例
cluster.addInstance('root@node02:3306');
# 创建成功后,查看cluster状态
mysql-js> cluster.status();
过程与 node02 完全相同,只需要注意 my.cnf 中的 'server_id' 值改为 3,
也是改成node03的ip:loose-group_replication_local_address= "172.30.12.20:24901"
重启MySQL
通过 node01 的 mysql-shell 添加 node03 到 cluster
# 添加实例
cluster.addInstance('root@node03:3306');
# 创建成功后,查看cluster状态
mysql-js> cluster.status();
进入 node01 中 mysql-router 安装目录执行命令
./bin/mysqlrouter --bootstrap root@node01:3306 -d myrouter --user=root
这里会在mysql-router 目录生成router配置文件,我们把配置文件修改一下:
# File automatically generated during MySQL Router bootstrap
[DEFAULT]
user=root
logging_folder=/usr/mysql/mysql-router/myrouter/log
runtime_folder=/usr/mysql/mysql-router/myrouter/run
data_folder=/usr/mysql/mysql-router/myrouter/data
keyring_path=/usr/mysql/mysql-router/myrouter/data/keyring
master_key_path=/usr/mysql/mysql-router/myrouter/mysqlrouter.key
[logger]
level = INFO
[routing:read_write]
#指定mysql router绑定的服务器
bind_address = 172.30.12.14
#指定绑定的端口
bind_port = 7001
#读写模式(read-write, read_only)
mode = read-write
#指定mysql server 列表 (ip:port 格式,使用逗号分隔)
destinations = 172.30.12.14:3306
#最大连接数
max_connections = 1000
#最大错误连接数
#max_connect_errors = 100
#连接超时时间
connect_timeout = 9
[routing:read_only]
bind_address = 172.30.12.14
bind_port = 7002
mode = read-only
destinations = 172.30.12.17:3306,172.30.12.20:3306
max_connections = 1000
#max_connect_errors = 100
connect_timeout = 9
mysqlrouter --config /usr/mysql/mysql-router/myrouter/mysqlrouter.conf &
可能遇到的问题:
一般可以这样解决,停止集群:
在数据库上执行:
STOP GROUP_REPLICATION;
RESET MASTER;
RESET SLAVE;
登录 shell ,执行
bin/mysqlsh
mysql-js> shell.connect('root@localhost:3306');
mysql-js> dba.rebootClusterFromCompleteOutage('myCluster');#上面配置的名称
一般就会恢复,然后重新
cluster.addInstance('root@node02:3306');
cluster.addInstance('root@node03:3306');
在数据库中查看:
SELECT * FROM performance_schema.replication_group_members;
这样就表示集群成功了。
如果你的主从不同步,一般可以这样解决:
从master中导出数据库,到slave中导入数据。
在master通过命令:SHOW MASTER STATUS;
记下 file 和 position
在slave中执行:
CHANGE MASTER TO MASTER_HOST = '172.30.12.14',MASTER_PORT = 3306,MASTER_USER = 'root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='master-bin.000001',MASTER_LOG_POS=1172;